Windows 2000 驱动程序初始化

在 Windows 2000 及更高版本上,仅当应用程序请求时才检索驱动程序信息。 换句话说,为了响应 Microsoft DirectDraw 应用程序创建 DirectDraw 对象实例的请求,图形引擎调用驱动程序函数来初始化 DirectDraw 驱动程序。

从 Windows 2000 开始,此序列在启动时和每次模式更改后完成。 这有副作用。 在 Windows 98/Me 上,驱动程序通常具有两种操作模式- GDI 模式和 DirectDraw 模式。 如果 DirectDraw 正在运行,则它不允许 GDI 缓存位图,而是将所有内存分配给 DirectDraw (反之亦然,在 GDI 模式下) 。 此行为导致窗口化应用程序 ((例如使用 DirectX) 的网页)受到影响。 因此,在 Windows 2000 及更高版本上,需要 GDI 和 DirectDraw 来配合内存的使用方式。 Windows 驱动程序开发工具包附带的 Permedia3 示例驱动程序 (DDK) 提供了有关如何执行此操作的示例。 (DDK 先于 Windows 驱动程序工具包 [WDK].)

驱动程序初始化序列是通过调用以下函数实现的:

  • DrvGetDirectDrawInfo 用于检索有关硬件功能的信息。 GDI 两次调用此函数:

    • 第一次调用确定显示内存堆的大小以及驱动程序支持的 FOURC 数。 GDI 为 pvmListpdwFourCC 参数传递 NULL。 驱动程序应仅初始化并返回 pdwNumHeapspdwNumFourCC 参数。
    • 第二次调用是在 GDI 根据 pdwNumHeaps 和 pdwNumFourCC 参数中第一次调用返回的值分配显示内存和 FOURCC 内存 之后进行的。 第二次调用中,驱动程序应初始化并返回 pdwNumHeapspvmListpdwNumFourCCpdwFourCC 参数。

    GDI 分配和零初始化 pHalInfo 指向的DD_HALINFO结构。 DrvGetDirectDrawInfo 函数应使用特定于驱动程序的信息填充 DD_HALINFO 结构的相关成员:

    • 驱动程序应初始化 VIDEOMEMORYINFO 结构的相应成员,以描述显示器内存的一般格式。 请参阅 显示内存
    • 驱动程序应初始化 DDCORECAPS 结构的相应成员,以将驱动程序的核心功能描述为 DirectDraw。
    • 如果驱动程序支持通过向驱动程序的 DdGetDriverInfo 回调发送 GUID 来查询的任何 DirectX 功能,则驱动程序必须初始化 GetDriverInfo 成员以指向驱动程序的 DdGetDriverInfo 回调,并在 dwFlags 中设置DDHALINFO_GETDRIVERINFOSET位。
    • 驱动程序必须将 dwSize 设置为 DD_HALINFO 结构的大小(以字节为单位)。
  • 运行时使用 DrvEnableDirectDraw 启用 DirectDraw 硬件并确定驱动程序的一些回调支持。 GDI 分配和零初始化 DD_CALLBACKSDD_SURFACECALLBACKSDD_PALETTECALLBACKS 参数结构。 驱动程序应对它实现的每个回调执行以下操作:

    • 将相应结构的相应成员设置为指向回调。
    • 在相应结构的 dwFlags 成员中设置相应的DDHAL_XXX_XXX 位。

    驱动程序可以实现其 DrvEnableDirectDraw 函数,以指示它支持 使用 DrvEnableDirectDraw 的 DirectDraw 回调支持中列出的回调函数。

    驱动程序的 DrvEnableDirectDraw 实现还可以专用硬件资源,例如显示内存,仅供 DirectDraw 使用。

  • DdGetDriverInfo 用于检索驱动程序支持的其他回调函数和功能。

    如果不是 NULL,则驱动程序的 DrvGetDirectDrawInfoDD_HALINFO 结构中返回 GetDriverInfo 回调。 GDI 分配和初始化DD_GETDRIVERINFODATA结构,并为DD_GETDRIVERINFODATA参考部分所述的每个 GUID 调用 DdGetDriverInfo。 所有 GUID 都在 ddrawint.h 中定义。

    驱动程序可以实现其 DdGetDriverInfo 函数,以指示它支持 使用 DdGetDriverInfo 的 DirectDraw 和 Direct3D 回调支持中指定的回调函数。

锁定表面内存 (整个表面或部分表面) 可确保应用程序和硬件无法同时访问 Surface 内存。 这可以防止在应用程序写入 Surface 内存时发生错误。 此外,在解锁表面内存之前,应用程序无法翻页。