共用方式為


建置適用於前端裝載和特製化監視器的自定義撰寫器應用程式

Windows.Devices.Display.Core API 是適用於第三方組合器及內部 Windows 元件的低階 Windows 執行階段 (WinRT) API,其位於所有其他公用 API 下方,用於列舉、設定及驅動 Windows 中的顯示適配卡和顯示目標。 其概念是將顯示控制器視為個別的引擎,類似於 GPU 上的 3D 引擎和媒體引擎。 此 API 負責:

  • 回答有關顯示硬體的查詢(例如功能和可能的顯示模式)
  • 回答有關目前組態的查詢
  • 顯示硬體設定屬性(例如顯示模式)
  • 設定顯示硬體(連線監視器的解析度、其電線格式等)
  • 配置和掃描稱為主要的特殊 GPU 表面
  • 允許 Direct3D 與 Windows.Devices.Display.Core API 之間的互操作性(例如共用介面、柵欄)

值得一提的是,Windows.Devices.Display.Core 不是

  • 它不是遊戲或應用程式用來在視窗中顯示內容的 API。 應用程式仍然使用 DXGIXAML組合 APIGDI 等。
  • 它不是遊戲或應用程式用來顯示內容全螢幕的 API。 應用程式仍然使用 DXGI、Win32 應用程式仍然使用 HWND,而 UWP 應用程式一律會在 CoreWindow 中顯示內容。

此 API 僅適用於驅動特殊硬體的撰寫器應用程式。

顯示用於特製化顯示之 API 架構層的圖表。

建置自定義撰寫器案例

Windows.Devices.Display.Core API 適用於下列案例:

  • 虛擬和擴增實境顯示器,需要專屬的撰寫器來直接驅動顯示控制器,並接收與 Windows 桌面分開的計時和模式設定的精細控制。
  • 需要對商業設定中顯示器進行專用控制的特殊顯示硬體案例。 例如,在 Windows 桌面無法正確轉譯這類顯示器時,因為硬體變形、灰階顯示器等。
  • 特殊化的「應用裝置」案例,其中監視器可能完全專用於應用程式,而不會長時間受到 Windows 桌面體驗的任何干擾(例如專用視訊監視器)。

API 會透過下列方式來完成此作業:

  • 提供完整顯示模式資訊的精細控制,包括有線格式、HDR 等。
  • 使用柵欄同步處理簡報,可讓撰寫器將簡報鏈結至進程或子元件,且效能負擔幾乎為零。
  • 改善查詢和設定基礎影片簡報網路 (VidPN) 的能力,讓系統元件和低階組合元件能夠以較不容易出錯且更具擴充性的方式執行更複雜的作業。

請注意,此 API 僅適用於具有特殊硬體的一 非常特定的第三方使用案例。 其使用高度受限於宣告自己需要此 API 功能的硬體。 因此,開發人員應該對硬體概念有某種程度的熟悉程度,合作夥伴應該直接與Microsoft連絡,以協助解決問題。

硬體和軟體需求

第三方自定義組合器只能取得已預先指定為前端顯示器(HMD)或「特製化」顯示器的顯示器。 此指定必須以下列兩種方式之一提供:

  • EDID 擴充功能 - 專為永久使用作為 HMD、X 光監視器、視訊牆或其他特殊案例而設計的自定義顯示裝置,應實 作用於前端掛接和特製化顯示器的 Microsoft EDID 擴充功能。
  • 使用者覆寫 - 針對使用現成監視器的自定義硬體安裝,Windows 會提供 UI 切換,以將監視器指定為「特製化」。

在軟體中覆寫 EDID,可能不會將顯示器指定為 HMD 或特製化顯示器。

注意

特製化顯示器僅適用於 Windows 10 版本 2004,且需要工作站或 Windows 10 IoT 企業版 Windows 10 企業版、Windows 10 專業版。

實作自定義撰寫器藍圖

實作自定義撰寫器可以分成數個階段:

  • 列舉和探索相關聯的 HMD 或特製化顯示
  • 取得所選取顯示器的擁有權
  • 設定所有選取顯示器的模式
  • 建立資源以將畫面呈現至顯示器
  • 轉譯內容和排程畫面簡報
