Hardwareüberlagerungsunterstützung

Eine Hardwareüberlagerung ist ein dedizierter Bereich des Videospeichers, der auf der primären Oberfläche überlagert werden kann. Es wird keine Kopie ausgeführt, wenn die Überlagerung angezeigt wird. Der Überlagerungsvorgang wird in der 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 Überlagerungen für Videoinhalte mit hoher Framerate effizient sind. Ab Windows 7 unterstützt Direct3D 9 Hardwareüberlagerungen. Diese Unterstützung ist hauptsächlich für die Videowiedergabe vorgesehen und unterscheidet sich in einigen Fällen von früheren DirectDraw-APIs:

  • Die Überlagerung kann nicht verkleinert, gespiegelt oder deinterlaced werden.
  • Quellfarbtasten und Alpha-Blending werden nicht unterstützt.
  • Überlagerungen können gestreckt werden, wenn die Overlayhardware sie unterstützt. Andernfalls wird die Dehnung nicht unterstützt. In der Praxis unterstützen nicht alle Grafiktreiber Dehnen.
  • Jedes Gerät unterstützt höchstens eine Überlagerung.
  • Überlagerung wird mithilfe eines Zielfarbschlüssels ausgeführt, aber die Direct3D-Laufzeit wählt automatisch die Farbe aus und zeichnet das Zielrechteck. Direct3D verfolgt automatisch die Position des Fensters und aktualisiert die Überlagerungsposition, wenn die PresentEx aufgerufen wird.

Erstellen einer Hardwareüberlagerungsoberfläche

Rufen Sie IDirect3D9::GetDeviceCaps auf, um die Überlagerungsunterstützung abzufragen. Wenn der Treiber hardwareüberlagerung unterstützt, wird das D3DCAPS_OVERLAY Flag im D3DCAPS9 festgelegt. Caps-Element .

Rufen Sie IDirect3D9ExoverlayExtension::CheckDeviceOverlayType auf, um herauszufinden, ob ein bestimmtes Überlagerungsformat für einen bestimmten Anzeigemodus unterstützt wird.

Rufen Sie zum Erstellen der Überlagerung IDirect3D9Ex::CreateDeviceEx auf, und geben Sie den D3DSWAPEFFECT_OVERLAY Swapeffekt an. Der Hintergrundpuffer kann ein NICHT-RGB-Format verwenden, wenn die Hardware es unterstützt.

Überlagerungsflächen weisen die folgenden Einschränkungen auf:

  • 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 Overlay-Swapeffekt muss mit der IDirect3DDevice9Ex-Schnittstelle verwendet werden. Es wird für IDirect3DDevice9 nicht unterstützt.
  • Multisampling kann nicht verwendet werden.
  • Die kennzeichnungen D3DPRESENT_DONOTFLIP und D3DPRESENT_FLIPRESTART werden nicht unterstützt.
  • Präsentationsstatistiken sind für die Überlagerungsoberfläche nicht verfügbar.

Wenn die Hardware das Dehnen nicht unterstützt, empfiehlt es sich, eine Swapchain so groß wie der Anzeigemodus zu erstellen, damit das Fenster in beliebige Dimensionen geändert werden kann. Das Erneute Erstellen der Swapchain ist keine optimale Möglichkeit, die Größe des Fensters zu ändern, da es zu schwerwiegenden Renderingartefakten führen kann. Aufgrund der Art und Weise, wie die GPU den Überlagerungsspeicher verwaltet, kann das Erneute Erstellen der Swapchain möglicherweise dazu führen, dass eine Anwendung den Videospeicher ausläuft.

Neue D3DPRESENT_PARAMETERS Flags

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

Flag Beschreibung
D3DPRESENTFLAG_OVERLAY_LIMITEDRGB Der RGB-Bereich beträgt 16 bis 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 erweiterter YCbCr (xvYCC) aus.
Erfordert die funktion D3DOVERLAYCAPS_YCbCr_BT601_xvYCC oder D3DOVERLAYCAPS_YCbCr_BT709_xvYCC .

 

Verwenden von Hardwareüberlagerungen

Um die Überlagerungsoberfläche anzuzeigen, ruft die Anwendung IDirect3DDevice9Ex::P resentEx auf. Die Direct3D-Laufzeit zeichnet automatisch den Zielfarbschlüssel.

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

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

 

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

  • Wenn eine andere Anwendung das Overlay verwendet, gibt PresentExD3DERR_NOTAVAILABLE zurück.
  • Wenn das Fenster in einen anderen Monitor verschoben wird, muss die Anwendung die Swapchain neu erstellen. Andernfalls ruft die Anwendung PresentEx auf, 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 Sie eine Überlagerungsoberfläche erstellen.

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