硬體重迭支援
硬體重迭是可在主要介面上重迭的專用視訊記憶體區域。 顯示重迭時不會執行任何複本。 重迭作業會在硬體中執行,而不需修改主要介面中的資料。
在舊版 Windows 中,對於視訊播放使用硬體重迭很常見,因為重迭對於高畫面播放速率的視訊內容有效率。 從 Windows 7 開始,Direct3D 9 支援硬體重迭。 此支援主要是用於視訊播放,而且在某些方面與先前的 DirectDraw API 不同:
- 重迭無法壓縮、鏡像或取消交錯。
- 不支援來源色彩索引鍵和 Alpha 混合。
- 如果重迭硬體支援重迭,可以延展重迭。 否則,不支援延展。 實際上,並非所有圖形驅動程式都支援延展。
- 每個裝置最多支援一個重迭。
- 重迭是使用目的地色彩索引鍵來執行,但 Direct3D 執行時間會自動選取色彩並繪製目的地矩形。 Direct3D 會在呼叫 PresentEx 時自動追蹤視窗的位置,並更新重迭位置。
建立硬體重迭介面
若要查詢重迭支援,請呼叫 IDirect3D9::GetDeviceCaps。 如果驅動程式支援硬體重迭, 則會 在 D3DCAPS9 中設定D3DCAPS_OVERLAY旗標。Caps 成員。
若要瞭解特定顯示模式是否支援特定的重迭格式,請呼叫 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;
}
相關主題