Condividi tramite


Creazione di un'app compositor personalizzata per monitoraggi montati e specializzati

L'API Windows.Devices.Display.Core è un'API Windows Runtime (WinRT) di basso livello per compositori di terze parti e componenti interni di Windows che si trova sotto tutte le altre API pubbliche per enumerare, configurare e guidare schede di visualizzazione e destinazioni di visualizzazione in Windows. L'idea è quella di considerare il controller di visualizzazione come un motore separato, analogo al motore 3D e al motore multimediale nella GPU. Questa API è responsabile di:

  • Risposte alle query sull'hardware di visualizzazione (ad esempio funzionalità e modalità di visualizzazione possibili)
  • Risposta alle query sulla configurazione corrente
  • Impostazione delle proprietà sull'hardware di visualizzazione (ad esempio le modalità di visualizzazione)
  • Configurazione dell'hardware di visualizzazione (la risoluzione dei monitor connessi, il relativo formato di collegamento e così via)
  • Allocazione ed analisi di superfici GPU speciali note come primarie
  • Possibilità di interoperabilità tra Direct3D e le API Windows.Devices.Display.Core (ad esempio condivisione di superfici, recinzioni)

Vale la pena di chiamare ciò che Windows.Devices.Display.Core non è:

  • Non è un'API usata da giochi o app per la visualizzazione del contenuto in una finestra. Le app usano ancora DXGI, XAML, API di composizione, GDI e così via.
  • Non è un'API usata da giochi o app per la visualizzazione del contenuto a schermo intero. Le app usano ancora DXGI, le app Win32 usano ancora HWND e le app UWP visualizzano sempre il contenuto in un CoreWindow.

Questa API è destinata alle app compositori che guidano solo hardware specializzato.

Diagramma che mostra i livelli architetturali dell'API per le visualizzazioni specializzate.

Scenari per la creazione di compositori personalizzati

Le API Windows.Devices.Display.Core sono appropriate per l'uso negli scenari seguenti:

  • Schermi di realtà virtuale e aumentata che richiedono un compositore proprietario per guidare direttamente il controller di visualizzazione e ricevere un controllo granulare sulla tempistica e la configurazione della modalità separate dal desktop di Windows.
  • Scenari hardware di visualizzazione specializzati che richiedono un controllo dedicato su uno schermo in un'impostazione commerciale. Ad esempio, nei casi in cui il desktop di Windows non è in grado di eseguire correttamente il rendering su tale schermo a causa di distorsioni hardware, schermi in scala di grigi e così via.
  • Scenari di "appliance" specializzati in cui un monitor può essere completamente dedicato a un'app senza interferenze dall'esperienza desktop di Windows in un lungo periodo di tempo (ad esempio, un monitor video dedicato).

A tale scopo, l'API esegue questa operazione:

  • Fornire un controllo granulare sulle informazioni sulla modalità di visualizzazione completa, tra cui formato di filo, HDR e così via.
  • L'uso di recinti per sincronizzare la presentazione consente a un compositor di concatenare la presentazione tra processi o componenti secondari con un sovraccarico di prestazioni quasi zero.
  • Miglioramento della possibilità di eseguire query e configurare la rete VidPN (Video Present Network) sottostante per consentire ai componenti di sistema e ai componenti di composizione di basso livello di eseguire operazioni più complesse in modo meno soggetto a errori e più estendibile.

Si noti che questa API è solo per un set molto specifico di casi d'uso di terze parti con hardware specializzato. Il suo uso è altamente limitato all'hardware che dichiara se stesso la necessità della funzionalità di questa API. Pertanto, è previsto un certo grado di familiarità con i concetti hardware degli sviluppatori e i partner devono contattare Microsoft direttamente per risolvere i problemi.

Requisiti hardware e software

I compositori personalizzati di terze parti possono acquisire solo schermi pre-designati come display a testa (HMD) o display "specializzati". Questa designazione deve essere fornita in uno dei due modi seguenti:

  • Estensione EDID: i dispositivi di visualizzazione personalizzati progettati per l'uso permanente come HMD, monitor a raggi X, pareti video o altri scenari specializzati devono implementare l'estensione Microsoft EDID per schermi montati a testa e specializzati.
  • Override utente: per le installazioni hardware personalizzate che usano monitor off-the-shelf, Windows fornisce un interruttore dell'interfaccia utente per progettare i monitor come "specializzati".

