共用方式為


比較 Direct2D 和 GDI 硬體加速

Direct2DGDI 都是即時模式 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 驅動程式將繪圖命令傳遞至核心模式驅動程式。

圖 1 - direct2d 與 gdi

GDI 和 Direct2D 硬體加速

Direct2DGDI 硬體加速之間的最重要差異是驅動它們的基礎技術。 Direct2D 會分層在 Direct3D 上方,而 GDI 有自己的驅動程式模型 GDI 設備驅動器介面 (DDI),其對應至 GDI 基本類型。 Direct3D 驅動程式模型會對應至 GPU 中 3D 轉譯硬體呈現的內容。 第一次定義 GDI DDI 時,大部分的顯示加速硬體都會以 GDI 基本類型為目標。 隨著時間的推移,越來越多的強調 3D 遊戲加速,減少應用程式加速。 因此,BitBlt API 獲得了硬體加速,而大部分其他 GDI 操作則沒有。

這為一連串 GDI 在顯示器上的渲染變更鋪平了道路。 下圖顯示 GDI 顯示轉譯如何從 Windows XP 變更為 Windows 7。

圖 2 - gdi 顯示器轉譯的演進

另外還有一些其他因素導致 GDI 驅動程式模型變更,如下所述。

增加顯示驅動程序的複雜度和大小

隨著時間推移,3D 驅動程式變得更加複雜。 更複雜的程式代碼往往有較多的缺陷,因此將驅動程式放在使用者模式下是有益的,因為驅動程式的錯誤無法導致系統重新啟動。 如上圖所示,顯示驅動程式分為複雜的使用者模式元件和更簡單的核心模式元件。

在同步處理會話及全域核心位址空間時遇到的困難

在 Windows XP 中,顯示驅動程式存在於兩個不同的位址空間中:會話空間和核心空間。 驅動程式的部分需要響應電源管理事件等事件。 這必須與會話位址空間中的驅動程序狀態同步。 這是一項困難的工作,當顯示驅動程式嘗試處理這些相異的位址空間時,可能會導致缺陷。

複合視窗管理

Windows 7 中引進的 「桌面視窗管理員」(DWM)會將所有視窗轉譯為螢幕外表面,然後將它們組合在一起以顯示在螢幕上。 這需要 GDI,才能轉譯為 Surface,然後 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 加速

Direct2DGDI 都是 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 上是透過硬體加速的,而當 Windows 7 執行桌面視窗管理員和使用 WDDM 1.1 驅動程式時也是加速的。 Direct2D 在幾乎任何 WDDM 驅動程式上都會進行硬體加速,無論是否正在使用 DWM。 在 Vista 上,GDI 一律會在 CPU 上轉譯。

簡報模型

第一次設計 Windows 時,記憶體不足,無法讓每個視窗儲存在自己的點陣圖中。 因此,GDI 一律以邏輯方式直接呈現在螢幕上,並套用各種剪輯區域,以確保應用程式不會在其視窗外進行呈現。 在 Direct2D 模型中,應用程式會轉譯為後台緩衝區,並在應用程式完成繪圖時顯示結果。 這可讓 Direct2D 比 GDI 更流暢地處理動畫案例。

結論

現有的 GDI 程式代碼將繼續在 Windows 7 下運作良好。 不過,撰寫新的圖形轉譯程序代碼時,應該考慮 Direct2D,因為它更能利用新式 GPU。