Concetti fondamentali

Nota

Per le app in Windows 10, è consigliabile usare le API Windows.UI.Composition anziché DirectComposition. Per altre informazioni, vedere Modernizzare l'app desktop usando il livello visuale.

Questo argomento offre una panoramica dei concetti di base di Microsoft DirectComposition. Contiene le sezioni seguenti:

Composizione

DirectComposition definisce una composizione come una raccolta di bitmap combinate e manipolate applicando varie trasformazioni, effetti e animazioni per produrre un risultato visivo in un'interfaccia utente dell'applicazione. DirectComposition funziona solo con contenuto bitmap; non supporta vettori o testo. DirectComposition non fornisce contenuto bitmap. Fornisce invece interfacce in cui gli utenti possono disegnare con D2D, DXGI o caricare il proprio contenuto di trama.

Un'applicazione DirectComposition crea due set di oggetti per comporre una scena: bitmap composte insieme e oggetti visivi che definiscono le relazioni spaziali tra le bitmap. Per altre informazioni sugli oggetti bitmap supportati da DirectComposition, vedere Oggetti Bitmap.

Oggetti visivi

Glioggetti visivi (o oggetti visivi) sono gli elementi fondamentali di DirectComposition. Sono i blocchi predefiniti di base usati per creare composizioni e animazioni nell'interfaccia utente dell'applicazione.

In termini di programmazione, un oggetto visivo è un oggetto con un set di proprietà ed espone un'interfaccia usata per impostare il valore delle proprietà. La proprietà Content di un oggetto visivo associa una particolare bitmap all'oggetto visivo, mentre altre proprietà controllano il modo in cui DirectComposition posiziona e modifica l'oggetto visivo come viene eseguito il rendering sullo schermo.

Per altre informazioni, vedere Proprietà di un oggetto visivo.

Albero visivo

DirectComposition crea una composizione da una raccolta gerarchica di oggetti visivi denominata albero visivo. L'oggetto visivo alla radice di un albero viene chiamato oggetto visivo radice e può avere uno o più oggetti visivi figlio associati. Un oggetto visivo figlio può avere uno o più oggetti visivi figlio propri. Qualsiasi oggetto visivo che ha oggetti visivi figlio associati viene chiamato oggetto visivo padre e tutti gli oggetti visivi figlio che condividono lo stesso elemento padre sono denominati oggetti visivi di pari livello. Un oggetto visivo specifico insieme a tutti gli oggetti visivi figlio e discendenti viene chiamato sottoalbero visivo.

La posizione di un oggetto visivo nell'albero consente di determinare la posizione dello schermo e l'ordine z rispetto agli altri oggetti visivi nella composizione. L'oggetto visivo radice viene posizionato rispetto all'angolo superiore sinistro dell'area client della finestra di destinazione in cui viene eseguito il rendering della composizione. Tutti gli oggetti visivi figlio vengono posizionati rispetto all'angolo superiore sinistro dell'oggetto visivo padre (o l'oggetto visivo specificato dalla proprietà TransformParent) e vengono sempre visualizzati davanti al padre nell'ordine z.

La figura seguente mostra una composizione di oggetti visivi e la struttura dell'albero visivo usato per produrre la composizione. Visual 1 è l'oggetto visivo radice ed è anche l'elemento padre degli oggetti visivi figlio 2 e 3, che sono oggetti visivi di pari livello. Visual 3 include due oggetti visivi figlio personalizzati, Visuals 4 e 5. Insieme, Gli oggetti visivi da 3 a 5 costituiscono un sottoalbero visivo.

una composizione di oggetti visivi e l'albero visivo corrispondente

Un oggetto visivo padre gestisce un elenco ordinato degli oggetti visivi figlio. Quando gli oggetti visivi di pari livello vengono posizionati in modo che si sovrapponga tra loro, DirectComposition imposta l'ordine z dei fratelli in base all'ordine in cui vengono visualizzati nell'elenco elementi figlio dell'oggetto visivo padre. Un fratello che viene visualizzato più avanti nell'elenco viene posizionato davanti a tutti i fratelli che vengono visualizzati in precedenza nell'elenco. La figura seguente mostra l'ordine z degli oggetti visivi figlio sovrapposti.

