Compatibilidad con superposición de hardware
Una superposición de hardware es un área dedicada de memoria de vídeo que se puede superponer en la superficie principal. No se realiza ninguna copia cuando se muestra la superposición. La operación de superposición se realiza en hardware, sin modificar los datos en la superficie principal.
El uso de superposiciones de hardware para la reproducción de vídeo era común en versiones anteriores de Windows, ya que las superposiciones son eficaces para el contenido de vídeo con una alta velocidad de fotogramas. A partir de Windows 7, Direct3D 9 admite superposiciones de hardware. Esta compatibilidad está pensada principalmente para la reproducción de vídeo y difiere en algunos aspectos de las API anteriores de DirectDraw:
- La superposición no se puede reducir, reflejar ni desinterlazar.
- No se admiten las teclas de color de origen ni la combinación alfa.
- Las superposiciones se pueden ampliar si el hardware de superposición lo admite. De lo contrario, no se admite la extensión. En la práctica, no todos los controladores gráficos admiten la extensión.
- Cada dispositivo admite como máximo una superposición.
- La superposición se realiza mediante una clave de color de destino, pero el tiempo de ejecución de Direct3D selecciona automáticamente el color y dibuja el rectángulo de destino. Direct3D realiza automáticamente un seguimiento de la posición de la ventana y actualiza la posición de superposición cada vez que se llama a PresentEx .
Creación de una superficie de superposición de hardware
Para consultar la compatibilidad con la superposición, llame a IDirect3D9::GetDeviceCaps. Si el controlador admite la superposición de hardware, la marca D3DCAPS_OVERLAY se establece en D3DCAPS9. Miembro Caps .
Para averiguar si se admite un formato de superposición específico para un modo de presentación determinado, llame a IDirect3D9ExOverlayExtension::CheckDeviceOverlayType.
Para crear la superposición, llame a IDirect3D9Ex::CreateDeviceEx y especifique el efecto de intercambio D3DSWAPEFFECT_OVERLAY . El búfer de reserva puede usar un formato no RGB si el hardware lo admite.
Las superficies de superposición tienen las siguientes limitaciones:
- La aplicación no puede crear más de una cadena de intercambio de superposición.
- La superposición debe usarse en modo de ventana. No se puede usar en modo de pantalla completa.
- El efecto de intercambio de superposición debe usarse con la interfaz IDirect3DDevice9Ex . No se admite para IDirect3DDevice9.
- No se puede usar el muestreo múltiple.
- No se admiten las marcas D3DPRESENT_DONOTFLIP y D3DPRESENT_FLIPRESTART .
- Las estadísticas de presentación no están disponibles para la superficie de superposición.
Si el hardware no admite el ajuste, se recomienda crear una cadena de intercambio tan grande como el modo de presentación, de modo que la ventana se pueda cambiar de tamaño a cualquier dimensión. Volver a crear la cadena de intercambio no es una manera óptima de controlar el cambio de tamaño de la ventana, ya que puede provocar artefactos de representación graves. Además, debido a la forma en que la GPU administra la memoria de superposición, volver a crear la cadena de intercambio puede provocar que una aplicación se agote la memoria de vídeo.
Nuevas marcas de D3DPRESENT_PARAMETERS
Se definen las marcas de D3DPRESENT_PARAMETERS siguientes para crear superposiciones.
Marca | Descripción |
---|---|
D3DPRESENTFLAG_OVERLAY_LIMITEDRGB | El rango RGB es de 16 a 235. El valor predeterminado es de 0 a 255. Requiere la funcionalidad D3DOVERLAYCAPS_LIMITEDRANGERGB . |
D3DPRESENTFLAG_OVERLAY_YCbCr_BT709 | Los colores YUV usan la definición BT.709. El valor predeterminado es BT.601. Requiere la funcionalidad D3DOVERLAYCAPS_YCbCr_BT709 . |
D3DPRESENTFLAG_OVERLAY_YCbCr_xvYCC | Genera los datos mediante YCbCr extendido (xvYCC). Requiere la funcionalidad D3DOVERLAYCAPS_YCbCr_BT601_xvYCC o D3DOVERLAYCAPS_YCbCr_BT709_xvYCC . |
Uso de superposiciones de hardware
Para mostrar la superficie de superposición, la aplicación llama a IDirect3DDevice9Ex::P resentEx. El tiempo de ejecución de Direct3D dibuja automáticamente la clave de color de destino.
Las siguientes marcas PresentEx se definen para superposiciones.
Marca | Descripción |
---|---|
D3DPRESENT_UPDATECOLORKEY | Establezca esta marca si la composición del Administrador de ventanas de escritorio (DWM) está deshabilitada. Esta marca hace que Direct3D vuelva a dibujar la clave de color. Si DWM está habilitado, esta marca no es necesaria, porque Direct3D dibuja la clave de color una vez en la superficie que DWM usa para el redireccionamiento. |
D3DPRESENT_HIDEOVERLAY | Oculta la superposición. |
D3DPRESENT_UPDATEOVERLAYONLY | Novedades la superposición sin cambiar el contenido. Esta marca es útil si la ventana se mueve mientras el vídeo está en pausa. |
Una aplicación debe estar preparada para controlar los casos siguientes:
- Si otra aplicación usa la superposición, PresentEx devuelve D3DERR_NOTAVAILABLE.
- Si la ventana se mueve a otro monitor, la aplicación debe volver a crear la cadena de intercambio. De lo contrario, si la aplicación llama a PresentEx para mostrar la superposición en un monitor diferente, PresentEx devuelve D3DERR_INVALIDDEVICE.
- Si el modo de presentación cambia, Direct3D intenta restaurar la superposición. Si el nuevo modo no admite la superposición, PresentEx devuelve D3DERR_UNSUPPORTEDOVERLAY.
Código de ejemplo
En el ejemplo siguiente se muestra cómo crear una superficie de superposición.
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;
}
Temas relacionados