Gestionnaire de périphériques Direct3D

Le gestionnaire d’appareils Microsoft Direct3D permet à deux objets ou plus de partager le même appareil Microsoft Direct3D 9. Un objet agit en tant que propriétaire de l’appareil Direct3D 9. Pour partager l’appareil, le propriétaire de l’appareil crée le gestionnaire de périphériques Direct3D. D’autres objets peuvent obtenir un pointeur vers le gestionnaire de périphériques auprès du propriétaire de l’appareil, puis utiliser le gestionnaire de périphériques pour obtenir un pointeur vers l’appareil Direct3D. Tout objet qui utilise l’appareil contient un verrou exclusif, qui empêche d’autres objets d’utiliser l’appareil en même temps.

Notes

Le Gestionnaire de périphériques Direct3D prend uniquement en charge les appareils Direct3D 9. Il ne prend pas en charge les appareils DXGI.

 

Pour créer le gestionnaire de périphériques Direct3D, appelez DXVA2CreateDirect3DDeviceManager9. Cette fonction retourne un pointeur vers l’interface IDirect3DDeviceManager9 du gestionnaire de périphériques, ainsi qu’un jeton de réinitialisation. Le jeton de réinitialisation permet au propriétaire de l’appareil Direct3D de définir (et réinitialiser) l’appareil sur le gestionnaire d’appareils. Pour initialiser le gestionnaire d’appareils, appelez IDirect3DDeviceManager9::ResetDevice. Passez un pointeur à l’appareil Direct3D, ainsi que le jeton de réinitialisation.

Le code suivant montre comment créer et initialiser le gestionnaire d’appareils.

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

Le propriétaire de l’appareil doit fournir un moyen pour d’autres objets d’obtenir un pointeur vers l’interface IDirect3DDeviceManager9 . Le mécanisme standard consiste à implémenter l’interface IMFGetService . Le GUID de service est MR_VIDEO_ACCELERATION_SERVICE.

Pour partager l’appareil entre plusieurs objets, chaque objet (y compris le propriétaire de l’appareil) doit accéder à l’appareil via le gestionnaire de périphériques, comme suit :

  1. Appelez IDirect3DDeviceManager9::OpenDeviceHandle pour obtenir un handle sur l’appareil.
  2. Pour utiliser l’appareil, appelez IDirect3DDeviceManager9::LockDevice et transmettez le handle d’appareil. La méthode retourne un pointeur vers l’interface IDirect3DDevice9 . La méthode peut être appelée en mode bloquant ou en mode non bloquant, en fonction de la valeur du paramètre fBlock .
  3. Lorsque vous avez terminé d’utiliser l’appareil, appelez IDirect3DDeviceManager9::UnlockDevice. Cette méthode rend l’appareil disponible pour d’autres objets.
  4. Avant de quitter, appelez IDirect3DDeviceManager9::CloseDeviceHandle pour fermer le handle d’appareil.

Vous devez maintenir le verrou de l’appareil uniquement pendant l’utilisation de l’appareil, car le verrouillage de l’appareil empêche d’autres objets d’utiliser l’appareil.

Le propriétaire de l’appareil peut basculer vers un autre appareil à tout moment en appelant ResetDevice, généralement parce que l’appareil d’origine a été perdu. La perte d’appareil peut se produire pour diverses raisons, notamment des modifications dans la résolution du moniteur, des actions de gestion de l’alimentation, le verrouillage et le déverrouillage de l’ordinateur, etc. Pour plus d’informations, consultez la documentation Direct3D.

La méthode ResetDevice invalide tous les handles d’appareil qui ont été ouverts précédemment. Lorsqu’un handle d’appareil n’est pas valide, la méthode LockDevice retourne DXVA2_E_NEW_VIDEO_DEVICE. Si cela se produit, fermez le handle et appelez à nouveau OpenDeviceHandle pour obtenir un nouveau handle d’appareil, comme indiqué dans le code suivant.

L’exemple suivant montre comment ouvrir un handle d’appareil et le verrouiller.

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

Accélération vidéo DirectX 2.0