ハードウェア オーバーレイのサポート

ハードウェア オーバーレイは、プライマリ サーフェスにオーバーレイできるビデオ メモリの専用領域です。 オーバーレイが表示されている場合、コピーは実行されません。 オーバーレイ操作はハードウェアで実行され、プライマリ サーフェスのデータは変更されません。

以前のバージョンの Windows では、ビデオ再生にハードウェア オーバーレイを使用するのが一般的でした。これは、フレーム レートが高いビデオ コンテンツではオーバーレイが効率的であるためです。 Windows 7 以降、Direct3D 9 ではハードウェア オーバーレイがサポートされています。 このサポートは主にビデオ再生を目的としており、以前の DirectDraw API とは一部の点で異なります。

  • オーバーレイを圧縮、ミラー化、またはインターレース解除することはできません。
  • ソース カラー キーとアルファ ブレンドはサポートされていません。
  • オーバーレイ ハードウェアでサポートされている場合は、オーバーレイを引き伸ばすことができます。 それ以外の場合、ストレッチはサポートされていません。 実際には、すべてのグラフィックス ドライバーがストレッチをサポートしているわけではありません。
  • 各デバイスでは、最大 1 つのオーバーレイがサポートされます。
  • オーバーレイは変換先の色キーを使用して実行されますが、Direct3D ランタイムによって色が自動的に選択され、変換先の四角形が描画されます。 Direct3D は、 PresentEx が呼び出されるたびに、ウィンドウの位置を自動的に追跡し、オーバーレイの位置を更新します。

ハードウェア オーバーレイ サーフェスの作成

オーバーレイのサポートを照会するには、 IDirect3D9::GetDeviceCaps を呼び出します。 ドライバーがハードウェア オーバーレイをサポートしている場合はD3DCAPS9 でD3DCAPS_OVERLAY フラグが設定されます。Caps メンバー。

特定の表示モードで特定のオーバーレイ形式がサポートされているかどうかを確認するには、 IDirect3D9ExOverlayExtension::CheckDeviceOverlayType を呼び出します。

オーバーレイを作成するには、 IDirect3D9Ex::CreateDeviceEx を呼び出し、 D3DSWAPEFFECT_OVERLAY スワップ効果を指定します。 バック バッファーでは、ハードウェアでサポートされている場合は、RGB 以外の形式を使用できます。

オーバーレイ サーフェスには、次の制限があります。

  • アプリケーションで複数のオーバーレイ スワップ チェーンを作成することはできません。
  • オーバーレイはウィンドウ モードで使用する必要があります。 全画面表示モードでは使用できません。
  • オーバーレイ スワップ効果は 、IDirect3DDevice9Ex インターフェイスで使用する必要があります。 IDirect3DDevice9 ではサポートされていません。
  • マルチサンプリングは使用できません。
  • D3DPRESENT_DONOTFLIPフラグとD3DPRESENT_FLIPRESTART フラグはサポートされていません。
  • オーバーレイ サーフェスでは、プレゼンテーションの統計情報を使用できません。

ハードウェアがストレッチをサポートしていない場合は、ウィンドウのサイズを任意のサイズに変更できるように、表示モードと同じ大きさのスワップ チェーンを作成することをお勧めします。 スワップ チェーンを再作成することは、ウィンドウのサイズ変更を処理するための最適な方法ではありません。これは、重大なレンダリングアーティファクトを引き起こす可能性があるためです。 また、GPU によってオーバーレイ メモリが管理されるため、スワップ チェーンを再作成すると、アプリケーションがビデオ メモリを使い果たされる可能性があります。

新しいD3DPRESENT_PARAMETERS フラグ

オーバーレイを作成するために、次の D3DPRESENT_PARAMETERS フラグが定義されています。

フラグ 説明
D3DPRESENTFLAG_OVERLAY_LIMITEDRGB RGB 範囲は 16 から 235 です。 既定値は 0 から 255 です。
D3DOVERLAYCAPS_LIMITEDRANGERGB機能が必要です。
D3DPRESENTFLAG_OVERLAY_YCbCr_BT709 YUV 色は BT.709 定義を使用します。 既定値は BT.601 です。
D3DOVERLAYCAPS_YCbCr_BT709機能が必要です。
D3DPRESENTFLAG_OVERLAY_YCbCr_xvYCC 拡張 YCbCr (xvYCC) を使用してデータを出力します。
D3DOVERLAYCAPS_YCbCr_BT601_xvYCCまたは D3DOVERLAYCAPS_YCbCr_BT709_xvYCC 機能 必要です。

 

ハードウェア オーバーレイの使用

