IDXGIOutput1
COM公式ドキュメント
IDXGIOutput1 インターフェイスは、アダプターの出力(アウトプット)(モニターなど)を表します。
解説(Remarks)
アダプターから利用できる出力を調べるには、IDXGIAdapter::EnumOutputs を使用します。スワップチェーンが更新する特定の出力を調べるには、IDXGISwapChain::GetContainingOutput を使用します。その後、任意の IDXGIOutput オブジェクトから QueryInterface を呼び出して、IDXGIOutput1 オブジェクトを取得できます。
メソッド 4
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
要求されたフォーマットおよびその他の入力オプションに一致するディスプレイモードを取得します。(IDXGIOutput1.GetDisplayModeList1)
| EnumFormat | DXGI_FORMAT | in | カラーフォーマットを表す DXGI_FORMAT 型の値。 |
| Flags | DXGI_ENUM_MODES | in | ビットごとの OR 演算で組み合わせた DXGI_ENUM_MODES 型の値の組み合わせ。結果の値は、含めるディスプレイモードのオプションを指定します。スケーリングを必要とするディスプレイモードを列挙対象にするには、DXGI_ENUM_MODES_SCALING を指定する必要があります。スケーリングを必要とせず、ディスプレイ出力に直接対応する中央揃えのモードは、既定で列挙されます。 |
| pNumModes | DWORD* | inout | pDesc が指すメモリブロックに GetDisplayModeList1 が返すディスプレイモードの数を受け取る変数へのポインター。pNumModes がフォーマットとオプションに一致するディスプレイモードの数を返すようにするには、pDesc を NULL に設定します。それ以外の場合、pNumModes は pDesc に返されたディスプレイモードの数を返します。 |
| pDesc | DXGI_MODE_DESC1* | outoptional | ディスプレイモードのリストへのポインター。ディスプレイモードの数を取得するには NULL に設定します。 |
戻り値
DXGI_ERROR トピックで説明されているエラーコードのいずれかを返します。まれではありますが、このメソッドを呼び出した直後に利用可能なディスプレイモードが変化する場合があり、その場合は(すべてのディスプレイモードを格納する十分な領域がないとき)DXGI_ERROR_MORE_DATA が返されます。
解説(Remarks)
GetDisplayModeList1 は GetDisplayModeList を更新したもので、更新されたモード記述である DXGI_MODE_DESC1 構造体のリストを返します。GetDisplayModeList は、ステレオモードを含め DXGI_ENUM_MODES で指定されたすべてのモードを返すことができるため、GetDisplayModeList1 を呼び出すかのように動作します。ただし、GetDisplayModeList は、従来のモード記述でありステレオモードを示さない DXGI_MODE_DESC 構造体のリストを返します。
GetDisplayModeList1 メソッドは、Flags パラメーターに DXGI_ENUM_MODES_STEREO フラグを指定しない限り、ステレオモードを列挙しません。DXGI_ENUM_MODES_STEREO を指定すると、pDesc パラメーターが指す返却モードのリストにステレオモードが含まれます。つまり、このメソッドはステレオモードとモノラルモードの両方を返します。
一般に、ウィンドウモードから全画面モードに切り替えると、スワップチェーンはスワップチェーンの解像度、色深度、リフレッシュレートを満たす(またはそれ以上の)ディスプレイモードを自動的に選択します。ディスプレイモードをより細かく制御するには、GetDisplayModeList1 を使用して、モニターの機能に対して検証されたディスプレイモードの集合、または(デスクトップ設定がモニターに対して検証されていない場合は)デスクトップに一致するすべてのモードを取得します。
次のサンプルコードは、GetDisplayModeList1 を 2 回呼び出す必要があることを示しています。1 回目の GetDisplayModeList1 の呼び出しで利用可能なモードの数を取得し、2 回目の GetDisplayModeList1 の呼び出しでモードの記述を取得します。
UINT num = 0;
DXGI_FORMAT format = DXGI_FORMAT_R32G32B32A32_FLOAT;
UINT flags = DXGI_ENUM_MODES_INTERLACED;
pOutput->GetDisplayModeList1( format, flags, &num, 0);
...
DXGI_MODE_DESC1 * pDescs = new DXGI_MODE_DESC1[num];
pOutput->GetDisplayModeList1( format, flags, &num, pDescs);
要求されたディスプレイモードに最も近いディスプレイモードを検索します。(IDXGIOutput1.FindClosestMatchingMode1)
| pModeToMatch | DXGI_MODE_DESC1* | in | 一致させるディスプレイモードを記述する DXGI_MODE_DESC1 構造体へのポインター。DXGI_MODE_DESC1 のメンバーは未指定にすることができ、これはそのメンバーに対する優先指定がないことを示します。Width または Height の値が 0 の場合、その値が未指定であることを示します。Width または Height のいずれかが 0 の場合、両方とも 0 でなければなりません。RefreshRate の分子と分母が 0 の場合、未指定であることを示します。DXGI_MODE_DESC1 のその他のメンバーには、そのメンバーが未指定であることを示す列挙値があります。pConcernedDevice が NULL の場合、DXGI_MODE_DESC1 の Format メンバーを DXGI_FORMAT_UNKNOWN にすることはできません。 |
| pClosestMatch | DXGI_MODE_DESC1* | out | pModeToMatch で記述されたディスプレイモードに最も近いディスプレイモードの記述を受け取る DXGI_MODE_DESC1 構造体へのポインター。 |
| pConcernedDevice | IUnknown* | inoptional | Direct3D デバイスインターフェイスへのポインター。このパラメーターが NULL の場合、FindClosestMatchingMode1 は pModeToMatch のフォーマットに一致するモードのみを返します。それ以外の場合、FindClosestMatchingMode1 はデバイスによるスキャンアウトがサポートされているフォーマットのみを返します。各機能レベルでデバイスによるスキャンアウトがサポートされているフォーマットについては、次を参照してください。 |
戻り値
DXGI_ERROR トピックで説明されているエラーコードのいずれかを返します。
解説(Remarks)
Direct3D デバイスには UNORM フォーマットが必要です。
FindClosestMatchingMode1 は、pModeToMatch で指定したモードに最も近い、利用可能なディスプレイモードを検索します。
入力としてステレオモードを指定するために、pModeToMatch が指す DXGI_MODE_DESC1 構造体の Stereo メンバーを設定した場合、FindClosestMatchingMode1 はステレオモードのみを考慮します。Stereo が設定されていない場合、FindClosestMatchingMode1 はモノラルモードのみを考慮します。
FindClosestMatchingMode1 は、同程度にランク付けされたディスプレイモードのメンバー(つまり、すべて指定済み、またはすべて未指定など)を次の順序で解決します。
- ScanlineOrdering
- Scaling
- Format
- Resolution
- RefreshRate
FindClosestMatchingMode1 は、ディスプレイモードのメンバーを、通常は指定された順序で 1 つずつ一致させます。
メンバーが未指定の場合、FindClosestMatchingMode1 はこの出力に関連するデスクトップの値に近づけます。この出力がデスクトップの一部でない場合、FindClosestMatchingMode1 は既定のデスクトップ出力を使用して値を求めます。アプリケーションが完全に未指定のディスプレイモードを使用した場合、FindClosestMatchingMode1 は通常、この出力のデスクトップ設定に一致するディスプレイモードを返します。未指定のメンバーは指定済みのメンバーよりも優先度が低いため、FindClosestMatchingMode1 は未指定のメンバーを指定済みのメンバーよりも後で解決します。
ディスプレイサーフェス(フロントバッファー)を、ユーザーが提供するリソースにコピーします。
| pDestination | IDXGIResource* | in | GetDisplaySurfaceData1 がディスプレイサーフェスをコピーする先のリソースを表す、リソースインターフェイスへのポインター。 |
戻り値
DXGI_ERROR トピックで説明されているエラーコードのいずれかを返します。
解説(Remarks)
GetDisplaySurfaceData1 は IDXGIOutput::GetDisplaySurfaceData に似ていますが、GetDisplaySurfaceData1 は IDXGIResource を受け取るのに対し、IDXGIOutput::GetDisplaySurfaceData は IDXGISurface を受け取る点が異なります。
入力リソースが、スワップチェーンのバッファーと等しい配列サイズ(D3D11_TEXTURE2D_DESC 構造体の ArraySize メンバー)を持つ 2D テクスチャ(ID3D11Texture2D インターフェイスで表される)でない場合、GetDisplaySurfaceData1 はエラーを返します。
元の IDXGIOutput::GetDisplaySurfaceData と更新版の GetDisplaySurfaceData1 は、まったく同じ動作をします。配列サイズが 2 のテクスチャ(ArraySize = 2)は IDXGISurface を実装しないため、GetDisplaySurfaceData1 が必要とされました。
GetDisplaySurfaceData1 は、出力が全画面モードのときにのみ呼び出すことができます。GetDisplaySurfaceData1 が成功すると、コピー先リソースにデータが格納されます。
コピー先リソースの領域を割り当てるときは、IDXGIOutput::GetDesc を使用して出力のサイズ(幅と高さ)を調べます。これは、対象モニターの回転に関係なく当てはまります。グラフィックスコンポーネント(Direct3D 11 など)によって作成されるコピー先リソースは、CPU の書き込みアクセス許可(D3D11_CPU_ACCESS_WRITE を参照)を指定して作成する必要があります。その他のサーフェスは、CPU の読み取り/書き込みアクセス許可(D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE)を指定して作成できます。GetDisplaySurfaceData1 は、サーフェスデータをコピー先リソースに合わせて変更(拡大、縮小、フォーマット変換、回転)します。GetDisplaySurfaceData1 は、ポイントサンプリングを使用して拡大と縮小を行います。
アダプターの出力を表す IDXGIOutput1 インターフェイスから、デスクトップ複製インターフェイスを作成します。
| pDevice | IUnknown* | in | デスクトップイメージの処理に使用できる Direct3D デバイスインターフェイスへのポインター。このデバイスは、出力が接続されているアダプターから作成する必要があります。 |
| ppOutputDuplication | IDXGIOutputDuplication** | out | 新しい IDXGIOutputDuplication インターフェイスを受け取る変数へのポインター。 |
戻り値
DuplicateOutput は次を返します。
- DuplicateOutput がデスクトップ複製インターフェイスの作成に成功した場合は S_OK。
- 次のいずれかの理由による E_INVALIDARG:
- 指定されたデバイス(pDevice)が無効である、正しいアダプター上で作成されていない、または IDXGIFactory1(あるいは IDXGIFactory1 を継承する、それ以降のバージョンの DXGI ファクトリインターフェイス)から作成されていない。
- 呼び出し元のアプリケーションがすでにこのデスクトップ出力を複製している。
- アプリケーションが現在のデスクトップイメージへのアクセス権を持っていない場合は E_ACCESSDENIED。たとえば、LOCAL_SYSTEM で実行されるアプリケーションのみがセキュアデスクトップにアクセスできます。
- 作成された IDXGIOutputDuplication インターフェイスが、現在のデスクトップモードまたはシナリオをサポートしていない場合は DXGI_ERROR_UNSUPPORTED。たとえば、8bpp および非 DWM デスクトップモードはサポートされていません。DuplicateOutput が DXGI_ERROR_UNSUPPORTED で失敗した場合、アプリケーションはデスクトップの切り替えやモード変更のシステム通知を待ち、そのような通知が発生した後に DuplicateOutput を再度呼び出すことができます。詳細については、EVENT_SYSTEM_DESKTOPSWITCH およびモード変更通知(WM_DISPLAYCHANGE)を参照してください。
- DXGI が同時実行できる複製アプリケーションの最大数の上限(既定では 4)に達した場合は DXGI_ERROR_NOT_CURRENTLY_AVAILABLE。したがって、他のアプリケーションが閉じられるまで、呼び出し元のアプリケーションはデスクトップ複製インターフェイスを作成できません。
- セッションが現在切断されているために DuplicateOutput が失敗した場合は DXGI_ERROR_SESSION_DISCONNECTED。
- その他のエラーコードについては、DXGI_ERROR トピックで説明されています。
Platform Update for Windows 7: Platform Update for Windows 7 がインストールされた Windows 7 または Windows Server 2008 R2 では、DuplicateOutput は E_NOTIMPL で失敗します。Platform Update for Windows 7 の詳細については、Platform Update for Windows 7 を参照してください。
解説(Remarks)
アプリケーションがデスクトップ全体を複製したい場合は、デスクトップ上のアクティブな出力ごとにデスクトップ複製インターフェイスを作成する必要があります。このインターフェイスは、各出力イメージのタイミングを同期する明示的な方法を提供しません。代わりに、アプリケーションは各出力のタイムスタンプを使用して、イメージを合成する方法を決定する必要があります。
DuplicateOutput を成功させるには、pDevice を IDXGIFactory1 または IDXGIFactory1 を継承する、それ以降のバージョンの DXGI ファクトリインターフェイスから作成する必要があります。
現在のモードがステレオモードの場合、デスクトップ複製インターフェイスは左側のステレオイメージのみを提供します。
既定では、1 つのセッション内で同時に IDXGIOutputDuplication インターフェイスを使用できるのは 4 つのプロセスのみです。1 つのプロセスは、1 つのデスクトップ出力に対して 1 つのデスクトップ複製インターフェイスしか持てませんが、そのプロセスはデスクトップの一部である各出力に対してデスクトップ複製インターフェイスを持つことができます。
パフォーマンスを向上させるには、DuplicateOutput1 の使用を検討してください。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IDXGIOutput1 "{00CDDEA8-939B-4B83-A340-A685226666CC}" #usecom global IDXGIOutput1 IID_IDXGIOutput1 "{}" #comfunc global IDXGIOutput1_GetDisplayModeList1 19 int,int,var,var #comfunc global IDXGIOutput1_FindClosestMatchingMode1 20 var,var,sptr #comfunc global IDXGIOutput1_GetDisplaySurfaceData1 21 sptr #comfunc global IDXGIOutput1_DuplicateOutput 22 sptr,sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IDXGIOutput1 "{00CDDEA8-939B-4B83-A340-A685226666CC}" #usecom global IDXGIOutput1 IID_IDXGIOutput1 "{}" #comfunc global IDXGIOutput1_GetDisplayModeList1 19 int,int,sptr,sptr #comfunc global IDXGIOutput1_FindClosestMatchingMode1 20 sptr,sptr,sptr #comfunc global IDXGIOutput1_GetDisplaySurfaceData1 21 sptr #comfunc global IDXGIOutput1_DuplicateOutput 22 sptr,sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。