Direct3D Device Manager
Med Enhetshanteraren för Microsoft Direct3D kan två eller flera objekt dela samma Microsoft Direct3D 9-enhet. Ett objekt fungerar som ägare till Direct3D 9-enheten. Om du vill dela enheten skapar enhetens ägare Direct3D-enhetshanteraren. Andra objekt kan hämta en pekare till enhetshanteraren från enhetsägaren och sedan använda enhetshanteraren för att hämta en pekare till Direct3D-enheten. Alla objekt som använder enheten har ett exklusivt lås som förhindrar att andra objekt använder enheten samtidigt.
Not
Direct3D Device Manager stöder endast Direct3D 9-enheter. Det stöder inte DXGI-enheter.
Om du vill skapa Direct3D-enhetshanteraren anropar du DXVA2CreateDirect3DDeviceManager9. Den här funktionen returnerar en pekare till enhetshanterarens IDirect3DDeviceManager9- gränssnitt, tillsammans med en återställningstoken. Med återställningstoken kan ägaren till Direct3D-enheten ange (och återställa) enheten i enhetshanteraren. Om du vill initiera enhetshanteraren anropar du IDirect3DDeviceManager9::ResetDevice. Skicka in en pekare till Direct3D-enheten tillsammans med återställningstoken.
Följande kod visar hur du skapar och initierar enhetshanteraren.
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;
}
Enhetsägaren måste tillhandahålla ett sätt för andra objekt att få en pekare till IDirect3DDeviceManager9-gränssnittet. Standardmekanismen är att implementera gränssnittet IMFGetService. Tjänstens GUID är MR_VIDEO_ACCELERATION_SERVICE.
Om du vill dela enheten mellan flera objekt måste varje objekt (inklusive enhetens ägare) komma åt enheten via enhetshanteraren enligt följande:
- Anropa IDirect3DDeviceManager9::OpenDeviceHandle för att hämta ett handtag till enheten.
- Om du vill använda enheten anropar du IDirect3DDeviceManager9::LockDevice och skickar in enhetshandtaget. Metoden returnerar en pekare till gränssnittet IDirect3DDevice9. Metoden kan anropas i ett blockeringsläge eller ett icke-blockerande läge, beroende på värdet för parametern fBlock.
- När du är klar med enheten anropar du IDirect3DDeviceManager9::UnlockDevice. Den här metoden gör enheten tillgänglig för andra objekt.
- Innan du avslutar anropar du IDirect3DDeviceManager9::CloseDeviceHandle för att stänga enhetshandtaget.
Du bör endast hålla kvar enhetslåset när du använder enheten, eftersom om du håller i enhetslåset hindrar du andra objekt från att använda enheten.
Enhetens ägare kan när som helst växla till en annan enhet genom att anropa ResetDevice, vanligtvis eftersom den ursprungliga enheten gick förlorad. Enhetsförlust kan inträffa av olika orsaker, till exempel ändringar i övervakningsupplösningen, energisparåtgärder, låsning och upplåsning av datorn och så vidare. Mer information finns i Direct3D-dokumentationen.
Metoden ResetDevice ogiltigförklarar alla enhetshandtag som öppnades tidigare. När ett enhetshandtag är ogiltigt returnerar metoden LockDeviceDXVA2_E_NEW_VIDEO_DEVICE. Om detta inträffar stänger du handtaget och anropar OpenDeviceHandle igen för att hämta ett nytt enhetshandtag, enligt följande kod.
I följande exempel visas hur du öppnar ett enhetshandtag och låser enheten.
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;
}
Relaterade ämnen