ordine z degli oggetti visivi figlio sovrapposti

Proprietà di un oggetto visivo

Un oggetto visivo espone un set di proprietà che consentono di impostare il contenuto bitmap per l'oggetto visivo e di controllare il modo in cui DirectComposition posiziona e modifica il contenuto visivo. Le sezioni seguenti descrivono in dettaglio ogni proprietà.

Proprietà di contenuto

La proprietà Content di un oggetto visivo specifica il contenuto bitmap associato all'oggetto visivo. Si tratta della bitmap usata da DirectComposition quando si include l'oggetto visivo in una composizione.

Impostare la proprietà Content di un oggetto visivo chiamando il metodo IDCompositionVisual::SetContent .

Per altre informazioni sui tipi di contenuto bitmap supportati da DirectComposition, vedere Oggetti Bitmap.

Proprietà Clip

La proprietà Clip di un oggetto visivo specifica un'area rettangolare denominata area di ritaglio (o rettangolo di clip). Quando viene eseguito il rendering di un oggetto visivo, viene visualizzata solo la parte dell'oggetto visivo che rientra nell'area di ritaglio, mentre qualsiasi contenuto che si estende all'esterno dell'area di ritaglio viene ritagliato (ovvero non visualizzato). DirectComposition supporta le aree di ritaglio con angoli arrotondati o quadrati.

Impostare la proprietà Clip di un oggetto visivo chiamando il metodo IDCompositionVisual::SetClip .

Per altre informazioni, vedere Ritaglio.

BorderMode, proprietà

La proprietà BorderMode specifica come comporre i bordi delle bitmap e delle clip associate a questo oggetto visivo o agli oggetti visivi nel sottoalbero radicato in questo oggetto visivo.

La modalità bordo influisce sul modo in cui i bordi di una bitmap vengono composti quando la bitmap viene trasformata in modo che i bordi non siano allineati all'asse con coordinate integer. Influisce anche sul modo in cui il contenuto viene ritagliato agli angoli di una clip che ha angoli arrotondati e al bordo di un clip trasformato in modo che i bordi non siano allineati all'asse con coordinate integer.

Per altre informazioni, vedere IDCompositionVisual::SetBorderMode.

BitmapInterpolationMode, proprietà

La proprietà BitmapInterpolationMode indica a DirectComposition come comporre una bitmap quando viene trasformata in modo che non esista una corrispondenza uno-a-uno tra pixel nella bitmap e nei pixel sullo schermo.

Impostare la proprietà BitmapInterpolationMode di un oggetto visivo chiamando il metodo IDCompositionVisual::SetBitmapInterpolationMode .

CompositeMode, proprietà

La proprietà CompositeMode indica a DirectComposition come combinare il contenuto bitmap di un oggetto visivo con la destinazione di rendering. Per una descrizione delle modalità composite supportate, vedere DCOMPOSITION_COMPOSITE_MODE.

Impostare la proprietà CompositeMode di un oggetto visivo chiamando il metodo IDCompositionVisual::SetCompositeMode .

Proprietà OffsetX e OffsetY

Le proprietà OffsetX e OffsetY indicano a DirectComposition dove posizionare un oggetto visivo orizzontalmente e verticalmente. Definiscono la posizione fissa bidimensionale da cui vengono calcolate tutte le trasformazioni e gli effetti per l'oggetto visivo.

Per un oggetto visivo radice, le proprietà OffsetX e OffsetY definiscono la coordinata x e la coordinata y di un punto rispetto all'angolo superiore sinistro della finestra che ospita l'oggetto visivo. Per un oggetto visivo figlio, le coordinate sono relative all'angolo superiore sinistro dell'oggetto padre o, se viene specificata la proprietà TransformParent , l'angolo superiore sinistro dell'oggetto visivo specificato. Quando viene eseguito il rendering di un oggetto visivo, viene posizionato in modo che l'angolo superiore sinistro dell'oggetto visivo coincide con le coordinate specificate.

Impostare le proprietà OffsetX e OffsetY di un oggetto visivo chiamando i metodi IDCompositionVisual::SetOffsetX e SetOffsetY .

