Condividi tramite


Guida alla programmazione di swapchain di composizione

L'API di swapchain di composizione è un successore spirituale della porta di scambio DXGI, che consente alle applicazioni di eseguire il rendering e la presentazione del contenuto sullo schermo. L'uso di questa API tramite la porta di scambio DXGI offre diversi vantaggi. All'applicazione viene assegnato un controllo con granularità più fine per quanto riguarda lo stato della porta di scambio e viene fornita una maggiore libertà quando si tratta di come viene usata la porta di scambio. Inoltre, l'API offre una storia migliore per una tempistica attuale precisa.

Che cos'è la presentazione?

La presentazione è il concetto di visualizzazione dei risultati delle operazioni di disegno sullo schermo. Un presente è una singola istanza della presentazione, ovvero una richiesta di mostrare i risultati di un'operazione di disegno su un singolo buffer sullo schermo. Un presente può contenere attributi aggiuntivi che descrivono come visualizzare sullo schermo. In questa API, un presente può anche avere un'ora di destinazione, ovvero un timestamp relativo al sistema (un'ora di interruzione) che descrive l'ora ideale in cui deve essere visualizzata la presente. L'applicazione può usarla per controllare in modo più accurato la frequenza con cui il contenuto viene visualizzato sullo schermo e per sincronizzare i regali con altri eventi nel sistema, ad esempio una traccia audio.

Al centro della presentazione è la sincronizzazione. Ovvero, le operazioni di disegno vengono in genere eseguite da una GPU, anziché dalla CPU e, di conseguenza, vengono eseguite su una sequenza temporale asincrona da quella della CPU che ha eseguito inizialmente le operazioni. La presentazione è un'operazione inviata alla GPU che assicura che le operazioni di disegno rilasciate in precedenza siano state completate prima che il buffer venga visualizzato sullo schermo.

L'applicazione genererà molti regali nel corso del tempo e avrà più trame da selezionare durante l'emissione di regali. L'applicazione deve usare i meccanismi di sincronizzazione forniti da questa API per assicurarsi che una volta disegnata e presente un buffer, non si disegnare di nuovo in tale buffer fino a quando tale presente non viene visualizzato e successivamente sostituito con un nuovo buffer da un successivo presente. In caso contrario, il contenuto del buffer che l'applicazione intende presentare inizialmente può essere sovrascritto come visualizzato sullo schermo.

Modalità presentazione: composizione, sovrapposizione multiplane e iflip

I buffer presentati dall'applicazione possono essere visualizzati dal sistema in diversi modi.

Il modo più semplice, ovvero quello predefinito, è che il presente verrà inviato a DWM e il DWM eseguirà il rendering di un frame in base al buffer presentato. Ciò significa che è presente una copia (o più accuratamente, un rendering 3D) del buffer di presentazione nel backbuffer inviato dal DWM alla visualizzazione. Questo metodo di visualizzazione di un presente è denominato Composition.

Una modalità più efficiente di visualizzazione di un presente sarebbe quella di analizzare il buffer di presentazione direttamente nell'hardware ed eliminare la copia che avviene. Questo metodo di visualizzazione di un presente è denominato scanout diretto. Durante la gestione dei regali, DWM può decidere di programmare l'hardware per eseguire direttamente l'analisi da un buffer di presentazione, assegnando il buffer a un piano di sovrimpressione multipla (o piano MPO, per brevità) o capovolgendo direttamente il buffer all'hardware (noto come capovolgimento diretto).

Un modo ancora più efficiente per visualizzare un presente sarebbe quello di visualizzare i regali direttamente dal kernel grafico e ignorare completamente il DWM. Questo metodo di presentazione è noto come capovolgimento indipendente (iflip). Sia la sovrapposizione multiplane che iflip sono descritte in Per ottenere prestazioni ottimali, usare il modello di scorrimento DXGI.

La composizione è il più facilmente supportato, ma anche il meno efficiente. La superficie deve essere allocata appositamente per essere idonea per l'analisi diretta o iflip, e questo tipo di allocazione speciale ha requisiti di sistema più rigorosi rispetto alla swapchain di composizione. È disponibile solo in WDDM 3.0 e hardware superiore. Di conseguenza, l'applicazione può eseguire query sul supporto dell'API per la presentazione di sola composizione, nonché per la presentazione idonea per l'analisi diretta o iflip.

Factory di presentazione, controllo delle funzionalità e gestione presentazioni

Il primo oggetto che l'applicazione userà dall'API di swapchain di composizione è la factory di presentazione. La factory di presentazione viene creata dall'applicazione e associata a un dispositivo Direct3D che l'applicazione passa alla chiamata da creare e, di conseguenza, ha un'affinità con la scheda video associata al dispositivo.

La factory di presentazione espone i metodi per verificare se il sistema corrente e il dispositivo grafico sono in grado di usare l'API swapchain di composizione. È possibile usare metodi di funzionalità come IPresentationFactory::IsPresentationSupported per controllare il supporto del sistema. Se i metodi di funzionalità indicano il supporto del sistema per l'API, è possibile usare la factory di presentazione per creare un gestore presentazioni. Questo gestore di presentazioni è l'oggetto usato per eseguire funzioni di presentazione ed è associato allo stesso dispositivo Direct3D e alla scheda video di quella factory di presentazione usata per crearla.

Attualmente, i requisiti di sistema per l'uso dell'API di swapchain di composizione sono driver GPU che supportano WDDM (Windows Device Driver Model) 2.0 e Windows 11 (Build 10.0.22000.194) o versione successiva. Per usare l'API swapchain di composizione nel modo più efficiente (analisi diretta e capovolgimento indipendente o iflip), i sistemi necessitano di driver GPU che supportano WDDM 3.0.

Se il sistema non è in grado di usare l'API swapchain di composizione, l'applicazione dovrà disporre di un percorso di codice separato per gestire la presentazione usando metodi meno recenti, ad esempio una porta di scambio DXGI.

Registrare buffer di presentazione da presentare

Il gestore presentazioni tiene traccia dei buffer che può presentare. Per presentare una trama Direct3D, l'applicazione deve prima creare tale trama con Direct3D, quindi registrarla con lo strumento di gestione presentazioni. Quando una trama è stata registrata con il gestore presentazioni, viene chiamata buffer di presentazione e può da quel punto in poi essere presentata alla schermata da tale gestore di presentazione. L'applicazione può aggiungere e rimuovere buffer di presentazione come desiderato, anche se esiste un numero massimo di buffer di presentazione che possono essere aggiunti a un singolo gestore presentazioni (attualmente 31). Questi buffer di presentazione possono anche essere di dimensioni e formati variabili che avranno effetto quando viene presentato un singolo buffer di presentazione.

Una trama può essere registrata con un numero qualsiasi di manager di presentazione; Tuttavia, ciò non verrebbe considerato normale nella maggior parte dei casi e genererà scenari di sincronizzazione complessi che l'applicazione sarebbe responsabile della gestione.

Definizione del contenuto da presentare

In generale, i buffer presenti devono essere associati al contenuto in una struttura ad albero visuale. È quindi necessario definire un tipo di binding in modo che, quando si verificano problemi dell'applicazione, è chiaro dove nella struttura ad albero visuale i buffer presentati devono essere inseriti. Questa associazione viene chiamata Contenuto presentazione.

Il contenuto presentato potrebbe assumere molte forme. L'applicazione potrebbe voler presentare un singolo buffer da visualizzare oppure potrebbe voler presentare contenuto stereo con buffer sia per l'occhio sinistro che per quello destro e così via. La versione iniziale di questa API offre il supporto per la presentazione di un singolo buffer sullo schermo.

Definiamo una superficie di presentazione come forma di contenuto di presentazione a cui viene presentato un singolo buffer alla volta. Una superficie di presentazione può essere impostata come contenuto in una struttura ad albero visuale e può mostrare un singolo buffer di presentazione sullo schermo alla volta. Presentation Manager presenta aggiornerà il buffer visualizzato da una o più superfici di presentazione in modo atomico.

Il gestore di presentazioni può essere usato per creare una o più superfici di presentazione per un handle di superficie di composizione specifico. Ogni handle di superficie di composizione può essere associato a uno o più oggetti visivi in una struttura ad albero visuale (tramite strategie descritte nella documentazione dell'API Windows.UI.Composition e DirectComposition) per definire la relazione tra la superficie di presentazione associata e la posizione in cui viene visualizzata nella relativa struttura ad albero visuale. L'applicazione può aggiornare una o più superfici di presentazione, inviate al sistema e eseguite alla successiva operazione presente.

Si noti che il gestore di presentazioni può presentare qualsiasi buffer di presentazione a un numero qualsiasi di superfici di presentazione desiderate. Non ci sono restrizioni. Tuttavia, spetta all'applicazione tenere traccia dei buffer rilasciati e dove, per assicurarsi di non tentare di rilasciare un nuovo disegno nel buffer mentre è ancora visualizzato da una superficie di presentazione.

Applicazione di proprietà all'area di presentazione

Oltre a specificare quali buffer visualizzare in una superficie di presentazione, un presente può anche specificare varie altre proprietà per tale superficie di presentazione. Queste includono proprietà che definiscono come verrà campionata la trama di origine, tra cui la modalità alfa e lo spazio colore, il modo in cui la trama di origine verrà trasformata e disposta e le eventuali restrizioni di visualizzazione o readback per il contenuto protetto. Tutti questi metodi vengono esposti come metodi di setter delle proprietà in una superficie di presentazione che possono essere modificati dall'applicazione e, analogamente agli aggiornamenti del buffer, avranno effetto quando viene eseguita la presentazione dell'applicazione.

Presentazione alla superficie di presentazione

Dopo che l'applicazione crea superfici di presentazione, registra i buffer di presentazione e specifica gli aggiornamenti per il problema durante un presente, è possibile applicare tali proprietà presentando. L'applicazione genera un presente tramite lo strumento di gestione presentazioni. Quando tale presente viene elaborato dal sistema, tutti gli aggiornamenti vengono applicati in modo atomico. Inoltre, l'applicazione può anche specificare altre proprietà del presente, ad esempio il momento ideale in cui deve avvenire (l'ora di destinazione attuale) e altre proprietà più rare, ad esempio la frequenza di contenuto prevista, che può essere usata per abilitare le modalità di aggiornamento personalizzate nel sistema. Poiché i regali possono essere pianificati in un determinato momento, l'applicazione può emettere più regali in anticipo. Questi regali verranno elaborati uno alla volta man mano che viene raggiunta l'ora pianificata.

Sincronizzazione della presentazione

L'applicazione deve essere sicura che quando esegue il rendering in buffer e presenta problemi, seleziona un buffer per il rendering in cui non viene attualmente fatto riferimento da nessun altro presente precedente in sospeso, in quanto in questo modo potrebbe sovrascrivere il contenuto del buffer previsto. Inoltre, se l'applicazione rilascia il rendering in un buffer attualmente visualizzato da una superficie di presentazione nell'hardware di scanout, il rendering potrebbe essere bloccato a tempo indeterminato, perché Direct3D non consente il rendering del buffer anteriore.

L'API swapchain di composizione fornisce alcuni meccanismi diversi per consentire all'applicazione di praticare una corretta sincronizzazione dei buffer presentati.

Si dice che un buffer sia disponibile se non sono presenti regali in sospeso che lo fanno riferimento e attualmente non viene visualizzato dal sistema. In caso contrario, non è disponibile. L'API fornisce un evento per ogni buffer di presentazione che indica se il buffer è disponibile o meno. Si tratta del metodo di sincronizzazione più semplice da usare per l'applicazione. Prima di disegnare in un buffer e presentarlo, l'applicazione può assicurarsi che venga segnalato l'evento disponibile . L'evento disponibile per un particolare buffer diventa senza segno nel momento in cui è stato associato a una superficie di presentazione nell'API e rimane senza segno fino a quando il presente non viene ritirato.

In secondo luogo, il responsabile della presentazione tiene traccia di un singolo recinto presente in ritiro per comunicare con l'applicazione che sono stati completati. Il valore della recinzione corrisponde all'identificatore presente dell'ultimo presente che ha iniziato la fase di ritiro del ciclo di vita, come illustrato nella sezione del ciclo di vita seguente. Una volta che un presente entra in questa fase, è sicuro presupporre che tutti i buffer che sono stati sostituiti dai regali successivi possono essere riutilizzati.

Questo metodo di sincronizzazione è più avanzato, ma consente un maggiore controllo sulla limitazione del flusso di lavoro ed è più informativo sullo stato del sistema per quanto riguarda la profondità della coda corrente. Per una panoramica del ciclo di vita di un presente, vedere la sezione seguente.

Ciclo di vita di un presente

I regali di Presentation Manager vengono accodati al sistema come parte della coda corrente. I processi di sistema vengono visualizzati nell'ordine in coda. Inoltre, ogni presente ha un identificatore presente univoco (per il gestore presentazioni) associato, ovvero un valore di incremento assegnato a un presente, a partire da 1 per il primo presente e incrementando di 1 per ogni presente successivo. Questo identificatore presente viene usato in varie parti dell'API, ad esempio primitive di sincronizzazione e statistiche di presentazione, per fare riferimento a tale particolare presente.

Ogni presente che i problemi dell'applicazione seguono un ciclo di vita specifico, come descritto qui.

Dopo che l'applicazione configura le modifiche da apportare come parte di un presente, userà il gestore presentazioni per rilasciare effettivamente il presente. A questo punto, si dice che il presente sia in sospeso.

Una volta in sospeso, un presente siederà nella coda presente del responsabile della presentazione, dove rimarrà fino a quando non si verifica una delle due cose.

  • Il presente viene annullato. Lo strumento di gestione presentazioni consente all'applicazione di annullare i regali rilasciati in precedenza. In questo caso, il presente viene detto di essere annullato e quindi diventa immediatamente ritirato. In questa transizione, gli eventi disponibili del buffer associati per la presente annullata verranno aggiornati, ma il limite attualmente ritirato non verrà segnalato, perché il presente presente visualizzato in precedenza (prima dei regali annullati) rimarrà visualizzato. Per questo motivo, l'applicazione non può usare il recinto attuale ritiro per determinare quali regali sono stati annullati. È invece necessario apprendere questa situazione dalla statistica di stato presente che torna per ogni presente presente annullata. È consigliabile che l'applicazione usi eventi disponibili nel buffer per trovare un buffer disponibile da presentare dopo un annullamento. Una volta visualizzato il presente, il presente precedente inizierà il processo di ritiro e aggiornerà il limite di ritiro presente.
  • Se non viene annullato, il presente alla fine diventa pronto per l'elaborazione. Per essere pronti, devono essere soddisfatte due condizioni principali.
    • Tutte le operazioni di disegno rilasciate nel contesto Direct3D prima della chiamata al presente devono essere completate. In questo modo si garantisce che il buffer non venga visualizzato prima del completamento del disegno dell'applicazione.
    • Se è stata specificata un'ora di destinazione attuale, l'ora relativa al sistema corrente che si prevede di poter mostrare il presente soddisfa il tempo di destinazione richiesto applicato all'applicazione corrente.

Quando il sistema decide di trovare un presente da mostrare sullo schermo, sceglierà l'ultimo presente che è diventato pronto per la visualizzazione. Se sono presenti più regali pronti, tutti gli eventi disponibili nel buffer, ovvero il presente con l'identificatore più grande presente, verranno ignorati e immediatamente entrano nello stato ritirato, a quel punto verranno segnalato gli eventi disponibili nel buffer, ma il limite di ritiro presente non verrà segnalato, perché il presente presente non passa dallo stato visualizzato.

Quando viene scelto di visualizzare il presente pronto , il sistema inizia a eseguire il lavoro per visualizzarlo sullo schermo. Ciò può significare il rendering del buffer come parte di un frame DWM e quindi richiedere l'hardware mostrare tale fotogramma sullo schermo oppure potrebbe significare inviare il buffer direttamente all'hardware di analisi nel caso di iflip. Al termine di questa operazione, si dice che il presente venga accodato. Ad alto livello, questo significa che è sulla sua strada per essere visualizzato.

Quando l'hardware viene visualizzato per visualizzare il presente, si dice che questo presente venga visualizzato. Lì rimarrà, visibile sullo schermo, fino a quando non arriva un successivo presente e lo sostituisce.

Quando un presente successivo viene accodato, si sa che l'hardware smetterà di mostrare il presente corrente. A questo punto, si dice che il presente si ritiri.

Quando il presente successivo diventa visualizzato, si dice che il presente corrente venga ritirato.

Il responsabile della presentazione espone un recinto di ritiro presente, che viene segnalato all'identificatore presente di ogni presente quando entra nello stato di ritiro . Questo segnale indica all'applicazione che è diventato sicuro eseguire il rendering del lavoro nei buffer associati a tale presente senza danneggiare un presente precedente. Se il rendering dell'applicazione non funziona durante lo stato di ritiro del presente, il lavoro di rendering verrà accodato fino a quando il presente non entra nello stato ritirato, a quel punto verrà eseguito. Se il lavoro di rendering viene emesso dopo che il presente viene ritirato, verrà eseguito immediatamente.

Di seguito è riportato un diagramma della modifica dello stato.

Lifecycle of a present

Diagramma di buffer, superfici e presentazione

Di seguito è riportato un diagramma relativo al gestore presentazioni, ai buffer di presentazione, alle superfici di presentazione, alle presentazioni, alle presentazioni e agli aggiornamenti.

Diagram of buffers, surfaces, and presents

Questo diagramma mostra un gestore presentazioni, con due superfici di presentazione e tre buffer di presentazione, che hanno avuto due presentazioni rilasciate finora, ovvero il primo buffer visualizzato 1 nella superficie 1 e il buffer 2 nella superficie 2. La seconda versione aggiornata della superficie 2 per mostrare il buffer di presentazione 3 e non ha modificato l'associazione della superficie 1. Dopo la visualizzazione di 2, la superficie 1 mostrerà il buffer 1 e la superficie 2 mostrerà il buffer 3, che può essere visualizzato nello stato corrente degli oggetti nella gestione presentazioni. Ogni presente nella coda avrà effetto quando viene elaborato nel sistema.

Nota

Poiché Present 2 non ha modificato il buffer per la superficie 1, la superficie 1 è stata lasciata associata al buffer 1 rispetto al presente precedente. In questo senso, esiste un riferimento "implicito" nel buffer 1 presente 2, poiché la superficie 1 rimarrà associata al buffer 1 dopo la visualizzazione di 2.

Aggiunta di superfici di presentazione alla struttura ad albero visuale

Le superfici di presentazione sono contenuti esistenti come parte di una struttura ad albero visuale della composizione. Ogni superficie di presentazione è associata a un punto di manipolazione della superficie di composizione. In Windows.UI.Composition è possibile creare un pennello di superficie per un handle di superficie di composizione preesistente e associato a un oggetto visivo sprite. In DirectComposition, una superficie di composizione può essere creata da un handle di superficie di composizione preesistente e associata come contenuto a un oggetto visivo. Per altre informazioni, vedere la documentazione corrispondente per ogni API.

API come Windows Media Foundation, compilate per usare questa API, espongono handle di superficie di composizione che verranno pre-associati a una superficie di presentazione. Un'applicazione può anche creare un handle di superficie di composizione personalizzato per associarsi successivamente a una superficie di presentazione e aggiungere a una struttura ad albero visuale chiamando DCompositionCreateSurfaceHandle.

Lettura delle statistiche di presentazione

L'API swapchain di composizione espone statistiche di presentazione, che descrivono varie informazioni su come è stato elaborato un particolare presente. Le informazioni in genere potrebbero descrivere come è stata usata una superficie di presentazione in un frame DWM, il punto nel tempo in cui è stato visualizzato, se è stato visualizzato o meno e così via.

Esistono diversi tipi di statistiche di presentazione e sono progettati per essere espandibili nelle versioni future dell'API. Un'applicazione usa lo strumento di gestione presentazioni per registrarsi per ricevere i tipi di statistiche a cui è interessato. Tali statistiche vengono quindi spostate nella coda delle statistiche del gestore presentazioni. Il responsabile della presentazione espone un evento disponibile per le applicazioni, ovvero un handle di eventi che indica quando la coda delle statistiche contiene elementi statistici disponibili per la lettura. Quando lo fa, l'applicazione può rimuovere dalla coda il primo elemento delle statistiche, leggerlo ed elaborarlo. Il responsabile della presentazione reimposta le statistiche disponibili quando l'applicazione ha letto tutte le statistiche attualmente presenti nella coda. Un'applicazione legge e elabora le statistiche in un ciclo fino a quando non viene reimpostato l'evento disponibile per le statistiche. È comune che l'applicazione eselabori questa coda di statistiche nello stesso ciclo di lavoro usato per presentare i problemi. Il modello di utilizzo suggerito consiste nell'classificare in ordine di priorità le statistiche di elaborazione rispetto al rilascio di nuovi regali, per assicurarsi che la coda non eselabori l'overflow.

La coda ha un numero massimo di statistiche che verrà monitorata, che sarà nell'ordine di 512-1024 statistiche. La profondità massima della coda deve essere sufficiente per archiviare circa 5 secondi di statistiche nei casi normali. Se la coda delle statistiche diventa piena e vengono segnalate più statistiche, il criterio è che le statistiche meno recenti verranno ritirati per fare spazio.