SurfaceFlinger e WindowManager

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

SurfaceFlinger

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

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

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

La tabella seguente descrive ASurfaceControl e i relativi componenti associati:

Componente Descrizione
ASurfaceControl Contiene SurfaceControl e consente a un'app di creare istanze SurfaceControl che corrispondono ai livelli sul display.
Può essere creato come elemento secondario di ANativeWindow o come elemento secondario 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 a un'app informazioni sulle transazioni presentate, ad esempio ora di blocco, tempi di acquisizione e barriera di rilascio precedente, tramite un callback preregistrato.

Sebbene le app possano inviare buffer in qualsiasi momento, SurfaceFlinger si attiva solo per accettare i buffer tra gli aggiornamenti del display, che possono variare a seconda del dispositivo. In questo modo, l'utilizzo della memoria viene ridotto al minimo e si evita lo strappo visibile sullo schermo, che può verificarsi durante l'aggiornamento del display a metà aggiornamento.

Quando il display è tra un aggiornamento e l'altro, invia il segnale VSync a SurfaceFlinger. Il segnale VSync indica che può aggiornare il display senza tearing. 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 aver raccolto tutti i buffer per i livelli visibili, SurfaceFlinger chiede a Hardware Composer (HWC) come deve eseguire la composizione. Se HWC contrassegna il tipo di composizione dei livelli come composizione client, SurfaceFlinger compone questi livelli. Quindi, SurfaceFlinger passa il buffer di output all'HWC.

WindowManager

WindowManager controlla gli oggetti Window, che sono contenitori per gli oggetti View. Gli oggetti Window sono sempre supportati da oggetti Surface. WindowManager gestisce i cicli di vita, gli eventi di input e 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 possa utilizzarli per comporre le superfici sul display.

Pre-rotazione

Molte sovrapposizioni hardware non supportano la rotazione (e anche se lo fanno, richiedono potenza di elaborazione); la soluzione è trasformare il buffer prima che raggiunga SurfaceFlinger. Android supporta un suggerimento per la 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 pre-trasformare il buffer prima che raggiunga SurfaceFlinger, in modo che quando 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 maggiori dettagli, consulta l'interfaccia ANativeWindow definita in system/core/include/system/window.h.