SurfaceFlinger e WindowManager

SurfaceFlinger accetta i buffer, li compone e li invia al display. WindowManager fornisce a SurfaceFlinger buffer e metadati della finestra, che SurfaceFlinger utilizza 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.

Android 10 aggiunge ASurfaceControl, un altro modo in cui SurfaceFlinger può accettare i buffer. ASurfaceControl combina una superficie e un'istanza SurfaceControl in un unico pacchetto di transazioni inviato a SurfaceFlinger. 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, come il tempo di aggancio, i tempi di acquisizione e così via.

La seguente tabella include ulteriori dettagli su ASurfaceControl e sui relativi componenti:

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 il display può essere aggiornato senza tearing. Quando SurfaceFlinger riceve il segnale VSync, scorre l'elenco dei livelli alla ricerca di nuovi buffer. Se SurfaceFlinger trova un nuovo buffer, 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, il livello viene ignorato.

Dopo aver raccolto tutti i buffer per i livelli visibili, SurfaceFlinger chiede all'Hardware Composer (HWC) come deve essere eseguita 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 da applicare al buffer da SurfaceFlinger. 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.