Gli schermi non possono essere designati come HMD o display specializzati eseguendo l'override dell'EDID nel software.

Nota

Gli schermi specializzati sono disponibili solo a partire da Windows 10 versione 2004 e richiedono Windows 10 Enterprise, Windows 10 Pro per workstation o Windows 10 IoT Enterprise.

Roadmap per l'implementazione di un programma di composizione personalizzato

L'implementazione di un programma di composizione personalizzato può essere suddivisa in diverse fasi:

  • Enumerare e individuare gli HMD associati o le visualizzazioni specializzate
  • Acquisire la proprietà delle visualizzazioni selezionate
  • Configurare le modalità per tutti i display selezionati
  • Creare risorse per la presentazione di frame nei display
  • Eseguire il rendering del contenuto e pianificare la presentazione dei fotogrammi
API Scopo e destinatari
DisplayInformation Usato per recuperare le proprietà di rendering e layout per coreWindow.
HdmiDisplayInformation API solo Xbox per l'enumerazione e l'impostazione di un set vincolato di modalità. Altamente specializzata per gli scenari di app multimediali Xbox.
DisplayMonitor Usato per eseguire query su proprietà di un dispositivo di monitoraggio fisico. Non espone informazioni di runtime sul modo in cui un monitoraggio è configurato o attualmente usato dal sistema operativo.
EnumDisplayDevices, EnumDisplayMonitors, EnumDisplaySettingsEx API Win32 legacy per l'esecuzione di query su HMONITORs, dispositivi GDI e mapping di monitoraggio fisico. Le informazioni restituite qui sono altamente virtualizzate e mantenute per la compatibilità delle applicazioni.
Direct3D Usato per il rendering del contenuto dei pixel in superfici GPU ed esecuzione del calcolo su una GPU.
Catene di scambio DXGI Utilizzato per la presentazione a schermo intero finestrata e senza bordi. Il contenuto della catena di scambio di app passa attraverso il programma di composizione del sistema, DWM.
Enumerazione di output DXGI Fornisce wrapper DXGI intorno a HMONITORs.
QueryDisplayConfig, SetDisplayConfig, DisplayConfigGetDeviceInfo, DisplayConfigSetDeviceInfo API Win32 per la configurazione della topologia di visualizzazione. Non fornisce alcun meccanismo per enumerare più modalità, ma include un set completo di informazioni sulla configurazione e le impostazioni correnti. Non tutte le proprietà più recenti di una modalità sono tuttavia esposte da queste API.
Windows.Devices.Display.Core (questo documento) Usato per enumerare le destinazioni, enumerare le modalità, configurare le modalità, allocare superfici GPU per la presentazione e presentare il contenuto da visualizzare.

Panoramica della configurazione di visualizzazione

Enumerazione hardware fisico

L'API Windows.Devices.Display.Core include vari oggetti per la rappresentazione di oggetti hardware fisici. Un DisplayAdapter è in genere (ma non sempre) un dispositivo hardware fisico, ad esempio una GPU connessa a PCI Express o una GPU integrata in una CPU. Gli oggetti DisplayTarget rappresentano i connettori fisici ,ad esempio HDMI, VGA, DisplayPort e così via, che possono essere connessi dalla GPU. Ciò può includere connessioni interne non visibili all'utente per i dispositivi con monitor interni (portatili, tablet e così via). Potrebbero essere presenti più oggetti DisplayTarget rappresentati nel software rispetto a quelli che un utente può connettersi fisicamente contemporaneamente. Ad esempio, poiché lo standard di connessione DisplayPort consente il concatenamento dei dati, i driver GPU enumerano in genere diverse destinazioni DisplayPort per porta fisica per tenere conto dei monitor concatenati.

Illustrazione della topologia hardware per schede di visualizzazione e destinazioni di visualizzazione.

