Windows内核原理与实现之 GDI (图形设备接口)

本文深入探讨Windows操作系统中的图形系统,重点介绍GDI(图形设备接口)如何提供与设备无关的编程接口,以及内核模式的图形引擎如何与显示驱动程序交互。内容涵盖GDI的初始化过程、DDI函数、DirectDraw和Direct3D在Windows子系统中的角色,揭示了Windows图形界面背后的机制。
摘要由CSDN通过智能技术生成

文章摘录自《Windows内核原理与实现》一书。

图形用户界面是  Windows 操作系统的重要特色,这也是在 Windows 子系统中提供的。概括而言,Windows 的图形系统有两方面特点:首先,它提供了一套与设备无关的编程接口,即 GDI,这使得应用程序可以适应各种底层显示设备的差异;其次,应用程序与图形设备驱动程序之间的通信足够高效,从而使在频繁输出和刷新图形元素的情况下,Windows也能够为用户提供良好的视觉效果。

Windows子系统定义了一个稳定的图形体系结构,以便第三方的图形设备硬件厂商可以方便地将他们的视频显示器和打印设备集成到Windows 中。图 9.12 显示了 Windows 子系统的图形部分的体系结构(适用于Windows2000 以后的系统)。

在 Windows NT 4以前,图形显示是在子系统的用户模式进程(即 csrss.exe)中被处理的,从而 Windows NT 4开始,这部分功能转移到了内核中,允许应用程序的图形请求被直接通过显示驱动程序转发到视频适配器。在图 9.12中,子系统 DLL被动态链接到应用程序进程中,它们接收应用程序的图形请求,并将其转发到内核模式下的图形引擎中。

内核模式的图形引擎(即Windows 子系统的 GDI)位于 win32k.sys 中,其职责是接受来自用户模式的图形请求,并且完成通用的、不涉及硬件的图形绘制功能,而把涉及硬件的或者需要特殊支持的图形功能交给显示驱动程序或者转发给视频端口驱动程序来完成。图形引擎在一个标准格式的位图(单个平面的plane),像素可以是1,2,4,8,16或32位,每行上的像素连续存放,并且每行数据以 4 字节为对齐边界上执行各种绘制操作。

如有必要,则通过 DDI (Device Driver Interface,设备驱动程序接口) 调用显示驱动程序来完成相应的功能,图形 DDI 函数的名称都以 "Drv" 为前缀,例如显示驱动程序的入口例程,即初始化例程,为 DrvEnableDriver。

虽然显示驱动程序也被称为驱动程序,但是它并不遵守 I/O 管理器定义的接口标准,图形引擎与显示驱动程序之间的通信并没有采用 IoCallDriver 的调用方式。显示驱动程序本质上是一个动态链接库,它暴露了一组 DDI 函数,供图形引擎调用其功能;而图形引擎也暴露了一组 ENG函数给显示驱动,从而使显示驱动程序可以调用图形引擎的功能。显示驱动程序支持的 DDI 函数都通过其入口函数(即 DrvEnableDriver)的输出参数(一个函数数组)被传递给图形引擎。关于 DDI 和 ENG 函数用法的一个典型例子是:图形引擎调用显示驱动程序的 DrvBitBlt 函数。将标准格式位图中的矩形块拷贝到显示器设备的图形表面(surface)中;显示驱动程序调用 EngBitBlt 函数,将它管理的图形表面拷贝到 GDI 管理的标准格式位图中。

图形引擎和显示驱动程序之间建立联系的初始化过程是这样来完成的:

● 在一个会话中,当 GDI 被第一次调用来创建一个设备环境 (device context)时,图形引擎调用显示驱动程序的入口函数 DrvEnableDriver,从而获得显示驱动程序的版本,以及它所支持的  DDI 函数。

● 图形引擎接着调用 DrvEnableDriver,以获得关于该驱动程序的物理设备的一个特征描述。对于 GDI,显示驱动程序代表了一个逻辑设备,它可以管理多个物理设备,每个物理设备有它自己的硬件类型、逻辑地址和图形表面(surface)。对于每个物理设备,显示驱动程序可以管理多个内存表示,即 PDEV 数据结构,这些内存标识描述了此设备的状态以及它的图形能力。在同一个物理设备的多个 PDEV 中,同一时刻只能使用一个。当图形引擎调用 DrvEnableDriver 时,显示驱动程序根据指定的设备模式创建一个 PDEV。

● 当物理设备的 PDEV 被创建以后,图形引擎调用 DrvCompletePDEV,把它为该 PDEV生成的一个句柄告诉显示驱动程序,以便将来显示驱动程序调用 ENG 接口函数时指定此 PDEV。

● 最后,图形引擎调用 DrvEnableSurface,让显示驱动程序为该物理设备创建一个图形表面,已代表最终的图形输出硬件。显示驱动程序可以有两种不同的方法来建立图形表面:

    1,自己管理图形表面。

    2,完全由图形引擎来管理图形表面(即设备无关的位图)。

显示驱动程序配合图形引擎来实现图形绘制功能,图形引擎已经实现了在标准格式位图上的各种绘制能力。显示驱动程序可以把性能要求不高的位图操作,或者图形适配器不支持的复杂操作,交给子系统的图形引擎来完成;然而,如果图形适配器支持一些特殊的加速操作,那么,显示驱动程序可以选择只实现跟这些加速操作相关的图形功能,而其他的都转交给图形引擎来完成。简而言之,图形引擎完成了在标准格式位图上的所有图形操作,而显示驱动程序则往往有选择地实现部分图形操作,它的代码尺寸相对比较小。

