Display Driver Initialization
Display driver initialization is similar to graphics driver initialization, as described in Supporting Initialization and Termination Functions. This section provides initialization details that are specific to display drivers.
Video miniport and display driver initialization occur after the NT executive and the Win32 subsystem are loaded and initialized. The system loads the video miniport driver or drivers that are enabled in the registry, and then determines which video miniport driver and display driver pair to use. During this process, GDI opens all necessary display drivers, based on the information provided by Window Manager.
The basic display driver initialization procedure, in which the desktop is created, is shown in the following figure.
When GDI is called to create the first device context (DC) for the video hardware, GDI calls the display driver function DrvEnableDriver. Upon return, DrvEnableDriver provides GDI with a DRVENABLEDATA structure that holds both the driver's graphics DDI version number and the entry points of all callable graphics DDI functions that are implemented by the driver (other than DrvEnableDriver).
GDI then calls the driver's DrvEnablePDEV function to request a description of the driver's physical device's characteristics. In the call, GDI passes in a DEVMODEW structure, which identifies the mode that GDI wants to set. If GDI requests a mode that the display or underlying miniport driver does not support, then the display driver must fail this call.
The display driver represents a logical device controlled by GDI. As shown in the following figure, a single logical device can manage several physical devices, each characterized by type of hardware, logical address, and surfaces supported. The display driver allocates the memory to support the device it creates. A display driver may be called upon to manage more than one PDEV for the same physical device, although only one PDEV can be enabled at a time for a given physical device. Each PDEV is created in a separate GDI call to DrvEnablePDEV, and each call creates another PDEV that is used with a different surface.
Because a driver must support more than one PDEV, it should not use global variables.
The following figure illustrates logical versus physical devices.
When installation of the physical device is complete, GDI calls DrvCompletePDEV. This function provides the driver with a GDI-generated physical device handle to use when requesting GDI functions for the device.
In the final stage of initialization, a surface is created for the video hardware by a GDI call to DrvEnableSurface, which enables graphics output to the hardware. Depending on the device and the environment, the display driver enables a surface in one of two ways:
- The driver manages its own surface by calling the GDI function EngCreateDeviceSurface to obtain a handle for the surface. The device-managed surface method is required for hardware that does not support a standard-format bitmap and is optional for hardware that does.
- GDI can manage the surface completely as an engine-managed surface if the hardware device has a surface organized as a standard-format bitmap. A driver can call EngModifySurface to convert the device-managed primary bitmap to one that is engine-managed. The driver can still hook any drawing operations.
Any existing GDI bitmap handle is a valid surface handle. A driver can call EngModifySurface to convert the device-managed primary bitmap to an engine-managed bitmap. If the surface is engine-managed, GDI can handle any or all drawing operations. If the surface is device-managed, at a minimum, the driver must handle DrvTextOut, DrvStrokePath, and DrvBitBlt.
GDI automatically enables DirectDraw after calling DrvEnableSurface. After DirectDraw is initialized, the driver can use DirectDraw's heap manager to perform off-screen memory management. See DirectDraw and GDI for details.
A display driver must implement DrvNotify in order to receive notification events, particularly the DN_DRAWING_BEGIN event. GDI sends this event immediately before it begins drawing, so it can be used to determine when caches can be initialized.
See the Plug and Play section for more information about the boot process.