Oggetti per l'impostazione delle modalità

Per l'enumerazione di oggetti DisplayTarget, l'impostazione e le modalità di query e così via, le connessioni agli oggetti DisplayTarget vengono rappresentate con oggetti DisplayPath. I gruppi di percorsi che visualizzano lo stesso contenuto (gruppi di cloni) sono rappresentati da DisplayView e questi vengono aggregati in displayState. Un oggetto DisplayState può quindi rappresentare un set completo di stato della modalità che può essere inviato ai driver per più monitor.

Illustrazione della topologia in modalità con percorso di visualizzazione, visualizzazione e oggetti stato di visualizzazione.

Stato atomico per la configurazione e l'enumerazione della modalità

L'API Windows.Devices.Display.Core è progettata per garantire che i compositori possano acquisire l'accesso a vari stati di visualizzazione del sistema in modo atomico e con comportamenti di decadimento ben definiti. Questo è importante perché le GPU sono risorse condivise, con vincoli di larghezza di banda e alimentazione molto limitati. Nei sistemi moderni, i dispositivi possono arrivare/partire in qualsiasi momento e altre cose possono influire sull'elenco delle modalità di visualizzazione disponibili (ad esempio l'ancoraggio o l'scollegamento, gli stati di sospensione, un altro componente che cambia modalità in un altro percorso). È quindi importante che i compositori siano resilienti alle modifiche apportate alla configurazione del sistema usando l'API Windows.Devices.Display.Core e seguendo i modelli consigliati per la configurazione dello stato.

L'API Windows.Devices.Display.Core fornisce quindi un semplice modello transazionale read-modify-commit, simile a un database. I client possono leggere in modo atomico un oggetto DisplayState per i dispositivi di visualizzazione nel sistema. Tutti gli oggetti sono non modificabili oppure forniscono API ben definite per aggiornare o eseguire il commit dello stato nel sistema. Le modifiche non vengono apportate fino a quando non viene chiamato DisplayState.TryApply , che "esegue il commit" delle modifiche apportate al sistema. Il commit o l'applicazione di modifiche a displayState non riesce senza alcun impatto o ha esito positivo con le modifiche complete applicate.

Per sfruttare le funzionalità di atomicità dell'API:

  • Scrivere qualsiasi logica di configurazione in modalità in un ciclo di ripetizione dei tentativi.
  • Creare un nuovo displayState all'inizio della configurazione della modalità, all'interno di ogni ciclo.
  • Usare il flag FailIfStateChanged quando si chiama DisplayState.TryApply per rilevare che lo stato del sistema non è più lo stesso di quando è stato creato DisplayState . In questo modo è possibile ritentare l'operazione. Se l'operazione ha esito negativo con SystemStateChanged, ripetere l'intero ciclo.
  • Non combinare altre API (DXGI, GDI e così via) che leggono o modificano lo stato con l'uso delle API Windows.Devices.Display.Core, perché potrebbero non avere le stesse garanzie di atomicità.
#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);

Le API seguenti leggono lo stato in modo atomico dal sistema:

Le API seguenti eseguono il commit dello stato nel sistema:

  • DisplayManager
    • TryAcquireTarget ReleaseTarget/ (e acquisizione di destinazioni con TryAcquireTargetsAnd* metodi) Acquisisce la proprietà di DisplayTargets dal sistema.
  • DisplayState
    • TryApply Aggiorna lo stato di visualizzazione corrente del sistema impostando o cancellando le modalità in tutte le destinazioni di proprietà del sistema, tramite i driver di visualizzazione.

Limitazioni note

L'API Windows.Devices.Display.Core presenta diverse limitazioni note (a partire da Windows 10, versione 2004):

  • I driver di visualizzazione indiretti (ad esempio Miracast, schede di visualizzazione USB, driver software) non possono essere risolti attualmente. DisplayManager.CreateDisplayDevice avrà esito negativo quando viene passata una scheda di visualizzazione indiretta.

Codice di esempio

Per un'applicazione di esempio, vedere l'esempio di compositore personalizzato Windows.Devices.Display.Core.