Dukungan Overlay Perangkat Keras
Overlay perangkat keras adalah area khusus memori video yang dapat dilapisi pada permukaan utama. Tidak ada salinan yang dilakukan ketika overlay ditampilkan. Operasi overlay dilakukan dalam perangkat keras, tanpa memodifikasi data di permukaan utama.
Penggunaan overlay perangkat keras untuk pemutaran video umum di versi Windows sebelumnya, karena overlay efisien untuk konten video dengan kecepatan bingkai yang tinggi. Mulai dari Windows 7, Direct3D 9 mendukung overlay perangkat keras. Dukungan ini ditujukan terutama untuk pemutaran video, dan berbeda dalam beberapa hal dari API DirectDraw sebelumnya:
- Overlay tidak dapat disusutkan, dicerminkan, atau dipisahkan.
- Kunci warna sumber dan penpaduan alfa tidak didukung.
- Overlay dapat direntangkan jika perangkat keras overlay mendukungnya. Jika tidak, peregangan tidak didukung. Dalam praktiknya, tidak semua driver grafis mendukung peregangan.
- Setiap perangkat mendukung paling banyak satu overlay.
- Overlay dilakukan menggunakan kunci warna tujuan, tetapi runtime Direct3D secara otomatis memilih warna dan menggambar persegi tujuan. Direct3D secara otomatis melacak posisi jendela dan memperbarui posisi overlay setiap kali PresentEx dipanggil.
Membuat Permukaan Overlay Perangkat Keras
Untuk meminta dukungan overlay, panggil IDirect3D9::GetDeviceCaps. Jika driver mendukung overlay perangkat keras, bendera D3DCAPS_OVERLAY diatur di D3DCAPS9. Anggota Caps .
Untuk mengetahui apakah format overlay tertentu didukung untuk mode tampilan tertentu, panggil IDirect3D9ExOverlayExtension::CheckDeviceOverlayType.
Untuk membuat overlay, panggil IDirect3D9Ex::CreateDeviceEx dan tentukan efek pertukaran D3DSWAPEFFECT_OVERLAY . Buffer belakang dapat menggunakan format non-RGB jika perangkat keras mendukungnya.
Permukaan overlay memiliki batasan berikut:
- Aplikasi tidak dapat membuat lebih dari satu rantai pertukaran overlay.
- Overlay harus digunakan dalam mode berjendela. Ini tidak dapat digunakan dalam mode layar penuh.
- Efek pertukaran overlay harus digunakan dengan antarmuka IDirect3DDevice9Ex . Ini tidak didukung untuk IDirect3DDevice9.
- Multisampling tidak dapat digunakan.
- Bendera D3DPRESENT_DONOTFLIP dan D3DPRESENT_FLIPRESTART tidak didukung.
- Statistik presentasi tidak tersedia untuk permukaan overlay.
Jika perangkat keras tidak mendukung peregangan, disarankan untuk membuat rantai pertukaran sebesar mode tampilan, sehingga jendela dapat diubah ukurannya ke dimensi apa pun. Membuat ulang rantai pertukaran bukanlah cara optimal untuk menangani pengubahan ukuran jendela, karena dapat menyebabkan artefak penyajian yang parah. Selain itu, karena cara GPU mengelola memori overlay, membuat ulang rantai pertukaran berpotensi menyebabkan aplikasi kehabisan memori video.
Bendera D3DPRESENT_PARAMETERS Baru
Bendera D3DPRESENT_PARAMETERS berikut didefinisikan untuk membuat overlay.
Bendera | Deskripsi |
---|---|
D3DPRESENTFLAG_OVERLAY_LIMITEDRGB | Rentang RGB adalah 16–235. Defaultnya adalah 0–255. Membutuhkan kemampuan D3DOVERLAYCAPS_LIMITEDRANGERGB . |
D3DPRESENTFLAG_OVERLAY_YCbCr_BT709 | Warna YUV menggunakan definisi BT.709. Defaultnya adalah BT.601. Membutuhkan kemampuan D3DOVERLAYCAPS_YCbCr_BT709 . |
D3DPRESENTFLAG_OVERLAY_YCbCr_xvYCC | Keluarkan data dengan menggunakan YCbCr (xvYCC) yang diperluas. Memerlukan kemampuan D3DOVERLAYCAPS_YCbCr_BT601_xvYCC atau D3DOVERLAYCAPS_YCbCr_BT709_xvYCC . |
Menggunakan Overlay Perangkat Keras
Untuk menampilkan permukaan overlay, aplikasi memanggil IDirect3DDevice9Ex::P resentEx. Runtime Direct3D secara otomatis menggambar kunci warna tujuan.
Bendera PresentEx berikut didefinisikan untuk overlay.
Bendera | Deskripsi |
---|---|
D3DPRESENT_UPDATECOLORKEY | Atur bendera ini jika komposisi Desktop Window Manager (DWM) dinonaktifkan. Bendera ini menyebabkan Direct3D menggambar ulang kunci warna. Jika DWM diaktifkan, bendera ini tidak diperlukan, karena Direct3D menarik kunci warna sekali di permukaan yang digunakan DWM untuk pengalihan. |
D3DPRESENT_HIDEOVERLAY | Menyembunyikan overlay. |
D3DPRESENT_UPDATEOVERLAYONLY | Updates overlay tanpa mengubah konten. Bendera ini berguna jika jendela bergerak saat video dijeda. |
Aplikasi harus disiapkan untuk menangani kasus-kasus berikut:
- Jika aplikasi lain menggunakan overlay, PresentEx mengembalikan D3DERR_NOTAVAILABLE.
- Jika jendela dipindahkan ke monitor lain, aplikasi harus membuat ulang rantai pertukaran. Jika tidak, jika aplikasi memanggil PresentEx untuk menampilkan overlay pada monitor yang berbeda, PresentEx mengembalikan D3DERR_INVALIDDEVICE.
- Jika mode tampilan berubah, Direct3D mencoba memulihkan overlay. Jika mode baru tidak mendukung overlay, PresentEx mengembalikan D3DERR_UNSUPPORTEDOVERLAY.
Contoh Kode
Contoh berikut menunjukkan cara membuat permukaan overlay.
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;
}
Topik terkait