Windows 95 Graphics Processing With DDB and DIB
This article provides an overview of how the Windows 95 operating system managed screen updates and rendering pipelines using Device-Dependent Bitmaps (DDBs) and Device-Independent Bitmaps (DIBs). It examines the architectural roles of the Graphics Device Interface (GDI), the introduction of the 32-bit DIB Engine, and the specific mechanisms used to translate application-level graphics data into hardware-rendered frame buffers.
The Role of GDI in Windows 95
In Windows 95, visual output was coordinated through the Graphics Device Interface (GDI). The GDI acted as an abstraction layer between user-space applications and video display drivers. When an application needed to draw or update a graphic, it did not interact directly with the video hardware. Instead, it sent drawing commands to GDI, which resolved coordinates, clipping regions, and color translations before dispatching the final raster operations to the display driver.
To manage pixel data within this pipeline, GDI relied heavily on two distinct bitmap formats: Device-Dependent Bitmaps (DDBs) and Device-Independent Bitmaps (DIBs).
Device-Dependent Bitmaps (DDB)
A Device-Dependent Bitmap was tied directly to the specific internal structure of the active display hardware.
- Memory and Format: DDBs were stored in system RAM or directly in video memory using the exact pixel organization, bit depth, and planar layout expected by the physical graphics adapter.
- Performance: Because the memory layout matched the
hardware, rendering a DDB to the screen was extremely fast. Display
drivers could perform bit-block transfers (
BitBlt) via hardware acceleration without requiring on-the-fly pixel conversion. - Limitations: DDBs were inflexible. Because the format varied between different graphics cards—such as monochrome, 16-color planar, or 256-color packed-pixel modes—an application could not reliably manipulate raw pixel bytes directly. Transferring a DDB across devices with different color depths or architectures resulted in corruption or required explicit conversion.
Device-Independent Bitmaps (DIB)
To overcome the portability issues of DDBs, Windows utilized Device-Independent Bitmaps. A DIB defined an explicit, standardized specification for storing two-dimensional raster graphics.
- Structure: A DIB contained a standardized header
(
BITMAPINFOHEADER) detailing dimensions, color resolution (1, 4, 8, 16, 24, or 32 bits per pixel), compression type, and an optional color table (palette). This was followed by a contiguous array of raw pixel values organized in horizontal scanlines padded to 32-bit boundaries. - Flexibility: DIBs allowed applications to read, modify, and write individual pixels directly in memory, regardless of the display hardware installed in the computer.
- Conversion Overhead: Because display hardware rarely matched the arbitrary color depths and alignments of arbitrary DIBs, early GDI versions suffered performance penalties when converting DIBs into hardware-compatible pixels for display.
The Windows 95 DIB Engine
Windows 95 significantly altered how graphics were processed by
introducing the DIB Engine (DIBENG.DLL). Prior to Windows
95, GDI handled software rasterization relatively slowly using 16-bit
code, and drivers were responsible for complex fallback routines.
The Windows 95 DIB Engine was an optimized 32-bit software rasterizer written in assembly language. It provided high-speed software fallbacks for common rendering operations, including line drawing, polygon fills, and blitting across 1, 4, 8, 16, 24, and 32-bit color depths. Video display drivers in Windows 95 were designed to "hook" functions they could accelerate via hardware and pass unaccelerated operations back to the DIB Engine.
Direct Access via CreateDIBSection
A key enhancement in the Windows 95 graphics pipeline was the
CreateDIBSection API.
Previously, applications faced a strict choice: use a DDB for fast
GDI drawing, or use a DIB for direct memory manipulation, which required
slow conversion functions like SetDIBitsToDevice or
StretchDIBits to render to the screen.
CreateDIBSection solved this conflict by providing a
hybrid approach:
- GDI allocated a memory buffer formatted as a standard DIB.
- The operating system returned both a GDI handle
(
HBITMAP) and a direct pointer to the underlying bitmap memory. - The application could write directly to the pixel memory using its own fast software algorithms.
- The application could simultaneously select the same handle into a standard GDI device context (DC) to apply native GDI operations like text rendering or vector drawing.
The Complete Update Pipeline
When an application processed a screen update using these formats in Windows 95, the workflow generally proceeded through four distinct phases:
- Surface Preparation: The application allocated an
off-screen surface, either by creating a memory DC compatible with the
screen (producing a DDB) or by using
CreateDIBSectionto establish a memory buffer with a known layout. - Rendering and Composition: Graphics were drawn to the off-screen surface. If a DIB section was used, custom rendering engines (such as game renderers or image editors) manipulated the pixel pointer directly, followed by optional GDI overlay calls.
- Format Translation: When blitting to the target screen DC, the GDI and the DIB Engine evaluated the source and destination formats. If the source was a DIB and the destination was the screen, the DIB Engine translated the color tables, adjusted bit depths, and formatted the scanlines to match the display adapter's configuration.
- Hardware Transfer: Once formatted, the display
driver executed the final transfer to the physical frame buffer. If the
graphics card supported hardware acceleration for the given color depth,
the driver transferred the pixels via hardware
BitBlt; otherwise, the DIB Engine wrote directly to the memory-mapped frame buffer using optimized CPU copy loops.