Supporto sovrimpressione hardware
Una sovrapposizione hardware è un'area dedicata di memoria video che può essere sovrapposta sulla superficie primaria. Nessuna copia viene eseguita quando viene visualizzata la sovrapposizione. L'operazione di sovrapposizione viene eseguita nell'hardware, senza modificare i dati nella superficie primaria.
L'uso delle sovrimpressione hardware per la riproduzione video è comune nelle versioni precedenti di Windows, perché le sovrapposizioni sono efficienti per il contenuto video con una frequenza di fotogrammi elevata. A partire da Windows 7, Direct3D 9 supporta sovrimpressione hardware. Questo supporto è destinato principalmente alla riproduzione video e differisce in alcuni aspetti dalle API DirectDraw precedenti:
- La sovrapposizione non può essere ridotto, mirroring o deinterlaced.
- Le chiavi di colore di origine e la fusione alfa non sono supportate.
- Le sovrimpressione possono essere estese se l'hardware sovrimpressione lo supporta. In caso contrario, l'estensione non è supportata. In pratica, non tutti i driver grafici supportano l'estensione.
- Ogni dispositivo supporta al massimo una sovrapposizione.
- La sovrapposizione viene eseguita usando una chiave di colore di destinazione, ma il runtime Direct3D seleziona automaticamente il colore e disegna il rettangolo di destinazione. Direct3D tiene automaticamente traccia della posizione della finestra e aggiorna la posizione di sovrapposizione ogni volta che viene chiamato PresentEx .
Creazione di una superficie di sovrapposizione hardware
Per eseguire query sul supporto di sovrimpressione, chiamare IDirect3D9::GetDeviceCaps. Se il driver supporta la sovrapposizione hardware, il flag di D3DCAPS_OVERLAY è impostato in D3DCAPS9. Membro caps .
Per scoprire se un formato di sovrapposizione specifico è supportato per una determinata modalità di visualizzazione, chiamare IDirect3D9ExOverlayExtension::CheckDeviceOverlayType.
Per creare la sovrapposizione, chiamare IDirect3D9Ex::CreateDeviceEx e specificare l'effetto di scambio D3DSWAPEFFECT_OVERLAY . Il buffer indietro può usare un formato non RGB se l'hardware lo supporta.
Le superfici di sovrapposizione presentano le limitazioni seguenti:
- L'applicazione non può creare più di una catena di scambio di sovrapposizioni.
- La sovrapposizione deve essere usata in modalità finestrata. Non può essere usato in modalità schermo intero.
- L'effetto di scambio sovrapposizione deve essere usato con l'interfaccia IDirect3DDevice9Ex . Non è supportato per IDirect3DDevice9.
- Non è possibile usare multicampionamento.
- I flag D3DPRESENT_DONOTFLIP e D3DPRESENT_FLIPRESTART non sono supportati.
- Le statistiche di presentazione non sono disponibili per la superficie di sovrapposizione.
Se l'hardware non supporta l'estensione, è consigliabile creare una catena di scambio grande come la modalità di visualizzazione, in modo che la finestra possa essere ridimensionata in qualsiasi dimensione. La ricreazione della catena di scambio non è un modo ottimale per gestire il ridimensionamento della finestra, perché può causare artefatti di rendering gravi. Inoltre, a causa del modo in cui la GPU gestisce la memoria di sovrapposizione, la ricreazione della catena di scambio può potenzialmente causare l'esecuzione di un'applicazione in memoria video.
Nuovi flag di D3DPRESENT_PARAMETERS
I flag di D3DPRESENT_PARAMETERS seguenti sono definiti per la creazione di sovrimpressione.
Flag | Descrizione |
---|---|
D3DPRESENTFLAG_OVERLAY_LIMITEDRGB | L'intervallo RGB è 16-235. Il valore predefinito è 0-255. Richiede la funzionalità di D3DOVERLAYCAPS_LIMITEDRANGERGB . |
D3DPRESENTFLAG_OVERLAY_YCbCr_BT709 | I colori YUV usano la definizione BT.709. Il valore predefinito è BT.601. Richiede la funzionalità di D3DOVERLAYCAPS_YCbCr_BT709 . |
D3DPRESENTFLAG_OVERLAY_YCbCr_xvYCC | Restituisce i dati usando YCbCr (xvYCC). Richiede la funzionalità D3DOVERLAYCAPS_YCbCr_BT601_xvYCC o D3DOVERLAYCAPS_YCbCr_BT709_xvYCC . |
Uso di sovrimpressione hardware
Per visualizzare l'area di sovrapposizione, l'applicazione chiama IDirect3DDevice9Ex::P resentEx. Il runtime Direct3D disegna automaticamente la chiave di colore di destinazione.
I flag PresentEx seguenti sono definiti per le sovrimpressione.
Flag | Descrizione |
---|---|
D3DPRESENT_UPDATECOLORKEY | Impostare questo flag se la composizione di Desktop Window Manager (DWM) è disabilitata. Questo flag causa il ridisegno della chiave di colore direct3D. Se DWM è abilitato, questo flag non è obbligatorio, perché Direct3D disegna la chiave di colore una volta sulla superficie utilizzata da DWM per il reindirizzamento. |
D3DPRESENT_HIDEOVERLAY | Nasconde la sovrapposizione. |
D3DPRESENT_UPDATEOVERLAYONLY | Aggiornamenti la sovrapposizione senza modificare il contenuto. Questo flag è utile se la finestra si sposta mentre il video viene sospeso. |
Un'applicazione deve essere preparata per gestire i casi seguenti:
- Se un'altra applicazione usa la sovrapposizione, PresentEx restituisce D3DERR_NOTAVAILABLE.
- Se la finestra viene spostata in un altro monitoraggio, l'applicazione deve ricreare la catena di scambio. In caso contrario, se l'applicazione chiama PresentEx per visualizzare la sovrapposizione in un monitor diverso, PresentEx restituisce D3DERR_INVALIDDEVICE.
- Se la modalità di visualizzazione cambia, Direct3D tenta di ripristinare la sovrapposizione. Se la nuova modalità non supporta la sovrapposizione, PresentEx restituisce D3DERR_UNSUPPORTEDOVERLAY.
Codice di esempio
Nell'esempio seguente viene illustrato come creare una superficie di sovrapposizione.
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;
}
Argomenti correlati