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:

  1. GDI allocated a memory buffer formatted as a standard DIB.
  2. The operating system returned both a GDI handle (HBITMAP) and a direct pointer to the underlying bitmap memory.
  3. The application could write directly to the pixel memory using its own fast software algorithms.
  4. 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:

  1. 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 CreateDIBSection to establish a memory buffer with a known layout.
  2. 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.
  3. 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.
  4. 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.