比較 Direct2D 和 GDI 硬體加速
Direct2D 和 GDI 都是立即模式 2D 轉譯 API,同時提供某種程度的硬體加速。 本主題會探索 Direct2D 和 GDI 之間的差異,包括兩個 API 硬體加速功能的過去和目前差異。
本主題包含下列部分:
Direct2D 與 GDI 之間的差異
GDI 會呈現不透明的別名幾何,例如多邊形、橢圓形和線條。 它會轉譯別名和 ClearType 文字,並可支援透過 AlphaBlend API 進行透明度混合。 不過,其透明度的處理不一致,而且大部分的 GDI API 只會忽略 Alpha 色板。 少數 GDI API 可保證 Alpha 通道在作業之後將包含的內容。 更重要的是,GDI 的轉譯不會輕易地對應至 3D 作業,而新式 GPU 在轉譯引擎的 3D 部分最有效率地轉譯。 例如, Direct2D的別名線條是設計成隻是在 GPU 上呈現兩個三角形來實作,而 GDI 則使用 Bresenham 的線條繪製演算法。
Direct2D 會呈現不透明、透明、別名和反別名的基本類型。 新式 UI 通常會使用透明度和動畫。 Direct2D 可讓您更輕鬆地建立新式 UI,因為它具有接受和轉譯透明內容方式的嚴格保證,而且其所有基本類型都會使用硬體加速來轉譯。 Direct2D 不是 GDI的純超集合:在 GPU 上實作時未在 Direct2D 中實作的基本類型並不合理。 由於 Direct2D 是以這個強調 3D 加速所建置,因此也可以輕鬆地與 Direct3D 搭配使用。
由於Windows NT 4,GDI已在核心模式中執行。 應用程式會呼叫 GDI,然後呼叫其核心模式對應專案,以將基本類型傳遞至自己的驅動程式模型。 此驅動程式接著會將結果傳送至全域核心模式顯示驅動程式。
從 Windows 2000 開始, GDI 和 GDI 驅動程式已在核心稱為「會話空間」的獨立空間中執行。系統會為每個登入會話建立會話位址空間,而 GDI 的每個實例都會在這個不同的核心模式位址空間中獨立執行。 不過,Direct2D 會在使用者模式中執行,並透過使用者模式 Direct3D 驅動程式將繪圖命令傳遞至核心模式驅動程式。
GDI 和 Direct2D 硬體加速
Direct2D與GDI硬體加速之間的最重要差異是驅動它們的基礎技術。 Direct2D 會分層在 Direct3D 之上,而 GDI 有自己的驅動程式模型,即 GDI 設備磁碟機介面 (DDI) ,其對應至 GDI 基本類型。 Direct3D 驅動程式模型會對應至 GPU 中的 3D 轉譯硬體呈現的內容。 第一次定義 GDI DDI 時,大部分的顯示加速硬體都是以 GDI 基本類型為目標。 經過一段時間後,更多和更多強調是針對 3D 遊戲加速,而應用程式加速則較少。 因此,BitBlt API 是硬體加速,而且大部分的其他 GDI 作業都不是。
這會設定一連串變更的階段,以將 GDI 呈現至顯示的方式。 下圖顯示 GDI 顯示呈現如何從 Windows XP 變更為 Windows 7。
另外還有一些造成 GDI 驅動程式模型變更的其他因素,如下所述。
增加顯示驅動程式的複雜度和大小
3D 驅動程式在一段時間內變得更複雜。 更複雜的程式碼通常會有更多瑕疵,讓驅動程式存在於無法重新開機系統之驅動程式的使用者模式中。 如上圖所示,顯示驅動程式分成複雜的使用者模式元件和更簡單的核心模式元件。
同步處理會話和全域核心位址空間時發生困難
在 Windows XP 中,顯示驅動程式存在於兩個不同的位址空間中:會話空間和核心空間。 驅動程式的元件需要回應電源管理事件等事件。 這必須與會話位址空間中的驅動程式狀態同步處理。 這是一項困難的工作,而且在顯示驅動程式嘗試處理這些不同的位址空間時,可能會導致瑕疵。
複合式視窗管理
桌面視窗管理員 (DWM) 、Windows 7 中引進的撰寫視窗管理員、將所有視窗轉譯成螢幕外表面,然後將它們組合在一起以顯示在螢幕上。 這需要 GDI 能夠轉譯至表面,然後 Direct3D 才會呈現。 這在 XP 驅動程式模型中造成問題,因為 GDI 和 Direct3D 是平行驅動程式堆疊。
因此,在 Windows Vista 中, GDI DDI 顯示器驅動程式會實作為 Microsoft 提供的正式顯示驅動程式 (CDD) ,將 GDI 內容轉譯為要組成畫面的系統記憶體點陣圖。
Windows 7 中的 GDI 轉譯
Windows Vista 中使用的驅動程式模型需要每一個 GDI 視窗都受到視訊記憶體介面和系統記憶體介面的支援。 這會導致每個 GDI 視窗使用系統記憶體。
基於這個理由, GDI 在 Windows 7 中再次變更。 GDI 已修改為轉譯為光圈記憶體區段,而不是轉譯至系統記憶體介面。 您可以從保存視窗內容的視訊記憶體表面更新光圈記憶體。 GDI 可以轉譯回光圈記憶體,然後結果可以傳回視窗表面。 由於 GPU 可定址光圈記憶體區段,因此 GPU 可以加速這些對視訊記憶體介面的更新。 例如,文字轉譯、BitBlts、AlphaBlend、TransparentBlt 和 StretchBlt 全都會在這些情況下加速。
對比 Windows 7 中的 Direct2D 和 GDI 加速
Direct2D 和 GDI 都是 2D 立即模式轉譯 API,且會加速硬體。 不過,這兩個 API 中都有一些差異。
資源的位置
根據預設,GDI會維護其資源,特別是系統記憶體中的點陣圖。 Direct2D 會在顯示器配接器上的視訊記憶體中維護其資源。 當 GDI 需要更新視訊記憶體時,這必須透過匯流排完成,除非資源已經位於光圈記憶體區段中,或者作業是否可以直接表示。 相反地,Direct2D 可以直接將其基本類型轉譯為 Direct3D 基本類型,因為資源已經在視訊記憶體中。
轉譯方法
為了維持相容性, GDI 會使用 CPU 執行大部分的轉譯到光圈記憶體。 相反地, Direct2D 會將其 API 呼叫轉譯為 Direct3D 基本類型和繪圖作業。 結果接著會在 GPU 上呈現。 當光圈記憶體複製到代表 GDI 視窗的視訊記憶體介面時,GPU 上會執行部分 GDI 轉譯。
延展性
Direct2D的轉譯呼叫都是 GPU 的獨立命令資料流程。 每個 Direct2D 處理站都代表不同的 Direct3D 裝置。 GDI 會針對系統上的所有應用程式使用一個命令資料流程。 GDI 的 方法可能會導致 GPU 和 CPU 轉譯內容額外負荷的建置。
位置
Direct2D 完全以使用者模式運作,包括 Direct3D 執行時間和使用者模式 Direct3D 驅動程式。 這有助於防止系統因核心中的程式碼瑕疵而造成系統損毀。 不過,GDI在核心模式的會話空間中具有大部分的功能,其 API 介面在使用者模式中。
硬體加速的可用性
GDI 是在 Windows XP 上加速的硬體,並在桌面視窗管理員執行且使用 WDDM 1.1 驅動程式時,在 Windows 7 上加速。 Direct2D 是在幾乎任何 WDDM 驅動程式上加速的硬體,以及 DWM 是否正在使用中。 在 Vista 上,GDI 一律會在 CPU 上呈現。
簡報模型
第一次設計 Windows 時,記憶體不足,無法讓每個視窗儲存在其自己的點陣圖中。 因此, GDI 一律會以邏輯方式轉譯到畫面,並套用各種裁剪區域,以確保應用程式不會在其視窗外轉譯。 在 Direct2D 模型中,應用程式會轉譯為後端緩衝區,並在應用程式完成繪圖時顯示結果。 這可讓 Direct2D 比 GDI 更流暢地處理動畫案例。
結論
現有的 GDI 程式碼將繼續在 Windows 7 下運作良好。 不過,撰寫新的圖形轉譯程式碼時,應該考慮 Direct2D ,因為它更能利用新式 GPU。