Udostępnij za pośrednictwem


Menedżer urządzeń Direct3D

Menedżer urządzeń Microsoft Direct3D umożliwia co najmniej dwa obiekty współużytkowania tego samego urządzenia Microsoft Direct3D 9. Jeden obiekt działa jako właściciel urządzenia Direct3D 9. Aby udostępnić urządzenie, właściciel urządzenia tworzy menedżera urządzeń Direct3D. Inne obiekty mogą uzyskać wskaźnik do menedżera urządzeń od właściciela urządzenia, a następnie użyć menedżera urządzeń, aby uzyskać wskaźnik do urządzenia Direct3D. Każdy obiekt, który korzysta z urządzenia, posiada wyłączną blokadę, co uniemożliwia innym obiektom jednoczesne korzystanie z urządzenia.

Nuta

Menedżer urządzeń Direct3D obsługuje tylko urządzenia Direct3D 9. Nie obsługuje urządzeń DXGI.

 

Aby utworzyć menedżera urządzeń Direct3D, wywołaj DXVA2CreateDirect3DDeviceManager9. Ta funkcja zwraca wskaźnik do interfejsuIDirect3DDeviceManager9 menedżera urządzeń wraz z tokenem resetowania. Token resetowania umożliwia właścicielowi urządzenia Direct3D ustawienie (i zresetowanie) urządzenia w Menedżerze urządzeń. Aby zainicjować menedżera urządzeń, wywołaj IDirect3DDeviceManager9::ResetDevice. Przekaż wskaźnik do urządzenia Direct3D wraz z tokenem resetowania.

Poniższy kod pokazuje, jak utworzyć i zainicjować menedżera urządzeń.

HRESULT CreateD3DDeviceManager(
    IDirect3DDevice9 *pDevice, 
    UINT *pReset, 
    IDirect3DDeviceManager9 **ppManager
    )
{
    UINT resetToken = 0;

    IDirect3DDeviceManager9 *pD3DManager = NULL;

    HRESULT hr = DXVA2CreateDirect3DDeviceManager9(&resetToken, &pD3DManager);

    if (FAILED(hr))
    {
        goto done;
    }

    hr = pD3DManager->ResetDevice(pDevice, resetToken);

    if (FAILED(hr))
    {
        goto done;
    }

    *ppManager = pD3DManager;
    (*ppManager)->AddRef();

    *pReset = resetToken;


done:
    SafeRelease(&pD3DManager);
    return hr;
}

Właściciel urządzenia musi zapewnić innym obiektom możliwość uzyskania wskaźnika do interfejsu IDirect3DDeviceManager9. Standardowy mechanizm polega na zaimplementowaniu interfejsuIMFGetService. Identyfikator GUID usługi jest MR_VIDEO_ACCELERATION_SERVICE.

Aby udostępnić urządzenie między kilkoma obiektami, każdy obiekt (w tym właściciel urządzenia) musi uzyskać dostęp do urządzenia za pośrednictwem menedżera urządzeń w następujący sposób:

  1. Wywołaj IDirect3DDeviceManager9::OpenDeviceHandle, aby uzyskać dojście do urządzenia.
  2. Aby użyć urządzenia, wywołaj IDirect3DDeviceManager9::LockDevice i przekaż uchwyt urządzenia. Metoda zwraca wskaźnik do interfejsu IDirect3DDevice9. Metodę można wywołać w trybie blokowania lub trybie nieblokowania, w zależności od wartości parametru fBlock.
  3. Po zakończeniu korzystania z urządzenia wywołaj IDirect3DDeviceManager9::UnlockDevice. Ta metoda udostępnia urządzenie innym obiektom.
  4. Przed zakończeniem wywołaj IDirect3DDeviceManager9::CloseDeviceHandle, aby zamknąć uchwyt urządzenia.

Blokada urządzenia powinna być przechowywana tylko podczas korzystania z urządzenia, ponieważ blokada urządzenia uniemożliwia korzystanie z urządzenia przez inne obiekty.

Właściciel urządzenia może w dowolnym momencie przełączyć się na inne urządzenie, wywołując ResetDevice, zazwyczaj dlatego, że oryginalne urządzenie zostało utracone. Utrata urządzenia może wystąpić z różnych powodów, w tym zmiany w rozdzielczości monitora, akcje zarządzania energią, blokowanie i odblokowywanie komputera itd. Aby uzyskać więcej informacji, zobacz dokumentację Direct3D.

Metoda ResetDevice unieważnia wszystkie otwarte wcześniej uchwyty urządzeń. Gdy uchwyt urządzenia jest nieprawidłowy, metoda LockDevice zwraca metodę DXVA2_E_NEW_VIDEO_DEVICE. W takim przypadku zamknij dojście i wywołaj OpenDeviceHandle ponownie, aby uzyskać nowy uchwyt urządzenia, jak pokazano w poniższym kodzie.

W poniższym przykładzie pokazano, jak otworzyć uchwyt urządzenia i zablokować urządzenie.

HRESULT LockDevice(
    IDirect3DDeviceManager9 *pDeviceManager,
    BOOL fBlock,
    IDirect3DDevice9 **ppDevice, // Receives a pointer to the device.
    HANDLE *pHandle              // Receives a device handle.   
    )
{
    *pHandle = NULL;
    *ppDevice = NULL;

    HANDLE hDevice = 0;

    HRESULT hr = pDeviceManager->OpenDeviceHandle(&hDevice);

    if (SUCCEEDED(hr))
    {
        hr = pDeviceManager->LockDevice(hDevice, ppDevice, fBlock);
    }

    if (hr == DXVA2_E_NEW_VIDEO_DEVICE)
    {
        // Invalid device handle. Try to open a new device handle.
        hr = pDeviceManager->CloseDeviceHandle(hDevice);

        if (SUCCEEDED(hr))
        {
            hr = pDeviceManager->OpenDeviceHandle(&hDevice);
        }

        // Try to lock the device again.
        if (SUCCEEDED(hr))
        {
            hr = pDeviceManager->LockDevice(hDevice, ppDevice, TRUE); 
        }
    }

    if (SUCCEEDED(hr))
    {
        *pHandle = hDevice;
    }
    return hr;
}

DirectX Video Acceleration 2.0