Hardwareüberlagerungsunterstützung

Ein Hardwareüberlagerung ist ein dedizierter Bereich des Videospeichers, der auf der primären Oberfläche überlagert werden kann. Wenn die Überlagerung angezeigt wird, wird kein Kopiervorgang ausgeführt. Der Überlagerungsvorgang wird auf Hardware ausgeführt, ohne die Daten auf der primären Oberfläche zu ändern.

Die Verwendung von Hardwareüberlagerungen für die Videowiedergabe war in früheren Versionen von Windows üblich, da Overlays für Videoinhalte mit einer hohen Bildfrequenz effizient sind. Ab Windows 7 unterstützt Direct3D 9 Hardwareüberlagerungen. Diese Unterstützung ist in erster Linie für die Videowiedergabe vorgesehen und unterscheidet sich in einigen Punkten von früheren DirectDraw-APIs:

  • Die Überlagerung kann nicht verkleinert, gespiegelt oder deinterlaced werden.
  • Quellfarbschlüssel und Alphamischung werden nicht unterstützt.
  • Überlagerungen können gestreckt werden, wenn die Overlayhardware dies unterstützt. Andernfalls wird das Dehnen nicht unterstützt. In der Praxis unterstützen nicht alle Grafiktreiber Stretching.
  • Jedes Gerät unterstützt höchstens ein Overlay.
  • Das Überlagern wird mithilfe eines Zielfarbschlüssels ausgeführt, aber die Direct3D-Runtime wählt automatisch die Farbe aus und zeichnet das Zielrechteck. Direct3D verfolgt automatisch die Position des Fensters nach und aktualisiert die Überlagerungsposition, wenn presentEx aufgerufen wird.

Erstellen einer Hardwareüberlagerungsoberfläche

Rufen Sie IDirect3D9::GetDeviceCaps auf, um die Unterstützung für Overlays abzufragen. Wenn der Treiber Hardwareüberlagerungen unterstützt, wird das flag D3DCAPS_OVERLAY im D3DCAPS9 festgelegt. Caps-Member .

Um herauszufinden, ob ein bestimmtes Überlagerungsformat für einen bestimmten Anzeigemodus unterstützt wird, rufen Sie IDirect3D9ExOverlayExtension::CheckDeviceOverlayType auf.

Rufen Sie zum Erstellen der Überlagerung IDirect3D9Ex::CreateDeviceEx auf, und geben Sie den D3DSWAPEFFECT_OVERLAY Tauscheffekt an. Der Hintergrundpuffer kann ein Nicht-RGB-Format verwenden, wenn dies von der Hardware unterstützt wird.

Für Überlagerungsoberflächen gelten die folgenden Einschränkungen:

  • Die Anwendung kann nicht mehr als eine Overlay-Swapchain erstellen.
  • Die Überlagerung muss im Fenstermodus verwendet werden. Sie kann nicht im Vollbildmodus verwendet werden.
  • Der Überlagerungseffekt muss mit der IDirect3DDevice9Ex-Schnittstelle verwendet werden. IDirect3DDevice9 wird nicht unterstützt.
  • Multisampling kann nicht verwendet werden.
  • Die flags D3DPRESENT_DONOTFLIP und D3DPRESENT_FLIPRESTART werden nicht unterstützt.
  • Präsentationsstatistiken sind für die Überlagerungsoberfläche nicht verfügbar.

Wenn die Hardware keine Dehnung unterstützt, wird empfohlen, eine Swapchain zu erstellen, die so groß ist wie der Anzeigemodus, damit die Größe des Fensters auf beliebige Dimensionen angepasst werden kann. Das Erneute Erstellen der Swapchain ist keine optimale Möglichkeit, die Größenänderung des Fensters zu verarbeiten, da dies zu schwerwiegenden Renderingartefakten führen kann. Aufgrund der Art und Weise, wie die GPU den Überlagerungsspeicher verwaltet, kann die Neuerstellung der Swapchain möglicherweise dazu führen, dass für eine Anwendung nicht mehr genügend Videospeicher vorhanden ist.

Neue D3DPRESENT_PARAMETERS Flags

Die folgenden D3DPRESENT_PARAMETERS-Flags werden zum Erstellen von Überlagerungen definiert.

Flag Beschreibung
D3DPRESENTFLAG_OVERLAY_LIMITEDRGB Der RGB-Bereich liegt zwischen 16 und 235. Der Standardwert ist 0–255.
Erfordert die D3DOVERLAYCAPS_LIMITEDRANGERGB-Funktion .
D3DPRESENTFLAG_OVERLAY_YCbCr_BT709 YUV-Farben verwenden die BT.709-Definition. Der Standardwert ist BT.601.
Erfordert die D3DOVERLAYCAPS_YCbCr_BT709-Funktion .
D3DPRESENTFLAG_OVERLAY_YCbCr_xvYCC Geben Sie die Daten mithilfe des erweiterten YCbCr (xvYCC) aus.
Erfordert die D3DOVERLAYCAPS_YCbCr_BT601_xvYCC- oder D3DOVERLAYCAPS_YCbCr_BT709_xvYCC-Funktion .

 

Verwenden von Hardwareüberlagerungen

Zum Anzeigen der Überlagerungsoberfläche ruft die Anwendung IDirect3DDevice9Ex::P resentEx auf. Die Direct3D-Runtime zeichnet automatisch den Zielfarbschlüssel.

Die folgenden PresentEx-Flags sind für Überlagerungen definiert.

Flag Beschreibung
D3DPRESENT_UPDATECOLORKEY Legen Sie dieses Flag fest, wenn die DwM-Komposition (Desktop Window Manager) deaktiviert ist. Dieses Flag bewirkt, dass Direct3D den Farbschlüssel neu zeichnet.
Wenn DWM aktiviert ist, ist dieses Flag nicht erforderlich, da Direct3D den Farbschlüssel einmal auf der Oberfläche zeichnet, die DWM für die Umleitung verwendet.
D3DPRESENT_HIDEOVERLAY Blendet die Überlagerung aus.
D3DPRESENT_UPDATEOVERLAYONLY Updates die Überlagerung, ohne den Inhalt zu ändern.
Dieses Flag ist nützlich, wenn das Fenster verschoben wird, während das Video angehalten wird.

 

Eine Anwendung sollte vorbereitet sein, um die folgenden Fälle zu behandeln:

  • Wenn eine andere Anwendung die Überlagerung verwendet, gibt PresentExD3DERR_NOTAVAILABLE zurück.
  • Wenn das Fenster auf einen anderen Monitor verschoben wird, muss die Anwendung die Swapchain neu erstellen. Wenn die Anwendung PresentEx aufruft, um die Überlagerung auf einem anderen Monitor anzuzeigen, gibt PresentExD3DERR_INVALIDDEVICE zurück.
  • Wenn sich der Anzeigemodus ändert, versucht Direct3D, die Überlagerung wiederherzustellen. Wenn der neue Modus die Überlagerung nicht unterstützt, gibt PresentExD3DERR_UNSUPPORTEDOVERLAY zurück.

Beispielcode

Das folgende Beispiel zeigt, wie Eine Überlagerungsoberfläche erstellt wird.

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-Video-APIs