Membangun aplikasi komposit kustom untuk monitor yang dipasang di kepala dan khusus
Windows.Devices.Display.Core API adalah API Windows Runtime (WinRT) tingkat rendah untuk kompositor pihak ketiga dan komponen Windows internal yang berada di bawah semua API publik lainnya untuk menghitung, mengonfigurasi, dan mendorong adaptor tampilan dan menampilkan target di Windows. Idenya adalah memperlakukan pengontrol tampilan sebagai mesin terpisah, dianalogikan dengan mesin 3D dan mesin media pada GPU. API ini bertanggung jawab untuk:
- Menjawab kueri tentang perangkat keras tampilan (seperti kemampuan dan kemungkinan mode tampilan)
- Menjawab kueri tentang konfigurasi saat ini
- Menyetel properti pada perangkat keras tampilan (seperti mode tampilan)
- Mengonfigurasi perangkat keras tampilan (resolusi monitor yang terhubung, format kawatnya, dll)
- Mengalokasikan dan memindai permukaan GPU khusus yang dikenal sebagai utama
- Mengizinkan interop antara Direct3D dan WINDOWS.Devices.Display.Core API (misalnya berbagi permukaan, pagar)
Perlu dipanggil apa yang bukan Windows.Devices.Display.Core:
- Ini bukan API yang digunakan oleh game atau aplikasi untuk menampilkan konten di jendela. Aplikasi masih menggunakan DXGI, XAML, API komposisi, GDI, dll.
- Ini bukan API yang digunakan oleh game atau aplikasi untuk menampilkan layar penuh konten. Aplikasi masih menggunakan aplikasi DXGI, Win32 masih menggunakan HWND, dan aplikasi UWP selalu menampilkan konten di CoreWindow.
API ini hanya untuk aplikasi komposit yang mendorong perangkat keras khusus.
Skenario untuk membangun kompositor kustom
API Windows.Devices.Display.Core sesuai untuk digunakan dalam skenario berikut:
- Tampilan realitas virtual dan tertambah yang memerlukan komposittor kepemilikan untuk langsung mendorong pengontrol tampilan dan menerima kontrol terperinci atas pengaturan waktu dan konfigurasi mode yang terpisah dari desktop Windows.
- Skenario perangkat keras tampilan khusus yang memerlukan kontrol khusus atas tampilan dalam pengaturan komersial. Misalnya, dalam kasus di mana desktop Windows tidak dapat merender dengan benar pada tampilan seperti itu karena warping perangkat keras, tampilan skala abu-abu, dll.
- Skenario "appliance" khusus di mana monitor dapat sepenuhnya didedikasikan untuk aplikasi tanpa gangguan dari pengalaman desktop Windows selama jangka waktu yang lama (misalnya monitor video khusus).
API menyelesaikan ini dengan:
- Memberikan kontrol terperinci atas informasi mode tampilan lengkap, termasuk format kawat, HDR, dll.
- Menggunakan pagar untuk menyinkronkan presentasi memungkinkan komposit untuk merantai presentasi di seluruh proses atau sub-komponen dengan overhead performa hampir nol.
- Meningkatkan kemampuan untuk mengkueri dan mengonfigurasi Video Present Network (VidPN) yang mendasar untuk memungkinkan komponen sistem dan komponen komposisi tingkat rendah untuk melakukan operasi yang lebih kompleks dengan cara yang kurang rawan kesalahan dan lebih dapat diperluas.
Perhatikan bahwa API ini hanya untuk serangkaian kasus penggunaan pihak ketiga yang sangat spesifik dengan perangkat keras khusus. Penggunaannya sangat dibatasi untuk perangkat keras yang menyatakan dirinya membutuhkan fungsionalitas API ini. Oleh karena itu, tingkat keakraban tertentu dengan konsep perangkat keras diharapkan dari pengembang, dan mitra harus menghubungi Microsoft secara langsung untuk membantu masalah.
Persyaratan perangkat keras dan perangkat lunak
Kompositor kustom pihak ketiga hanya dapat memperoleh tampilan yang telah ditetapkan sebelumnya sebagai tampilan yang dipasang di kepala (HMD) atau tampilan "khusus". Penetapan ini harus disediakan dengan salah satu dari dua cara:
- Ekstensi EDID - Perangkat tampilan kustom yang dirancang untuk penggunaan permanen sebagai HMD, monitor sinar X, dinding video, atau skenario khusus lainnya harus menerapkan ekstensi Microsoft EDID untuk tampilan yang dipasang di kepala dan khusus.
- Penggantian Pengguna - Untuk penginstalan perangkat keras kustom menggunakan monitor off-the-shelf, Windows menyediakan tombol UI untuk menunjuk monitor sebagai "khusus".
Tampilan mungkin tidak ditetapkan sebagai HMD atau tampilan khusus dengan menimpa EDID dalam perangkat lunak.
Catatan
Tampilan khusus hanya tersedia mulai windows 10, versi 2004, dan memerlukan Windows 10 Enterprise, Windows 10 Pro untuk Workstations, atau Windows 10 IoT Enterprise.
Peta strategi untuk menerapkan komposit kustom
Menerapkan komposit kustom dapat dipecah menjadi beberapa tahap:
- Menghitung dan menemukan HMD terkait atau tampilan khusus
- Memperoleh kepemilikan tampilan terpilih
- Mengonfigurasi mode untuk semua tampilan terpilih
- Membuat sumber daya untuk menyajikan bingkai ke tampilan
- Merender konten dan menjadwalkan presentasi bingkai
Perbandingan API terkait tampilan
API | Audiens Tujuan dan Target |
---|---|
DisplayInformation | Digunakan untuk mengambil properti penyajian dan tata letak untuk CoreWindow. |
HdmiDisplayInformation | API khusus Xbox untuk menghitung dan mengatur serangkaian mode yang dibatasi. Sangat khusus untuk skenario aplikasi media Xbox. |
DisplayMonitor | Digunakan untuk mengkueri properti perangkat monitor fisik. Tidak mengekspos informasi runtime apa pun tentang bagaimana monitor dikonfigurasi atau saat ini digunakan oleh OS. |
EnumDisplayDevices, EnumDisplayMonitors, EnumDisplaySettingsEx | API Win32 warisan untuk mengkueri HMONITOR, perangkat GDI, dan pemetaan monitor fisik. Informasi yang dikembalikan di sini sangat virtual dan dikelola untuk kompatibilitas aplikasi. |
Direct3D | Digunakan untuk merender konten piksel ke permukaan GPU dan melakukan komputasi pada GPU. |
Rantai Pertukaran DXGI | Digunakan untuk presentasi layar penuh berjendela berjendela dan tanpa batas. Konten rantai pertukaran aplikasi mengalir melalui komposittor sistem, DWM. |
Enumerasi Output DXGI | Menyediakan pembungkus DXGI di sekitar HMONITOR. |
QueryDisplayConfig, SetDisplayConfig, DisplayConfigGetDeviceInfo, DisplayConfigSetDeviceInfo | API Win32 untuk mengonfigurasi topologi tampilan. Tidak menyediakan mekanisme untuk menghitung beberapa mode, tetapi memiliki serangkaian informasi yang kaya tentang konfigurasi dan pengaturan saat ini. Namun, tidak semua properti mode yang lebih baru diekspos oleh API ini. |
Windows.Devices.Display.Core (dokumen ini) | Digunakan untuk menghitung target, menghitung mode, mengonfigurasi mode, mengalokasikan permukaan GPU untuk presentasi, dan menyajikan konten untuk ditampilkan. |
Gambaran umum konfigurasi tampilan
Enumerasi perangkat keras fisik
WINDOWS.Devices.Display.Core API memiliki berbagai objek untuk mewakili objek perangkat keras fisik. DisplayAdapter biasanya (tetapi tidak selalu) perangkat keras fisik, seperti GPU yang terhubung dengan PCI Express atau GPU terintegrasi pada CPU. Objek DisplayTarget mewakili konektor fisik (misalnya HDMI, VGA, DisplayPort, dll.) yang dapat disambungkan dari GPU. Ini mungkin termasuk koneksi internal yang tidak terlihat pengguna untuk perangkat dengan monitor internal (laptop, tablet, dll.). Mungkin ada lebih banyak objek DisplayTarget yang diwakili dalam perangkat lunak daripada yang dapat disambungkan secara fisik oleh pengguna pada satu waktu. Misalnya, karena standar koneksi DisplayPort memungkinkan penautan daisy, driver GPU biasanya menghitung beberapa target DisplayPort per port fisik untuk memperhitungkan monitor berantai.
Objek untuk mode pengaturan
Untuk menghitung objek DisplayTarget, mengatur dan mengkueri mode, dll. koneksi ke objek DisplayTarget diwakili dengan objek DisplayPath. Grup jalur yang menampilkan konten yang sama (grup kloning) diwakili oleh DisplayView, dan ini dikumpulkan ke dalam DisplayState. Oleh karena itu, satu objek DisplayState dapat mewakili serangkaian status mode lengkap yang dapat dikirim ke driver untuk beberapa monitor.
Status atom untuk konfigurasi mode dan enumerasi
WINDOWS.Devices.Display.Core API dirancang untuk memastikan bahwa kompositor dapat memperoleh akses ke berbagai status tampilan sistem secara atomik, dan dengan perilaku keusangan yang terdefinisi dengan baik. Ini penting karena GPU adalah sumber daya bersama, dengan bandwidth dan batasan daya yang sangat ketat. Dalam sistem modern, perangkat dapat tiba/berangkat kapan saja dan hal-hal lain dapat memengaruhi daftar mode tampilan yang tersedia (misalnya docking/undocking, status tidur, mode perubahan komponen lain di jalur lain). Oleh karena itu, penting bagi kompositor untuk tahan terhadap perubahan pada konfigurasi sistem dengan menggunakan WINDOWS.Devices.Display.Core API dan mengikuti pola yang direkomendasikan untuk mengonfigurasi status.
Oleh karena itu, Api Windows.Devices.Display.Core menyediakan model penerapan baca-modifikasi transaksional sederhana, mirip dengan database. Klien dapat membaca objek DisplayState secara atomik untuk perangkat tampilan dalam sistem. Semua objek tidak dapat diubah atau menyediakan API yang ditentukan dengan baik untuk memperbarui/menerapkan status kembali ke sistem. Perubahan tidak dilakukan sampai DisplayState.TryApply dipanggil, yang "menerapkan" perubahan pada sistem. Menerapkan/menerapkan perubahan pada DisplayState gagal tanpa dampak atau berhasil dengan perubahan penuh yang diterapkan.
Untuk memanfaatkan fitur atomitas API:
- Tulis logika konfigurasi mode apa pun dalam perulangan coba lagi.
- Buat DisplayState baru di awal konfigurasi mode, di dalam setiap perulangan.
- Gunakan bendera FailIfStateChanged saat memanggil DisplayState.TryApply untuk mendeteksi bahwa status sistem tidak lagi sama seperti saat DisplayState dibuat. Ini memungkinkan Anda kesempatan untuk mencoba kembali operasi. Jika operasi gagal dengan SystemStateChanged, coba lagi seluruh perulangan.
- Jangan mencampur API lain (DXGI, GDI, dll.) yang membaca atau mengubah status dengan penggunaan API Windows.Devices.Display.Core, karena mungkin tidak memiliki jaminan atomitas yang sama.
#include <winrt\Windows.Devices.Display.Core.h>
using namespace winrt::Windows::Devices::Display::Core;
...
// Create a DisplayManager
DisplayManager manager = DisplayManager::Create(DisplayManagerOptions::EnforceSourceOwnership);
// Loop around trying to acquire a target and set a mode
bool shouldRetry;
do
{
shouldRetry = false;
// ... Find the target that you want to use
auto targets = manager.GetCurrentTargets();
DisplayTarget selectedTarget = ...;
auto stateCreationResult = manager.TryAcquireTargetsAndCreateEmptyState(
winrt::single_threaded_vector<DisplayTarget>({ selectedTarget }));
if (stateCreationResult.ErrorCode() != DisplayManagerResult::Success)
{
winrt::check_hresult(stateCreationResult.ExtendedErrorCode());
}
auto state = stateCreationResult.State();
DisplayPath newPath = state.ConnectTarget(selectedTarget);
// ... Configure the path
auto applyResult = state.TryApply(DisplayStateApplyOptions::FailIfStateChanged);
if (applyResult.Status() == DisplayStateOperationStatus::SystemStateChanged)
{
shouldRetry = true;
}
else if (applyResult.Status() != DisplayStateOperationStatus::Success)
{
winrt::check_hresult(applyResult.ExtendedErrorCode());
}
} while (shouldRetry);
API berikut membaca status secara atomik dari sistem:
- DisplayManager
- DisplayState
- DisplayPath
- DisplayTarget
Status penerapan API berikut kembali ke sistem:
- DisplayManager
- TryAcquireTarget/ReleaseTarget (dan memperoleh target dengan
TryAcquireTargetsAnd*
metode) Memperoleh kepemilikan DisplayTargets dari sistem.
- TryAcquireTarget/ReleaseTarget (dan memperoleh target dengan
- DisplayState
- TryApply Memperbarui status tampilan sistem saat ini dengan mengatur atau menghapus mode pada semua target yang dimiliki dalam sistem, melalui driver tampilan.
Pembatasan yang diketahui
WINDOWS.Devices.Display.Core API memiliki beberapa batasan yang diketahui (pada Windows 10, versi 2004):
- Driver tampilan tidak langsung (misalnya Miracast, adaptor tampilan USB, driver perangkat lunak) saat ini tidak dapat diatasi. DisplayManager.CreateDisplayDevice akan gagal ketika melewati adaptor tampilan tidak langsung.
Kode Sampel
Untuk aplikasi sampel, lihat sampel komposittor kustom Windows.Devices.Display.Core.