API 目的和目標物件
DisplayInformation 用來擷取 CoreWindow 的轉譯和版面配置屬性。
HdmiDisplayInformation 適用於列舉和設定一組受限模式的 Xbox 專用 API。 針對 Xbox 媒體應用程式案例高度特製化。
DisplayMonitor 用於查詢實體監視器裝置的屬性。 不會公開操作系統如何設定或目前使用監視的任何運行時間資訊。
EnumDisplayDevicesEnumDisplayMonitorsEnumDisplaySettingsEx 用於查詢 HMONITORs、GDI 裝置和實體監視器對應的舊版 Win32 API。 此處傳回的資訊會高度虛擬化並維護應用程式相容性。
Direct3D 用於將圖元內容轉譯成 GPU 介面,並在 GPU 上執行計算。
DXGI 交換鏈結 用於視窗化和無框視窗全螢幕簡報。 應用程式交換鏈結內容會流經系統撰寫器 DWM。
DXGI 輸出列舉 提供 HMONITOR 周圍的 DXGI 包裝函式。
QueryDisplayConfig、SetDisplayConfigDisplayConfigGetDeviceInfoDisplayConfigSetDeviceInfo 用於設定顯示拓撲的 Win32 API。 不提供列舉多個模式的機制,但有一組關於目前組態和設定的豐富資訊。 不過,並非所有較新的模式屬性都會由這些 API 公開。
Windows.Devices.Display.Core (本文件) 用於列舉目標、列舉模式、設定模式、配置 GPU 介面以供呈現,以及呈現要顯示的內容。

顯示組態概觀

實體硬體列舉

Windows.Devices.Display.Core API 有各種物件來代表實體硬體物件。 DisplayAdapter 通常是實體硬體裝置,例如PCI Express 連線 GPU 或 CPU 上的整合式 GPU。 DisplayTarget 物件代表可從 GPU 連線到的實體連接器(例如 HDMI、VGA、DisplayPort 等)。 這可能包括具有內部監視器之裝置的內部非使用者可見連線(膝上型電腦、平板電腦等)。 軟體中代表的 DisplayTarget 物件可能比使用者一次實際連線更多。 例如,由於 DisplayPort 連線標準允許菊花鏈結,GPU 驅動程式通常會列舉每個實體埠的數個 DisplayPort 目標,以考慮鏈結的監視器。

顯示配卡和顯示目標的硬體拓撲圖例。

設定模式的物件

針對列舉 DisplayTarget 對象、設定和查詢模式等等,DisplayTarget 對象的連接會以 DisplayPath 物件表示。 顯示相同內容(複製群組)的路徑群組會以 DisplayView 表示,這些路徑會匯總成 DisplayState。 因此,一個 DisplayState 物件可以代表一組完整的模式狀態,可傳送至多個監視器的驅動程式。

顯示路徑、顯示檢視和顯示狀態物件的模式拓撲圖例。

模式組態和列舉的不可部分完成狀態

Windows.Devices.Display.Core API 的設計目的是確保撰寫器可以不可部分完成地取得各種系統顯示狀態的存取權,以及定義完善的過時行為。 這很重要,因為 GPU 是共用的資源,頻寬和電源限制非常緊密。 在現代系統中,裝置可以隨時抵達/離開,其他專案可能會影響可用顯示模式的清單(例如停駐/取消停駐、睡眠狀態、另一個元件變更另一個路徑上的模式)。 因此,撰寫器請務必使用 Windows.Devices.Display.Core API 來復原系統設定的變更,並遵循設定狀態的建議模式。

因此,Windows.Devices.Display.Core API 提供與資料庫類似的簡單交易式讀取-修改認可模型。 用戶端可以不可部分完成地讀取顯示系統中裝置的 DisplayState 物件。 所有物件都是不可變的,或是提供定義完善的 API,以將狀態更新/認可回系統。 在呼叫 DisplayState.TryApply 之前,不會進行變更,這會對系統進行「認可」變更。 認可/套用變更至 DisplayState 失敗,不會有任何影響,或成功套用完整變更。

若要利用 API 的不可部分完成性功能:

  • 請在 重試迴圈中寫入任何模式組態邏輯。
  • 請在 模式組態的開頭,在每個迴圈內建立新的 DisplayState。
  • 呼叫 DisplayState.TryApply,請使用 FailIfStateChanged 旗標來偵測系統狀態不再與建立 DisplayState的狀態相同。 這可讓您有機會重試作業。 如果作業因 SystemStateChanged 而失敗,請重試整個迴圈。
  • 請勿 使用 Windows.Devices.Display.Core API 來混合讀取或變更狀態的其他 API(DXGI、GDI 等),因為它們可能沒有相同的不可部分完成性保證。
#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 會從系統以不可部分完成的方式讀取狀態:

下列 API 會將狀態認可回系統:

  • DisplayManager
  • DisplayState
    • TryApply 透過顯示驅動程式,在系統中所有擁有的目標上設定或清除模式,以更新目前的系統顯示狀態。

已知的限制

Windows.Devices.Display.Core API 有數個已知的限制(從 Windows 10 版本 2004 起):

範例指令碼

如需範例應用程式,請參閱 Windows.Devices.Display.Core 自定義撰寫器範例