在Windows 子系统的图形结构中,显示驱动程序与视频小端口驱动程序是成对出现的,也就是说,对于一个视频适配器,硬件厂商除了要提供一个显示驱动程序之外,还需要提供一个配套的视频小端口驱动程序。图 9.12 中的视频端口驱动程序是由 Windows 操作系统本身提供的,在Windows Server 2003 中视频端口驱动程序为 videoprt.sys, 该文件实际上并非一个驱动程序,而是一个动态链接库。然而,视频小端口驱动程序是正真的驱动程序,而且往往是即插即用驱动程序,所以,它们由即插即用管理器在系统引导时加载到系统中。视频端口驱动程序暴露一组以“VideoPort” 为前缀的函数,而视频小端口驱动程序则以回调函数的形式暴露了一组以“HwVid” 为前缀的函数。例如,VideoPortMapMemory 函数将视频存储区的一段物理地址范围映射到系统地址空间或者进程地址空间中;HwVidInitialize 函数执行适配器的初始化工作。

显示驱动程序不能处理设备中断。只有小端口驱动程序才能配置视频适配器的存储区,并且将存储区映射到显示驱动程序可以访问的虚拟地址空间中。总体上,视频小端口驱动程序负责直接的硬件资源管理和控制,例如注册中断服务例程、定时器例程、DPC例程,管理电源状态以及 DMA 传输等;视频端口驱动程序负责与图形处理有关的各种事项,包括缓存区管理、设备内存区管理与映射、端口驱动程序负责与图形处理有关的各种事项,包括缓存区管理、设备内存区管理与映射、读写 I/O 寄存器等,它也为小端口驱动程序提供一个与系统内核和执行体打交道的环境。

GDI或显示驱动程序调用图形引擎的 EngDeviceIoControl 函数来跟视频小端口驱动程序进行通信。虽然视频小端口驱动程序是一个真正的设备驱动程序,但它的大部分功能逻辑是由视频端口驱动程序来完成的。至于创建设备对象、I/O 请求分发等设备驱动程序的常规逻辑,均由视频端口驱动程序代劳。小端口驱动程序链接到视频端口驱动程序上,它除了暴露一个入口函数作为初始化例程以外,其他所有的接口函数均以函数指针的形式告诉视频端口驱动程序。

视频端口驱动程序是一个动态链接库,它不仅提供了控制视频适配器所需要的大部分功能,而且会将视频小端口驱动程序包装成一个真正的 I/O 设备驱动程序。小端口驱动程序除了在入口函数中调用 VideoPortInitialize 函数外,只需要提供一组回调函数即可。

在Windows子系统的显示驱动程序模型中,除了 GDI 部分,它提供了对 Microsoft DirectX 的显示支持,允许像游戏、多媒体播放器等应用软件直接操纵显示器硬件,绕过前面所提到的 GDI 图形引擎,从而获得更快的显示速度,并且避免屏幕抖动。Windows子系统的 NtGdiDd<Xxx> 和 NtGdiD3d<Xxx> 系统服务正是为了这类应用软件提供的 DirectDraw 和 Direct3D 支持。

DirectDraw 是  DirectX 中的显示部分,是一套与Windows 子系统 GDI 平行的图形编程接口。由于 DirectDraw 驱动程序充分发挥了硬件的图形加速能力,所以,DirectDraw 在快速运行和持续屏幕变化等图形特性方面比 GDI 有更强的处理能力和执行效率。我们认为 DirectDraw 是 GDI 的一个增强,更加适用于像场景游戏和多媒体播放器这样的应用软件。在Windows 2000 及以后的系统上,DirectDraw  包含以下组件:

●  用户模式 DirectDraw,是一个动态链接库(ddraw.dll),它提供了硬件仿真、管理各种 DirectDraw 对象、管理显示存储区和显示器硬件的服务。DirectDraw 为应用程序提供了基于 COM(Component Object Model) 的接口,所以,使用 DirectDraw 的软件必须是一个 COM 应用。

●  内核模式 DirectDraw,如同 GDI 一样,他也是 Windows 子系统的 win32k.sys 中的一部分。内核模式 DirectDraw 的职责是,检查 DirectDraw 系统调用的参数的有效性,并且负责与 GDI 的同步,以及维护各种跨进程的状态。它提供的系统服务以 “NtGdiDd” 和 “NtGdiDvp” 为前缀。

●  DirectDraw 驱动程序,这是由图形硬件厂商提供的软件组件。从形式来看,它既可以是显示驱动程序中的一个组成部分,也可以是一个独立的驱动程序。DirectDraw 驱动程序的核心是利用硬件的能力来提供更快、更强的图形显示功能。它提供各种回调函数供子系统调用,这组回调函数涉及图形表面(surface)、颜色控制和调色板、运动补偿(motion compensation)、视频端口,以及驱动程序内部的数据对象管理等。在Windows DDK 文档中这些回调函数的前缀为 “Dd” ,例如 DdCreateSurface。

DirectDraw 驱动程序的结构与显示驱动程序很相似,他并非 I/O 设备驱动程序,而是一个动态链接库,其初始化函数 DrvEnableDirectDraw 负责硬件初始化。Windows 子系统对 DirectDraw 的支持实际上也是 GDI 的一个扩展或延伸,DirectDraw 驱动程序是显示驱动程序的扩展。

DirectX 中也包含了对于三维图形的支持,称为 Direct3D。Windows子系统也支持 Direct3D。Windows 子系统通过 DirectDraw 函数 DdGetDriverInfo 来获得 Direct3D 的回调函数,因此,Direct3D 也可以看做是 DirectDraw 的一个自然扩展。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值