Direct3D Device Manager
Správce zařízení Microsoft Direct3D umožňuje dvěma nebo více objektům sdílet stejné zařízení Microsoft Direct3D 9. Jeden objekt funguje jako vlastník zařízení Direct3D 9. Pokud chcete zařízení sdílet, vlastník zařízení vytvoří správce zařízení Direct3D. Jiné objekty mohou získat ukazatel na správce zařízení od vlastníka zařízení a pak pomocí správce zařízení získat ukazatel na zařízení Direct3D. Všechny objekty, které zařízení používají, mají výhradní zámek, který brání ostatním objektům v používání zařízení současně.
Poznámka
Správce zařízení Direct3D podporuje pouze zařízení Direct3D 9. Nepodporuje zařízení DXGI.
Chcete-li vytvořit správce zařízení Direct3D, zavolejte DXVA2CreateDirect3DDeviceManager9. Tato funkce vrátí ukazatel na rozhraní správce zařízení IDirect3DDeviceManager9 společně s resetováním tokenu. Token pro resetování umožňuje vlastníkovi zařízení Direct3D nastavit (a resetovat) zařízení ve správci zařízení. Chcete-li inicializovat správce zařízení, zavolejte IDirect3DDeviceManager9::ResetDevice. Předejte ukazatel na zařízení Direct3D spolu s resetováním tokenu.
Následující kód ukazuje, jak vytvořit a inicializovat správce zařízení.
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;
}
Vlastník zařízení musí poskytnout způsob, jak jiným objektům získat ukazatel na rozhraní IDirect3DDeviceManager9. Standardním mechanismem je implementace rozhraní MMFGetService. Identifikátor GUID služby je MR_VIDEO_ACCELERATION_SERVICE.
Pokud chcete sdílet zařízení mezi několika objekty, musí každý objekt (včetně vlastníka zařízení) přistupovat k zařízení prostřednictvím správce zařízení následujícím způsobem:
- Volání IDirect3DDeviceManager9::OpenDeviceHandle získat popisovač zařízení.
- Pokud chcete zařízení použít, zavolejte IDirect3DDeviceManager9::LockDevice a předejte popisovač zařízení. Metoda vrátí ukazatel na rozhraní IDirect3DDevice9. Metodu lze volat v režimu blokování nebo neblokující režim v závislosti na hodnotě fBlock parametru.
- Po dokončení používání zařízení zavolejte IDirect3DDeviceManager9::UnlockDevice. Tato metoda zpřístupní zařízení jiným objektům.
- Před ukončením volejte IDirect3DDeviceManager9::CloseDeviceHandle zavřete popisovač zařízení.
Zámek zařízení byste měli uchovávat jenom při používání zařízení, protože přidržením zámku zařízení zabráníte jiným objektům v používání zařízení.
Vlastník zařízení může kdykoli přepnout na jiné zařízení voláním ResetDevice, obvykle kvůli ztrátě původního zařízení. Ke ztrátě zařízení může dojít z různých důvodů, včetně změn v rozlišení monitoru, akcí řízení spotřeby, uzamčení a odemčení počítače atd. Další informace najdete v dokumentaci k Direct3D.
Metoda ResetDevice zneplatní všechny popisovače zařízení, které byly dříve otevřeny. Pokud je popisovač zařízení neplatný, metoda LockDevice vrátí DXVA2_E_NEW_VIDEO_DEVICE. Pokud k tomu dojde, zavřete popisovač a volání OpenDeviceHandle znovu získat nový popisovač zařízení, jak je znázorněno v následujícím kódu.
Následující příklad ukazuje, jak otevřít popisovač zařízení a uzamknout zařízení.
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;
}
Související témata