Gerenciador de Dispositivos Direct3D

O gerenciador de dispositivos Do Microsoft Direct3D permite que dois ou mais objetos compartilhem o mesmo dispositivo Microsoft Direct3D 9. Um objeto atua como o proprietário do dispositivo Direct3D 9. Para compartilhar o dispositivo, o proprietário do dispositivo cria o gerenciador de dispositivos Direct3D. Outros objetos podem obter um ponteiro para o gerenciador de dispositivos do proprietário do dispositivo e, em seguida, usar o gerenciador de dispositivos para obter um ponteiro para o dispositivo Direct3D. Qualquer objeto que usa o dispositivo contém um bloqueio exclusivo, o que impede que outros objetos usem o dispositivo ao mesmo tempo.

Observação

O Gerenciador de Dispositivos Direct3D dá suporte apenas a dispositivos Direct3D 9. Ele não dá suporte a dispositivos DXGI.

 

Para criar o gerenciador de dispositivos Direct3D, chame DXVA2CreateDirect3DDeviceManager9. Essa função retorna um ponteiro para a interface IDirect3DDeviceManager9 do gerenciador de dispositivos, juntamente com um token de redefinição. O token de redefinição permite que o proprietário do dispositivo Direct3D defina (e redefina) o dispositivo no gerenciador de dispositivos. Para inicializar o gerenciador de dispositivos, chame IDirect3DDeviceManager9::ResetDevice. Passe um ponteiro para o dispositivo Direct3D, juntamente com o token de redefinição.

O código a seguir mostra como criar e inicializar o gerenciador de dispositivos.

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;
}

O proprietário do dispositivo deve fornecer uma maneira de outros objetos obterem um ponteiro para a interface IDirect3DDeviceManager9 . O mecanismo padrão é implementar a interface IMFGetService . O GUID de serviço é MR_VIDEO_ACCELERATION_SERVICE.

Para compartilhar o dispositivo entre vários objetos, cada objeto (incluindo o proprietário do dispositivo) deve acessar o dispositivo por meio do gerenciador de dispositivos, da seguinte maneira:

  1. Chame IDirect3DDeviceManager9::OpenDeviceHandle para obter um identificador para o dispositivo.
  2. Para usar o dispositivo, chame IDirect3DDeviceManager9::LockDevice e passe o identificador do dispositivo. O método retorna um ponteiro para a interface IDirect3DDevice9 . O método pode ser chamado em um modo de bloqueio ou em um modo sem bloqueio, dependendo do valor do parâmetro fBlock .
  3. Quando terminar de usar o dispositivo, chame IDirect3DDeviceManager9::UnlockDevice. Esse método disponibiliza o dispositivo para outros objetos.
  4. Antes de sair, chame IDirect3DDeviceManager9::CloseDeviceHandle para fechar o identificador do dispositivo.

Você deve manter o bloqueio do dispositivo somente ao usar o dispositivo, pois manter o bloqueio do dispositivo impede que outros objetos usem o dispositivo.

O proprietário do dispositivo pode alternar para outro dispositivo a qualquer momento chamando ResetDevice, normalmente porque o dispositivo original foi perdido. A perda de dispositivo pode ocorrer por vários motivos, incluindo alterações na resolução do monitor, ações de gerenciamento de energia, bloqueio e desbloqueio do computador e assim por diante. Para obter mais informações, consulte a documentação do Direct3D.

O método ResetDevice invalida todos os identificadores de dispositivo que foram abertos anteriormente. Quando um identificador de dispositivo é inválido, o método LockDevice retorna DXVA2_E_NEW_VIDEO_DEVICE. Se isso ocorrer, feche o identificador e chame OpenDeviceHandle novamente para obter um novo identificador de dispositivo, conforme mostrado no código a seguir.

O exemplo a seguir mostra como abrir um identificador de dispositivo e bloquear o dispositivo.

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;
}

Aceleração de Vídeo Do DirectX 2.0