Prise en charge de la superposition matérielle
Une superposition matérielle est une zone dédiée de mémoire vidéo qui peut être superposée sur la surface primaire. Aucune copie n’est effectuée lorsque la superposition est affichée. L’opération de superposition est effectuée dans le matériel, sans modifier les données dans la surface primaire.
L’utilisation de superpositions matérielles pour la lecture vidéo était courante dans les versions antérieures de Windows, car les superpositions sont efficaces pour le contenu vidéo avec une fréquence d’images élevée. À partir de Windows 7, Direct3D 9 prend en charge les superpositions matérielles. Cette prise en charge est principalement destinée à la lecture vidéo et diffère à certains égards des API DirectDraw antérieures :
- La superposition ne peut pas être réduite, mise en miroir ou désentlacée.
- Les clés de couleur source et le mélange alpha ne sont pas pris en charge.
- Les superpositions peuvent être étirées si le matériel de superposition le prend en charge. Sinon, l’étirement n’est pas pris en charge. Dans la pratique, tous les pilotes graphiques ne prennent pas en charge l’étirement.
- Chaque appareil prend en charge au maximum une superposition.
- La superposition est effectuée à l’aide d’une clé de couleur de destination, mais le runtime Direct3D sélectionne automatiquement la couleur et dessine le rectangle de destination. Direct3D suit automatiquement la position de la fenêtre et met à jour la position de superposition chaque fois que le PresentEx est appelé.
Création d’une surface de superposition matérielle
Pour demander la prise en charge de la superposition, appelez IDirect3D9::GetDeviceCaps. Si le pilote prend en charge la superposition matérielle, l’indicateur D3DCAPS_OVERLAY est défini dans le D3DCAPS9. Membre majuscules .
Pour savoir si un format de superposition spécifique est pris en charge pour un mode d’affichage donné, appelez IDirect3D9ExOverlayExtension::CheckDeviceOverlayType.
Pour créer la superposition, appelez IDirect3D9Ex::CreateDeviceEx et spécifiez l’effet d’échange D3DSWAPEFFECT_OVERLAY . La mémoire tampon arrière peut utiliser un format non RVB si le matériel le prend en charge.
Les surfaces de superposition présentent les limitations suivantes :
- L’application ne peut pas créer plusieurs chaînes d’échange de superposition.
- La superposition doit être utilisée en mode fenêtré. Il ne peut pas être utilisé en mode plein écran.
- L’effet d’échange de superposition doit être utilisé avec l’interface IDirect3DDevice9Ex . Il n’est pas pris en charge pour IDirect3DDevice9.
- Impossible d’utiliser le multi-échantillonnage.
- Les indicateurs D3DPRESENT_DONOTFLIP et D3DPRESENT_FLIPRESTART ne sont pas pris en charge.
- Les statistiques de présentation ne sont pas disponibles pour la surface de superposition.
Si le matériel ne prend pas en charge l’étirement, il est recommandé de créer une chaîne d’échange aussi grande que le mode d’affichage, afin que la fenêtre puisse être redimensionnée dans n’importe quelle dimension. La recréation de la chaîne d’échange n’est pas un moyen optimal de gérer le redimensionnement de la fenêtre, car cela peut entraîner des artefacts de rendu graves. En outre, en raison de la façon dont le GPU gère la mémoire de superposition, la recréation de la chaîne d’échange peut potentiellement entraîner une utilisation insuffisante de la mémoire vidéo d’une application.
Nouveaux indicateurs D3DPRESENT_PARAMETERS
Les indicateurs de D3DPRESENT_PARAMETERS suivants sont définis pour la création de superpositions.
Indicateur | Description |
---|---|
D3DPRESENTFLAG_OVERLAY_LIMITEDRGB | La plage RVB est comprise entre 16 et 235. La valeur par défaut est de 0 à 255. Nécessite la fonctionnalité D3DOVERLAYCAPS_LIMITEDRANGERGB . |
D3DPRESENTFLAG_OVERLAY_YCbCr_BT709 | Les couleurs YUV utilisent la définition BT.709. La valeur par défaut est BT.601. Nécessite la fonctionnalité D3DOVERLAYCAPS_YCbCr_BT709 . |
D3DPRESENTFLAG_OVERLAY_YCbCr_xvYCC | Extrayez les données à l’aide de l’extension YCbCr (xvYCC). Nécessite la fonctionnalité D3DOVERLAYCAPS_YCbCr_BT601_xvYCC ou D3DOVERLAYCAPS_YCbCr_BT709_xvYCC . |
Utilisation de superpositions matérielles
Pour afficher la surface de superposition, l’application appelle IDirect3DDevice9Ex::P resentEx. Le runtime Direct3D dessine automatiquement la clé de couleur de destination.
Les indicateurs PresentEx suivants sont définis pour les superpositions.
Indicateur | Description |
---|---|
D3DPRESENT_UPDATECOLORKEY | Définissez cet indicateur si la composition du Gestionnaire de fenêtres de bureau (DWM) est désactivée. Cet indicateur permet à Direct3D de redessiner la touche de couleur. Si DWM est activé, cet indicateur n’est pas obligatoire, car Direct3D dessine une fois la touche de couleur sur la surface que DWM utilise pour la redirection. |
D3DPRESENT_HIDEOVERLAY | Masque la superposition. |
D3DPRESENT_UPDATEOVERLAYONLY | Mises à jour la superposition sans modifier le contenu. Cet indicateur est utile si la fenêtre se déplace pendant que la vidéo est suspendue. |
Une application doit être préparée pour gérer les cas suivants :
- Si une autre application utilise la superposition, PresentEx retourne D3DERR_NOTAVAILABLE.
- Si la fenêtre est déplacée vers un autre moniteur, l’application doit recréer la chaîne d’échange. Sinon, si l’application appelle PresentEx pour afficher la superposition sur un autre moniteur, PresentEx retourne D3DERR_INVALIDDEVICE.
- Si le mode d’affichage change, Direct3D tente de restaurer la superposition. Si le nouveau mode ne prend pas en charge la superposition, PresentEx retourne D3DERR_UNSUPPORTEDOVERLAY.
Exemple de code
L’exemple suivant montre comment créer une surface de superposition.
const UINT VIDEO_WIDTH = 256;
const UINT VIDEO_HEIGHT = 256;
HRESULT CreateHWOverlay(
HWND hwnd,
IDirect3D9Ex *pD3D,
IDirect3DDevice9Ex **ppDevice
)
{
*ppDevice = NULL;
D3DCAPS9 caps;
ZeroMemory(&caps, sizeof(caps));
HRESULT hr = pD3D->GetDeviceCaps(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
&caps
);
if (FAILED(hr))
{
return hr;
}
// Check if overlay is supported.
if (!(caps.Caps & D3DCAPS_OVERLAY))
{
return D3DERR_UNSUPPORTEDOVERLAY;
}
D3DOVERLAYCAPS overlayCaps = { 0 };
IDirect3DDevice9Ex *pDevice = NULL;
IDirect3D9ExOverlayExtension *pOverlay = NULL;
// Check specific overlay capabilities.
hr = pD3D->QueryInterface(IID_PPV_ARGS(&pOverlay));
if (SUCCEEDED(hr))
{
hr = pOverlay->CheckDeviceOverlayType(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
VIDEO_WIDTH,
VIDEO_HEIGHT,
D3DFMT_X8R8G8B8,
NULL,
D3DDISPLAYROTATION_IDENTITY,
&overlayCaps
);
}
// Create the overlay.
if (SUCCEEDED(hr))
{
DWORD flags = D3DCREATE_FPU_PRESERVE |
D3DCREATE_MULTITHREADED |
D3DCREATE_SOFTWARE_VERTEXPROCESSING;
D3DPRESENT_PARAMETERS pp = { 0 };
pp.BackBufferWidth = overlayCaps.MaxOverlayDisplayWidth;
pp.BackBufferHeight = overlayCaps.MaxOverlayDisplayHeight;
pp.BackBufferFormat = D3DFMT_X8R8G8B8;
pp.SwapEffect = D3DSWAPEFFECT_OVERLAY;
pp.hDeviceWindow = hwnd;
pp.Windowed = TRUE;
pp.Flags = D3DPRESENTFLAG_VIDEO;
pp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
hr = pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
NULL, flags, &pp, NULL, &pDevice);
}
if (SUCCEEDED(hr))
{
(*ppDevice) = pDevice;
(*ppDevice)->AddRef();
}
SafeRelease(&pD3D);
SafeRelease(&pDevice);
SafeRelease(&pOverlay);
return hr;
}
Rubriques connexes