SurfaceFlinger e WindowManager

SurfaceFlinger accetta, compone e invia i buffer al display. WindowManager fornisce a SurfaceFlinger i buffer e i metadati della finestra, che SurfaceFlinger utilizza per comporre le superfici sul display.

SurfaceFlinger

SurfaceFlinger può accettare i buffer in due modi: tramite BufferQueue e SurfaceControl o tramite ASurfaceControl.

Un modo in cui SurfaceFlinger accetta i buffer è tramite BufferQueue e SurfaceControl. Quando un'app passa in primo piano, richiede i buffer a WindowManager. WindowManager richiede quindi un livello a SurfaceFlinger. Un livello è una combinazione di una superficie, che contiene BufferQueue, e un'istanza SurfaceControl, che contiene i metadati del livello, come il frame del display. SurfaceFlinger crea il livello e lo invia a WindowManager. WindowManager invia quindi la superficie all'app, ma mantiene l'istanza SurfaceControl per manipolare l'aspetto dell'app sullo schermo.

A partire da Android 10, ASurfaceControl fornisce un altro modo per SurfaceFlinger di accettare i buffer. ASurfaceControl combina una superficie e un'istanza SurfaceControl in un unico pacchetto di transazioni che SurfaceFlinger riceve. ASurfaceControl è associato a un livello, che le app aggiornano tramite le istanze ASurfaceTransaction. Le app ricevono quindi informazioni sulle istanze ASurfaceTransaction tramite callback che passano ASurfaceTransactionStats contenenti informazioni, ad esempio il tempo di blocco e i tempi di acquisizione.

La tabella seguente descrive ASurfaceControl e i relativi componenti:

Componente Descrizione
ASurfaceControl Esegue il wrapping di SurfaceControl e consente a un'app di creare istanze SurfaceControl che corrispondono ai livelli sul display.
Può essere creato come figlio di ANativeWindow o come figlio di un'altra istanza ASurfaceControl.
ASurfaceTransaction Esegue il wrapping di Transaction per consentire al client di modificare le proprietà descrittive di un livello, ad esempio la geometria, e invia i buffer aggiornati a SurfaceFlinger.
ASurfaceTransactionStats Invia informazioni sulle transazioni presentate, ad esempio il tempo di blocco, i tempi di acquisizione e la recinzione di rilascio precedente, a un'app tramite un callback preregistrato.

Sebbene le app possano inviare i buffer in qualsiasi momento, SurfaceFlinger si riattiva solo per accettare i buffer tra gli aggiornamenti del display, che possono variare a seconda del dispositivo. In questo modo si riduce al minimo l'utilizzo della memoria e si evitano strappi visibili sullo schermo, che possono verificarsi durante l'aggiornamento del display a metà aggiornamento.

Quando il display è tra gli aggiornamenti, invia il segnale VSync a SurfaceFlinger. Il segnale VSync indica che può aggiornare il display senza strappi. Quando SurfaceFlinger riceve il segnale VSync, scorre l'elenco dei livelli alla ricerca di nuovi buffer. Se trova un nuovo buffer, SurfaceFlinger lo acquisisce; in caso contrario, continua a utilizzare il buffer acquisito in precedenza. SurfaceFlinger deve sempre visualizzare qualcosa, quindi mantiene un buffer. Se non sono mai stati inviati buffer su un livello, SurfaceFlinger ignora il livello.

Dopo che SurfaceFlinger ha raccolto tutti i buffer per i livelli visibili, chiede a Hardware Composer (HWC) come eseguire la composizione. Se HWC contrassegna il tipo di composizione del livello come composizione del client, SurfaceFlinger compone questi livelli. Quindi, SurfaceFlinger passa il buffer di output a HWC.

WindowManager

WindowManager controlla gli oggetti Window, che sono container per gli oggetti View. Gli oggetti Window sono sempre supportati da Surface oggetti. WindowManager supervisiona i cicli di vita, gli eventi di input e di messa a fuoco, l'orientamento dello schermo, le transizioni, le animazioni, la posizione, le trasformazioni, l'ordine z e molti altri aspetti di una finestra. WindowManager invia tutti i metadati della finestra a SurfaceFlinger in modo che SurfaceFlinger possa utilizzare questi dati per comporre le superfici sul display.

Pre-rotazione

Molte overlay hardware non supportano la rotazione (e anche se lo fanno, consumano potenza di elaborazione); la soluzione è trasformare il buffer prima che raggiunga SurfaceFlinger. Android supporta un suggerimento di query (NATIVE_WINDOW_TRANSFORM_HINT) in ANativeWindow per rappresentare la trasformazione più probabile che SurfaceFlinger applicherà al buffer. I driver GL possono utilizzare questo suggerimento per trasformare preventivamente il buffer prima che raggiunga SurfaceFlinger, in modo che quando il buffer arriva, sia trasformato correttamente.

Ad esempio, quando ricevi un suggerimento per ruotare di 90 gradi, genera e applica una matrice al buffer per evitare che esca dalla fine della pagina. Per risparmiare energia, esegui questa pre-rotazione. Per i dettagli, consulta l'interfaccia ANativeWindow definita in system/core/include/system/window.h.