Proprietà Effect

La proprietà Effect consente di specificare un effetto o un gruppo di effetti, che modificherà la modalità di composizione di un oggetto visivo e del relativo sottoalbero. Ad esempio, è possibile specificare gli effetti che controllano l'opacità di un oggetto visivo, unire l'oggetto visivo con un'altra bitmap in vari modi e applicare trasformazioni di prospettiva all'oggetto visivo.

Impostare la proprietà Effect di un oggetto visivo chiamando il metodo IDCompositionVisual::SetEffect .

Per altre informazioni, vedere Effects (Effetti).

Transform (proprietà)

La proprietà Transform specifica una trasformazione bidimensionale (2D) o un gruppo di trasformazioni 2D, affinché DirectComposition esegua l'esecuzione nell'oggetto visivo. Una trasformazione (o trasformazione) è un'operazione che modifica il sistema di coordinate di un oggetto visivo rispetto al relativo oggetto padre o rispetto all'oggetto visivo specificato dalla proprietà TransformParent. È possibile usare le trasformazioni per modificare la posizione, le dimensioni o la natura di un oggetto visivo spostandola in un'altra posizione (traslazione), rendendola più grande o più piccola (ridimensionamento), ruotandola (rotazione), distorcendone la forma (asimmetria) e così via.

Per impostare la proprietà Transform di un oggetto visivo, chiamare il metodo IDCompositionVisual::SetTransform .

Per altre informazioni, vedere Trasformazioni.

TransformParent - proprietà

Il sistema di coordinate di un oggetto visivo viene modificato dalle proprietà OffsetX, OffsetY e Transform. In genere, queste proprietà definiscono il sistema di coordinate di un oggetto visivo rispetto al padre immediato. Per utilizzare un oggetto visivo diverso da padre come base per il sistema di coordinate di un oggetto visivo figlio, utilizzare la proprietà TransformParent per specificare un oggetto visivo diverso come "padre" a scopo di trasformazione.

Per impostare la proprietà TransformParent di un oggetto visivo, chiamare il metodo IDCompositionVisual::SetTransformParent .

Oggetto dispositivo

Per usare DirectComposition, è necessario creare e modificare un'ampia gamma di oggetti COM (Component Object Model). Il primo oggetto che è necessario creare è l'oggetto dispositivo DirectComposition perché funge da factory per la creazione di tutti gli altri oggetti usati in una composizione.

Per creare un oggetto dispositivo, chiamare la funzione DCompositionCreateDevice , che restituisce un puntatore all'interfaccia IDCompositionDevice . Questa interfaccia espone un set di metodi usati per creare oggetti visivi, ritagliare oggetti, oggetti animazione, trasformare oggetti, oggetti effetto e così via.

L'oggetto dispositivo serve un altro scopo oltre a essere una factory per la creazione di altri oggetti. Espone un metodo denominato Commit che passa una struttura ad albero visuale a DirectComposition per l'elaborazione. Per altre informazioni, vedere Composizione transazionale.

Tenere presente che, anche se è possibile creare più istanze dell'oggetto dispositivo nell'applicazione, tutti gli oggetti usati in una particolare composizione devono essere creati dallo stesso oggetto dispositivo, con un'unica eccezione: è possibile combinare oggetti visivi da oggetti dispositivo diversi nello stesso albero visuale. In questo caso, DirectComposition considera la struttura ad albero visuale come di consueto, ad eccezione del fatto che le modifiche apportate a un oggetto visivo specifico nell'albero diventano effettive solo quando il metodo Commit viene chiamato sull'oggetto dispositivo che ha creato l'oggetto visivo.

La possibilità di usare oggetti visivi di dispositivi diversi nella stessa struttura ad albero visuale consente a più thread di creare e modificare una singola struttura ad albero visuale mantenendo due dispositivi indipendenti che possono essere usati per eseguire il commit delle modifiche in modo asincrono. Per altre informazioni, vedere Alberi visivi tra dispositivi.

Finestra di destinazione della composizione

