支持多个 PDEV

本部分说明应用程序如何在当前 PDEV 仍处于加载状态时创建新的 PDEV。 控制面板的显示程序要求显示驱动程序支持启用其他 PDEV,因为应用程序可以使用新桌面创建新的 PDEV。 具体而言,最终用户可以单击“显示”图标,对屏幕的大小、颜色数和刷新率等元素的更改运行测试。 显示程序动态创建新桌面以测试显示器的模式更改。

当用户单击“显示”图标请求模式更改时,GDI 将执行以下步骤。 这些步骤假定当前驱动程序实例没有活动的 Direct3D、WNDOBJ 或 DRIVEROBJ 对象。

  1. 暂时禁用当前 PDEV。 (旧的 PDEV 实例) 调用 DrvAssertMode 。 如果微型端口驱动程序要控制,则使用 FALSE 进行调用;如果应使用 PDEV,则使用 TRUE 进行调用。

  2. 调用 DrvEnableDriver 以加载新的驱动程序 ((如果新的 PDEV 实例) 需要)。

  3. 创建新的 PDEV

  4. 如果 DirectDraw 被驱动程序) 挂钩, (获取 DirectDraw 信息。 仅当第一次调用成功时,才会对 DrvGetDirectDrawInfo 进行第二次调用。

    • (新的 PDEV 实例) 调用 DrvGetDirectDrawInfo
    • (新的 PDEV 实例) 调用 DrvGetDirectDrawInfo
  5. 启用 DirectDraw (如果驱动程序挂钩,并且之前对 DrvGetDirectDrawInfo 的调用成功) : (新的 PDEV 实例) 调用 DrvEnableDirectDraw

  6. 如果两个实例使用相同的驱动程序,并且 DirectDraw 由驱动程序) 挂钩,请将旧的 PDEV 状态复制到新的 PDEV 实例 (:调用 DrvResetPDEV

  7. 通知每个驱动程序实例其新的 HDEV 关联。 对 DrvCompletePDEV 的第一次调用通知新的驱动程序实例;第二个调用通知旧驱动程序实例。

    • (新的 PDEV 实例) 调用 DrvCompletePDEV
    • (旧 PDEV 实例) 调用 DrvCompletePDEV

    驱动程序应在对需要 HDEV 的 GDI 的任何回调中使用新的 HDEV 值。

  8. 如果驱动程序挂钩且 DirectDraw 处于活动状态,) 禁用 DirectDraw (:) 调用 DrvDisableDirectDraw (旧的 PDEV 实例。

  9. 禁用图面: (旧 PDEV 实例) 调用 DrvDisableSurface

  10. 禁用 PDEV: (旧 PDEV 实例) 调用 DrvDisablePDEV

在此示例中,GDI 在用户单击“应用”时暂时禁用当前 PDEV,然后创建与对话框中的显示模式选择匹配的第二个 PDEV。 当用户在测试模式下在显示屏幕上查看位图后,第二个 PDEV 将被销毁,并且显示程序将还原桌面的原始 PDEV。 请注意,如果无法还原回到原始显示设置,则如果设置与硬件和驱动程序不兼容,系统将变得不可用。

如果驱动程序的当前实例拥有 Direct3D、WNDOBJ 或 DRIVEROBJ 对象,则驱动程序对以前模式更改序列的视图将发生如下更改 (请注意,在 Windows 2000 及更高版本中,只要驱动程序初始化) ,DirectDraw 始终处于启用状态:

  • 将推迟销毁拥有的驱动程序实例。 具体而言,步骤 7、步骤 8 和步骤 9 中对 DrvCompletePDEV 的第二次调用不会在模式更改时发生。 因此,由于在步骤 1 中调用 DrvAssertMode (FALSE) ,旧驱动程序实例被禁用,并且会一直保留到系统执行模式更改回原始模式,或直到销毁引用该实例的所有对象为止。

  • 如果在销毁引用对象之前系统还原回原始模式,则原始驱动程序实例将恢复。 也就是说,不会执行步骤 2 到步骤 5,并且通过调用 DrvAssertMode (TRUE 重新启用原始驱动程序实例) (请参阅步骤 1) 。

  • 如果在销毁所有引用对象之前系统未还原回到原始模式,则在销毁最终引用对象时将销毁驱动程序实例。 也就是说,步骤 7、步骤 8 和步骤 9 中对 DrvCompletePDEV 的第二次调用将在销毁最终引用对象时发生 (,例如,当所有拥有的进程) 终止时。

这意味着可以随时调用 Direct3D 或 OpenGL 驱动程序来销毁非活动驱动程序实例。 即使驱动程序的另一个实例当前处于活动状态,或者驱动程序处于全屏 MS-DOS 模式,或者其他驱动程序拥有完全 (的硬件(如 VGA 驱动程序) ),也可以调用这些驱动程序。 因此, DrvDisableDirectDrawDrvDisableSurfaceDrvDisablePDEV 例程 (驱动程序的步骤 8-10) 无法假定设备处于图形模式并且它们拥有独占访问权限。 一般情况下,驱动程序不应在其 DrvDisableXxx 例程中操作其视频硬件,除非他们知道其实例当前处于活动状态, (记住上一个 DrvAssertMode 调用) 的状态。

PDEV 专用于驱动程序,包含表示关联物理设备的所有信息和数据。 若要创建多个 PDEV,图形驱动程序必须满足以下两项要求:

  1. 驱动程序不得使用全局变量而不是取消引用 PDEV 结构的成员。 如果使用全局变量,则当创建新 PDEV 或还原旧 PDEV 时,它们可能包含或指向随机数据。 所有状态信息都必须保存在 PDEV 中。 PDEV 始终传递给任何图形操作,因此用于获取或设置全局数据。
  2. DrvDisableSurfaceDrvDisablePDEVDrvDisableDriver 例程必须在图形驱动程序中实现,以便应用程序可以创建和销毁其他 PDEV,并在某些情况下加载多个驱动程序。

注意

如果驱动程序的版本号为 1.0,GDI 将不会调用驱动程序来创建第二个 PDEV。 驱动程序的版本号在 DRVENABLEDATA 中返回。

有时,显示程序的测试位图将使用与当前加载的驱动程序不同的驱动程序显示。 例如,如果系统在使用 VGA 驱动程序的 16 色模式下运行,并使用 VGA64K 显示驱动程序测试 64K 颜色模式,则 VGA64K 驱动程序将在测试完成后动态加载和卸载。