Direct2D と GDI ハードウェア アクセラレータの比較
Direct2D と GDI はどちらもイミディエイト モードの 2D レンダリング API であり、どちらもある程度のハードウェア アクセラレーションを提供します。 このトピックでは、両方の API のハードウェア アクセラレータ機能の過去と現在の違いなど、Direct2D と GDI の違いについて説明します。
このトピックには、次の部分があります。
- Direct2D と GDI の違い
- GDI および Direct2D ハードウェア アクセラレータ
- Windows 7 での GDI レンダリング
- Windows 7 での Direct2D と GDI アクセラレーションのコントラスト
- まとめ
Direct2D と GDI の違い
GDI は、多角形、楕円、線など、不透明な別名を持つジオメトリをレンダリングします。 エイリアス化されたテキストと ClearType テキストがレンダリングされ、AlphaBlend API を介した透過性ブレンドをサポートできます。 ただし、透明度の処理は一貫性がなく、ほとんどの GDI API はアルファ チャネルを無視するだけです。 操作後にアルファ チャネルに含まれるものを保証する GDI API はほとんどありません。 さらに重要なのは、GDI のレンダリングは 3D 操作に簡単にマップされず、最新の GPU はレンダリング エンジンの 3D 部分で最も効率的にレンダリングされます。 たとえば、 Direct2D のエイリアス化された線は、GPU にレンダリングされる 2 つの三角形として単純に実装されるように設計されていますが、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 では、ディスプレイ ドライバーは、セッション空間とカーネル空間という 2 つの異なるアドレス空間に存在します。 ドライバーの一部は、電源管理イベントなどのイベントに応答する必要があります。 これは、セッション アドレス空間内のドライバーの状態と同期する必要があります。 これは困難な作業であり、ディスプレイ ドライバーがこれらの個別のアドレス空間に対処しようとすると、障害が発生する可能性があります。
複合ウィンドウ管理
Windows 7 で導入された合成ウィンドウ マネージャーであるデスクトップ ウィンドウ マネージャー (DWM) は、すべてのウィンドウを画面外の画面にレンダリングし、それらをまとめて構成して画面に表示します。 これを行うには、 GDI がサーフェスにレンダリングでき、Direct3D によってレンダリングされて表示される必要があります。 これは、GDI と Direct3D が並列ドライバー スタックであったため、XP ドライバー モデルで問題が発生しました。
その結果、Windows Vista では、 GDI DDI ディスプレイ ドライバーは、画面に構成されるシステム メモリ ビットマップに GDI コンテンツをレンダリングする Microsoft 提供の正規ディスプレイ ドライバー (CDD) として実装されました。
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 ウィンドウを表すビデオ メモリサーフェイスにアパーチャ メモリがコピーされると、GDI?s レンダリングの一部が GPU 上で実行されます。
スケーラビリティ
Direct2D のレンダリング呼び出しはすべて、GPU への独立したコマンド ストリームです。 各 Direct2D ファクトリは、異なる Direct3D デバイスを表します。 GDI は、システム上のすべてのアプリケーションに対して 1 つのコマンド ストリームを使用します。 GDI の メソッドを使用すると、GPU と CPU レンダリング コンテキストのオーバーヘッドが増加する可能性があります。
Location
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 では引き続き適切に動作します。 ただし、新しいグラフィックス レンダリング コードを記述する場合は、最新の GPU を利用するため、 Direct2D を考慮する必要があります。