Direct3D 裝置管理員
Microsoft Direct3D 裝置管理員可讓兩個或多個物件共用相同的 Microsoft Direct3D 9 裝置。 一個物件可作為 Direct3D 9 裝置的擁有者。 若要共用裝置,裝置的擁有者會建立 Direct3D 裝置管理員。 其他物件可以從裝置擁有者取得裝置管理員的指標,然後使用裝置管理員取得 Direct3D 裝置的指標。 使用裝置的任何物件都會保留獨佔鎖定,以防止其他物件同時使用裝置。
注意
Direct3D 裝置管理員僅支援 Direct3D 9 裝置。 它不支援 DXGI 裝置。
若要建立 Direct3D 裝置管理員,請呼叫 DXVA2CreateDirect3DDeviceManager9。 此函式會傳回裝置管理員 IDirect3DDeviceManager9 介面的指標,以及重設權杖。 重設權杖可讓 Direct3D 裝置的擁有者在裝置管理員上設定 (並重設) 裝置。 若要初始化裝置管理員,請呼叫 IDirect3DDeviceManager9::ResetDevice。 傳入 Direct3D 裝置的指標,以及重設權杖。
下列程式碼示範如何建立和初始化裝置管理員。
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;
}
裝置擁有者必須提供方法,讓其他物件取得 IDirect3DDeviceManager9 介面的指標。 標準機制是實作 IMFGetService 介面。 服務 GUID MR_VIDEO_ACCELERATION_SERVICE。
若要在數個物件之間共用裝置,每個物件 (包括裝置擁有者) 必須透過裝置管理員存取裝置,如下所示:
- 呼叫 IDirect3DDeviceManager9::OpenDeviceHandle 以取得裝置的控制碼。
- 若要使用裝置,請呼叫 IDirect3DDeviceManager9::LockDevice 並傳入裝置控制碼。 方法會傳回 IDirect3DDevice9 介面的指標。 方法可以在封鎖模式或非封鎖模式中呼叫,視 fBlock 參數的值而定。
- 當您使用裝置完成時,請呼叫 IDirect3DDeviceManager9::UnlockDevice。 這個方法可讓裝置可供其他物件使用。
- 結束之前,請呼叫 IDirect3DDeviceManager9::CloseDeviceHandle 以關閉裝置控制碼。
您應該只在使用裝置時保留裝置鎖定,因為保留裝置鎖定可防止其他物件使用裝置。
裝置的擁有者可以隨時呼叫 ResetDevice切換至另一個裝置,通常是因為原始裝置遺失。 裝置遺失可能會因為各種原因而發生,包括監視解析、電源管理動作、鎖定和解除鎖定電腦等變更。 如需詳細資訊,請參閱 Direct3D 檔。
ResetDevice方法會使先前開啟的任何裝置控制碼失效。 當裝置控制碼無效時, LockDevice 方法會傳回 DXVA2_E_NEW_VIDEO_DEVICE。 如果發生這種情況,請關閉控制碼並再次呼叫 OpenDeviceHandle 以取得新的裝置控制碼,如下列程式碼所示。
下列範例示範如何開啟裝置控制碼並鎖定裝置。
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;
}
相關主題