硬體重疊支援
硬體重疊是可在主要介面上重疊的專用視訊記憶體區域。 顯示重迭時,不會執行任何複製。 重迭作業會在硬體中執行,而不需修改主要介面中的數據。
在舊版 Windows 中,使用硬體重疊來播放視訊很常見,因為重疊對高幀速率的視訊內容有效率。 從 Windows 7 開始,Direct3D 9 支援硬體重疊。 這項支援主要適用於視訊播放,在某些方面與先前的 DirectDraw API 不同:
- 重疊無法壓縮、鏡像或反交錯。
- 不支援來源色彩索引鍵和Alpha混合。
- 如果重疊硬體支援重疊,則可以延展重疊。 否則,不支援延展。 實際上,並非所有圖形驅動程式都支援延展。
- 每個裝置最多都支援一個重疊。
- 重疊是使用目的地色彩索引鍵來執行,但 Direct3D 運行時間會自動選取色彩並繪製目的地矩形。 每當呼叫 PresentEx 時,Direct3D 會自動追蹤視窗的位置,並更新重疊位置。
建立硬體重疊介面
若要查詢覆迭支援,請呼叫 IDirect3D9::GetDeviceCaps。 如果驅動程式支持硬體重疊,則會在 D3DCAPS9 中設定 D3DCAPS_OVERLAY 旗標。 成員的上限。
若要瞭解特定顯示模式是否支援特定的重疊格式,請呼叫 IDirect3D9ExOverlayExtension::CheckDeviceOverlayType。
若要建立重疊,請呼叫 IDirect3D9Ex::CreateDeviceEx 並指定 D3DSWAPEFFECT_OVERLAY 交換效果。 如果硬體支援,後端緩衝區可以使用非 RGB 格式。
重疊表面有下列限制:
- 應用程式無法建立多個重疊交換鏈結。
- 重疊必須在視窗模式中使用。 無法在全螢幕模式中使用。
- 重疊交換效果必須與 IDirect3DDevice9Ex 介面搭配使用。 IDirect3DDevice9不支援。
- 無法使用多重取樣。
- 不支援 D3DPRESENT_DONOTFLIP 和 D3DPRESENT_FLIPRESTART 旗標。
- 重疊介面無法使用簡報統計數據。
如果硬體不支援延展,建議建立與顯示模式一樣大的交換鏈結,讓視窗大小調整為任何維度。 重新建立交換鏈結並不是處理調整視窗大小的最佳方法,因為它可能會導致嚴重的轉譯成品。 此外,由於 GPU 管理重迭記憶體的方式,重新建立交換鏈結可能會導致應用程式用盡視訊記憶體。
新的D3DPRESENT_PARAMETERS旗標
定義下列 D3DPRESENT_PARAMETERS 旗標來建立重疊。
旗 | 描述 |
---|---|
D3DPRESENTFLAG_OVERLAY_LIMITEDRGB | RGB 範圍是 16–235。 默認值為 0–255。 需要 D3DOVERLAYCAPS_LIMITEDRANGERGB 功能。 |
D3DPRESENTFLAG_OVERLAY_YCbCr_BT709 | YUV 色彩使用 BT.709 定義。 預設值為 BT.601。 需要 D3DOVERLAYCAPS_YCbCr_BT709 功能。 |
D3DPRESENTFLAG_OVERLAY_YCbCr_xvYCC | 使用擴充的 YCbCr (xvYCC) 輸出數據。 需要 D3DOVERLAYCAPS_YCbCr_BT601_xvYCC 或 D3DOVERLAYCAPS_YCbCr_BT709_xvYCC 功能。 |
使用硬體重疊
若要顯示重疊介面,應用程式會呼叫 IDirect3DDevice9Ex::P resentEx。 Direct3D 執行時間會自動繪製目的地色彩索引鍵。
下列 PresentEx 旗標會針對重迭定義。
旗 | 描述 |
---|---|
D3DPRESENT_UPDATECOLORKEY | 如果已停用桌面視窗管理員 (DWM) 組合,請設定此旗標。 此旗標會導致 Direct3D 重新繪製色彩索引鍵。 如果已啟用 DWM,則不需要此旗標,因為 Direct3D 會在 DWM 用於重新導向的介面上繪製色彩索引鍵一次。 |
D3DPRESENT_HIDEOVERLAY | 隱藏重疊。 |
D3DPRESENT_UPDATEOVERLAYONLY | 更新重疊而不變更內容。 如果暫停視訊時視窗移動,這個旗標就很有用。 |
應用程式應該準備好處理下列情況:
- 如果另一個應用程式使用重疊,PresentEx 會傳回 D3DERR_NOTAVAILABLE。
- 如果視窗移至另一個監視器,應用程式必須重新建立交換鏈結。 否則,如果應用程式呼叫 PresentEx 以顯示不同監視器上的重疊,PresentEx 會傳回 D3DERR_INVALIDDEVICE。
- 如果顯示模式變更,Direct3D 會嘗試還原重疊。 如果新模式不支援重疊,PresentEx 會傳回 D3DERR_UNSUPPORTEDOVERLAY。
範例程序代碼
下列範例示範如何建立重疊表面。
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;
}
相關主題