Una struttura ad albero visuale deve essere associata a una finestra prima che uno degli oggetti visivi dell'albero possa essere visualizzato sullo schermo. La finestra, denominata finestra di destinazione della composizione, può essere una finestra di primo livello o una finestra figlio. Inoltre, la finestra di destinazione della composizione può essere una finestra a più livelli; ovvero può avere lo stile della finestra WS_EX_LAYERED .

DirectComposition consente a un'applicazione di associare un massimo di due alberi visivi a ogni finestra. Gli alberi visivi includono uno composto sopra la finestra stessa, ma dietro tutte le finestre figlio della finestra e un'altra composta sopra la finestra e sopra le finestre figlio. In altre parole, ogni finestra ha quattro livelli concettuali e tutti i livelli vengono ritagliati nell'area visibile della finestra di destinazione. La figura seguente mostra i quattro livelli concettuali di una finestra.

livelli concettuali di una finestra

Composizione transazionale

DirectComposition usa un modello transazionale in cui si crea un set batch di modifiche a un oggetto visivo e quindi si esegue il commit del set su DirectComposition per l'elaborazione contemporaneamente. È possibile modificare lo stesso oggetto visivo DirectComposition ed eseguire il commit delle modifiche per qualsiasi numero di volte. Quando Desktop Window Manager (DWM) preleva i batch, raccoglie tutti i batch in sospeso e li applica al frame successivo nell'ordine in cui è stato eseguito il commit.

È garantito che tutte le modifiche all'interno di un singolo commit vengano applicate a un singolo frame. Poiché DWM raccoglie batch una sola volta per ogni fotogramma, è possibile modificare qualsiasi oggetto specifico una sola volta per fotogramma. I commit successivi che modificano oggetti diversi potrebbero essere applicati anche al frame corrente, ma DirectComposition non garantisce che le modifiche si verificheranno nello stesso frame.

I metodi IDCompositionSurface::BeginDraw e IDCompositionSurface::EndDraw consentono di sincronizzare gli aggiornamenti del rendering con gli aggiornamenti visivi. Ad esempio, è possibile chiamare IDCompositionSurface::BeginDraw, aggiornare le proprietà OffsetX e Clip di un oggetto visivo, chiamare IDCompositionDevice::Commit, disegnare contenuto con Microsoft DirectX e quindi chiamare IDCompositionSurface::EndDraw. In questo caso, Microsoft DirectComposition garantisce che il contenuto bitmap e le proprietà visive vengano aggiornate contemporaneamente.

Creazione di batch

È possibile eseguire il commit di più modifiche allo stesso oggetto visivo o più modifiche a oggetti visivi diversi all'interno dello stesso frame. Quando si apportano più modifiche allo stesso oggetto visivo all'interno dello stesso fotogramma, tenere presente quanto segue:

  • Se si apportano più modifiche alla stessa proprietà di un oggetto visivo, viene applicata solo l'ultima modifica. Ad esempio, se si imposta l'opacità su 0, quindi su 0.5 e infine su 1.0, all'oggetto visivo viene applicata solo un'opacità pari a 1.0.

  • Se si modificano più proprietà dello stesso oggetto visivo, DirectComposition applica prima le modifiche all'oggetto visivo e quindi a qualsiasi oggetto visivo figlio. Le proprietà vengono applicate nell'ordine seguente indipendentemente dall'ordine in cui vengono specificate:

    1. Offset
    2. Trasformazione
    3. Ritaglia
    4. Effetto

    La figura seguente mostra il risultato dell'applicazione di tutte e quattro le proprietà a un oggetto visivo.

    risultato dell'applicazione di tutte e quattro le proprietà a un oggetto visivo

    Tenere presente che tutte le modifiche vengono applicate all'oggetto visivo contemporaneamente all'interno del contesto dello stesso frame. Ciò significa che, dal punto di vista dell'utente, le modifiche apportate all'oggetto visivo si verificano immediatamente.

  • Per la proprietà Transform, è possibile usare IDCompositionDevice::CreateTransformGroup per creare un gruppo di trasformazioni da applicare a un oggetto visivo contemporaneamente. DirectComposition applica le trasformazioni nell'ordine specificato.

  • Per la proprietà Effect, è possibile utilizzare IDCompositionEffectGroup per applicare un gruppo di effetti. DirectComposition applica gli effetti nell'ordine specificato. Inoltre, le trasformazioni della prospettiva 3D comportano l'appiattimento della struttura ad albero visuale dopo l'applicazione di tutte le trasformazioni 3D nell'oggetto visivo corrente. Ciò garantisce che l'oggetto visivo risultante sia il più vicino possibile a 3D.

