基於win2k寫的,又是一本古老的書,甚至書上好多例子使用的庫已經改頭換面了,調試也沒法做了。不過,在市面上還真找不到其他深入講述系統圖形內部原理的書,真是雞肋。書中內容很多,而且相對抽象,學習了差不多一個月,只學了幾章,苦於很多東西沒法調試——書上講的和系統已經搭配不上了。現在只是把一些重點梳理一下,打下一點理論基礎。
作業系統的圖形和多媒體系統是分層的系統,最上面的應用程式通過Win32API和一套32位使用者模式系統DLL介面實現功能。系統DLL層包括類似的DLL,如GDI32.dll,USER32.dll,KERNEL32.dll。系統DLL層的大多數模組是由作業系統提供的,但是這一層的組件依賴於硬體銷售商提供的使用者模式驅動程式。在這下面是系統服務調用入口,它啟用由作業系統的核心模式中的系統服務常式提供的系統調用。在核心地址空間中的WindowsNt/2000執行體提供圖形引擎、IO管理器、視頻連接埠驅動程式等來支援圖形和多媒體系統。
在使用者模式層,圖形裝置介面(GDI)和映像顏色管理(ICM)為應用程式提供與裝置無關的圖形編程介面。
DirectX為Win32系統DLL加入一套比較新的對DirectXCOM介面操作的DLL,它執行DirectXCOM介面。對於實際與核心地址空間中DirectX執行的介面,DirectX則是通過GDI來完成的。
一、GDI體繫結構
GDI提供幾百個Windows程式中可以調用的函數。這些函數大多是從Win32的子系統DLL——GDI32.dll中匯出的。視窗管理模組USER32.dll是使用GDI函數的大使用者,它用GDI函數來繪製菜單、表徵圖、捲軸、標題列和每個視窗的架構等細節內容。有一些繪圖函數從USER32.dll匯出,提供給應用程式。windows2000提供543個進入點——win7提供714個進入點。
這些函數按功能分為17類,至今的win7的MSDN上的說明還是這種分類:
Bitmaps
Brushes
Clipping
Colors
Coordinate Spaces and Transformations
Device Contexts
Filled Shapes
Fonts and Text
Lines and Curves
Metafiles
Multiple Display Monitors
Painting and Drawing
Paths
Pens
Printing and Print Spooler
Rectangles
Regions 在Win32子系統DLL中,GDI32.dll是相對較少的模組。GDI通過windowsNT/2000系統調用或本地API調用GDI圖形引擎來實現其大部分功能。Win32子系統 DLLGDI32.dll通過把Win32API調用變成系統服務調用實現Win32GDIAPI,系統服務調用是win32k.sys中的GDI圖形引擎實現的。而像元檔案、增強型元檔案和EMF列印卸載確實是GDI32.dll提供的新功能,這些新功能沒有依靠GDI引擎的直接協助。
書上有介紹DirectX的體繫結構,都是使用COM技術建立在GDI和其他OS服務上面的,這裡不展開了。需要展開的是DirectX中的一個部分:DirectDraw體繫結構。
二、DirectDraw體繫結構
DirectDraw可以看作是GDI的特殊化。特殊化的第一步是把它的上村限制在電腦顯示卡而不是其他裝置上。第二步是減少GDI支援的功能。最後一步是實現硬體加速的有限功能,並添加對高效能遊戲和多媒體編程至關重要的功能。
DirectDraw體繫結構包括使用者模式和核心模式組件。DirectDraw的使用者模式組件是ddraw.dll,它與gdi32.dll和mcd.dll(OpenGL)相關。實際上,DirectDrawAPI是由DDRAW.dll實現的,而DDRAW.dll通過GDI32.dll與GDI引擎互動,進而與DirectDraw裝置驅動程式互動。
DirectDraw分幾層實現。最上面的層支援DirectDraw COM介面、標準COM匯出函數(DllGetClassObject等)及特殊DirectDraw建立常式(DirectDrawCreate等)。中介層是硬體模擬層(HEL),它模仿硬體不支援的所有或部分DirectDraw功能。底層叫做硬體抽象層(HAL),直接和顯示硬體對話。DirectDrawAPI和HEL都是使用者模式的,不能直接存取DirectDrawHAL,DirectDrawHAL在windowsNT/2k中是核心模式的。
三、圖形引擎
windowsNT/2k圖形引擎是GDI的支柱,是通往圖形裝置驅動程式的大門,也是其他驅動程式是基石。圖形引擎在一個核心模式DLL中,這個DLL還實現作業系統視窗管理的功能——即WIN32K.SYS。WIN32K.SYS可以看做核心支柱,實現Windows作業系統中的兩個重要模組:USER32.dll和GDI32.dll。WIN32K.SYS本身就是一個很大的DLL。
圖形引擎系統服務一般是NtGdi開頭。視窗管理服務一般以NtUser開頭。
圖形繪製引擎(GraphicsRenderEngine),圖形引擎自己和圖形引擎驅動程式都使用GRE。GREAPI和Win32GDIAPI有很大不同。GRE和圖形引擎使用的一些主要概念列表如下:GDI管理的位元影像,座標空間,表面,鉤入和踢回,繪製圖元。
圖形引擎將WIN32GDI繪圖調用合并、分解成一些圖元繪製命令,它們是GRE支援的繪圖調用,下面是簡單總結:
*EngLineTo和EngStmkePath繪製所有的直線和曲線
*EngFillPath和EngPaint用畫刷填充閉合面
*EngStoke和FillPath用畫刷填充閉合面,用畫筆一點一點地繪製其邊界
*EngBltBlt,EngPlgBlt,EngStretchBlt,EngStretchBltROP,EngCopyBits,EngAlphaBlend,EngTransparenBlt實現位元影像繪製API。
*EngGradientFill完成面漸層填充
*EngTestOut處理所有文本繪圖調用
除簡化的繪製圖元外,GRE使用一套全新的資料結構。這裡不是指GDI控制代碼,實際上GRE在GDI控制代碼層下面或者後面。
圖元變換。GDI API層負責把Win32API調用變成GRE圖元。
*座標系統。Win32API提供多種座標系統,可以完成視口到視窗轉換、映射模式和世界變換。而GRE/DDI使用裝置座標,裝置座標的大小是由繪圖表面的大小決定的。WinewAPI調用中的座標要轉換成實際繪圖表面裝置座標。
*橢圓曲線。GRE/DDI介面不支援橢圓曲線,像圓、弧、或者橢圓。它們需要被轉化成貝賽爾曲線。
*曲線到路徑。DDI介面只支援直線和路徑,因此曲線圖需要在內部黑鬼成路徑對象。圖形引擎有豐富的路徑對象控制函數集。