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:
- Chame IDirect3DDeviceManager9::OpenDeviceHandle para obter um identificador para o dispositivo.
- 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 .
- Quando terminar de usar o dispositivo, chame IDirect3DDeviceManager9::UnlockDevice. Esse método disponibiliza o dispositivo para outros objetos.
- 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;
}
Tópicos relacionados