Sincronizzazione

L'applicazione può chiamare DirectComposition da più thread contemporaneamente. L'ordine di esecuzione è garantito per le chiamate sequenziali, ma non per le chiamate simultanee. Ad esempio, se il thread A modifica un oggetto visivo e il thread B esegue il commit del batch contemporaneamente, non viene definito se tale modifica visiva viene inclusa nel batch di cui è stato eseguito il commit o se avvia un nuovo batch. D'altra parte, se l'applicazione usa altri meccanismi di sincronizzazione per garantire che un metodo venga chiamato prima dell'altro, DirectComposition rispetta l'ordine di chiamata e li elabora come se entrambe le chiamate fossero state eseguite in tale ordine da un singolo thread.

Alberi visivi tra dispositivi

Gli oggetti DirectComposition non sono associati a thread; è possibile usare più thread per modificare lo stesso set di oggetti. Tuttavia, tenere presente i problemi seguenti durante la condivisione dello stesso oggetto dispositivo.

  • Entrambi i thread devono essere in grado di chiamare IDCompositionDevice::Commit. Se solo uno dei thread chiama IDCompositionDevice::Commit, l'altro thread non può eseguire il commit delle modifiche apportate a DirectComposition.
  • Il comportamento transazionale potrebbe andare perso se un thread chiama IDCompositionDevice::Commit mentre l'altro thread sta ancora apportando modifiche che devono far parte della stessa transazione.

Se è necessario eseguire il commit di più transazioni simultanee in DirectComposition, è necessario usare più oggetti dispositivo, possibilmente da più thread. In questo scenario, la stessa struttura ad albero visuale viene condivisa da entrambi gli oggetti dispositivo e ogni oggetto dispositivo esegue il commit delle proprie transazioni.

La figura seguente mostra una struttura ad albero visuale condivisa da due oggetti dispositivo. Gli oggetti visivi 1, 2, 4 e 5 sono di proprietà di un dispositivo o dell'altro, ma l'oggetto visivo 3 è condiviso da entrambi i dispositivi e può quindi essere usato per connettere due sottoalberi in un unico albero visivo più grande. La condivisione dell'albero visuale consente di modificare i due dispositivi da due thread diversi in modo asincrono.

struttura ad albero visuale condivisa da due dispositivi

Per illustrare l'utilità della condivisione di una struttura ad albero visuale tra due dispositivi, prendere in considerazione un'architettura che abilita l'input tocco a bassa latenza. L'architettura può usare due thread, uno che gestisce la maggior parte delle attività dell'interfaccia utente e un secondo thread dedicato all'elaborazione degli eventi di input tocco. Il thread tocco aggiorna la trasformazione di un oggetto visivo specifico in base al movimento di input dell'utente. Aggiornando la trasformazione, il thread tocco può rendere l'intero sottoalbero sotto tale oggetto visivo, seguire il dito dell'utente, aumentare o ridurre le prestazioni man mano che l'utente esegue un movimento multitocco e così via. Il thread dell'interfaccia utente mantiene la proprietà della maggior parte dell'albero di composizione, con il thread tocco proprietario solo dei pochi oggetti visivi contrassegnati per la risposta tocco asincrona. La figura seguente mostra una versione semplificata di tale albero di composizione:

una struttura ad albero visuale condivisa tra un thread dell'interfaccia utente e un thread di tocco

In genere, il thread dell'interfaccia utente modifica solo gli oggetti visivi proprietari esclusivamente e il thread tocco modifica solo l'oggetto visivo condiviso. L'unica eccezione si verifica quando si crea o si distrugge un sottoalbero abilitato per il tocco.

IDCompositionSurface::BeginDraw

IDCompositionSurface::EndDraw

IDCompositonDevice::Commit

Concetti relativi a DirectComposition