オーバーレイ画面を表示するために、アプリケーションは IDirect3DDevice9Ex::P resentEx を呼び出します。 Direct3D ランタイムは、変換先の色キーを自動的に描画します。

オーバーレイには、次の PresentEx フラグが定義されています。

フラグ 説明
D3DPRESENT_UPDATECOLORKEY デスクトップ ウィンドウ マネージャー (DWM) コンポジションが無効になっている場合は、このフラグを設定します。 このフラグにより、Direct3D はカラー キーを再描画します。
DWM が有効になっている場合、Direct3D は DWM がリダイレクトに使用するサーフェスにカラー キーを 1 回描画するため、このフラグは必要ありません。
D3DPRESENT_HIDEOVERLAY オーバーレイを非表示にします。
D3DPRESENT_UPDATEOVERLAYONLY 内容を変更せずにオーバーレイを更新します。
このフラグは、ビデオの一時停止中にウィンドウが移動する場合に便利です。

 

アプリケーションは、次の場合に対応できるように準備する必要があります。

  • 別のアプリケーションがオーバーレイを使用している場合、 PresentExD3DERR_NOTAVAILABLEを返します。
  • ウィンドウが別のモニターに移動された場合、アプリケーションはスワップ チェーンを再作成する必要があります。 それ以外の場合、アプリケーションが PresentEx を呼び出して別のモニターにオーバーレイを表示すると、PresentEx はD3DERR_INVALIDDEVICEを返します。
  • 表示モードが変更されると、Direct3D はオーバーレイの復元を試みます。 新しいモードでオーバーレイがサポートされていない場合、 PresentExD3DERR_UNSUPPORTEDOVERLAYを返します。

コード例

次の例は、オーバーレイ サーフェスを作成する方法を示しています。

const UINT VIDEO_WIDTH = 256;
const UINT VIDEO_HEIGHT = 256;

HRESULT CreateHWOverlay(
    HWND hwnd, 
    IDirect3D9Ex *pD3D, 
    IDirect3DDevice9Ex **ppDevice
    )
{
    *ppDevice = NULL;

    D3DCAPS9                caps;
    ZeroMemory(&caps, sizeof(caps));

    HRESULT hr = pD3D->GetDeviceCaps(
        D3DADAPTER_DEFAULT,
        D3DDEVTYPE_HAL,
        &caps
        );

    if (FAILED(hr))
    {
        return hr;
    }

    // Check if overlay is supported.
    if (!(caps.Caps & D3DCAPS_OVERLAY))
    {
        return D3DERR_UNSUPPORTEDOVERLAY;
    }

    D3DOVERLAYCAPS          overlayCaps = { 0 };

    IDirect3DDevice9Ex           *pDevice = NULL;
    IDirect3D9ExOverlayExtension *pOverlay = NULL;

    // Check specific overlay capabilities.
    hr = pD3D->QueryInterface(IID_PPV_ARGS(&pOverlay));

    if (SUCCEEDED(hr))
    {
        hr = pOverlay->CheckDeviceOverlayType(
            D3DADAPTER_DEFAULT,
            D3DDEVTYPE_HAL,
            VIDEO_WIDTH,
            VIDEO_HEIGHT,
            D3DFMT_X8R8G8B8,
            NULL,
            D3DDISPLAYROTATION_IDENTITY,
            &overlayCaps
            );
    }

    // Create the overlay.
    if (SUCCEEDED(hr))
    {

        DWORD flags =   D3DCREATE_FPU_PRESERVE | 
                        D3DCREATE_MULTITHREADED | 
                        D3DCREATE_SOFTWARE_VERTEXPROCESSING;

        
        D3DPRESENT_PARAMETERS   pp = { 0 };

        pp.BackBufferWidth = overlayCaps.MaxOverlayDisplayWidth;
        pp.BackBufferHeight = overlayCaps.MaxOverlayDisplayHeight;
        pp.BackBufferFormat = D3DFMT_X8R8G8B8;
        pp.SwapEffect = D3DSWAPEFFECT_OVERLAY;
        pp.hDeviceWindow = hwnd;
        pp.Windowed = TRUE;
        pp.Flags = D3DPRESENTFLAG_VIDEO;
        pp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
        pp.PresentationInterval       = D3DPRESENT_INTERVAL_ONE;

        hr = pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
            NULL, flags, &pp, NULL, &pDevice);
    }

    if (SUCCEEDED(hr))
    {
        (*ppDevice) = pDevice;
        (*ppDevice)->AddRef();
    }

    SafeRelease(&pD3D);
    SafeRelease(&pDevice);
    SafeRelease(&pOverlay);
    return hr;
}

Direct3D ビデオ API