I livelli compositi dell'HWC (Hardware Composer (HWC)) compositi da SurfaceFlinger, che riduce la quantità di composizione di OpenGL ES (GLES) e le prestazioni della GPU.
HWC astrae oggetti come overlay e blitter 2D in composti superfici e comunica con apparecchiature specializzate per la composizione di finestre finestre composte. Utilizza HWC per le finestre composte anziché SurfaceFlinger composito con la GPU. La maggior parte delle GPU non è ottimizzata per composizione e quando la GPU compone livelli SurfaceFlinger, le app non possono utilizzare la GPU per il proprio rendering.
Le implementazioni HWC dovrebbero supportare:
- Almeno quattro overlay:
- Barra di stato
- Barra di sistema
- App
- Sfondo
- Livelli più grandi dello schermo (ad esempio, uno sfondo)
- Combinazione alfa premoltiplicata simultanea per pixel alfa e per piano combinazione alpha
- Percorso hardware per la riproduzione di video protetti
- Ordine di imballaggio RGBA, formati YUV e tiling, swizzling e passo passo proprietà
Per implementare HWC:
- Implementa un HWC non operativo e invia tutto il lavoro di composizione a GLES.
- Implementa un algoritmo per delegare la composizione all'HWC in modo incrementale. Ad esempio, delega solo le prime tre o quattro piattaforme all'overlay hardware dell'HWC.
- Ottimizzare l'HWC. Ecco alcuni esempi:
- La selezione di piattaforme che massimizzano il carico tolto dalla GPU e e le invia all'HWC.
- Rilevamento dell'aggiornamento dello schermo in corso. In caso contrario, delega in GLES anziché in HWC per risparmiare energia. Quando la schermata si aggiorna di nuovo, continua a scaricare la composizione sull'HWC.
- Prepararsi a casi d'uso comuni come:
- La schermata Home, che include la barra di stato, la barra di sistema, finestra e sfondi animati
- Giochi a schermo intero in modalità verticale e orizzontale
- Video a schermo intero con sottotitoli codificati e controllo della riproduzione
- Riproduzione di video protetti
- Multi-finestra schermo diviso
Primitive HWC
HWC fornisce due primitive, layer e display, per rappresentare le opere di composizione e la sua interazione con l'hardware del display. La HWC offre anche il controllo su VSYNC e un callback a SurfaceFlinger. per inviare una notifica quando si verifica un evento VSYNC.
Interfaccia HIDL
Android 8.0 e versioni successive utilizza un
Interfaccia HIDL chiamata Composer HAL per
IPC binderizzato tra HWC e SurfaceFlinger. L'HAL di Composer sostituisce l'interfaccia hwcomposer2.h
precedente. Se i fornitori forniscono un HAL Composer
di HWC, Composer HAL accetta direttamente le chiamate HIDL da
SurfaceFlinger. Se i fornitori forniscono un'implementazione legacy di HWC, Composer
HAL carica i puntatori delle funzioni da hwcomposer2.h
,
deviare le chiamate HIDL in chiamate del puntatore di funzione.
HWC fornisce funzioni per determinare le proprietà di una data visualizzazione; a Passa da una configurazione all'altra (ad esempio 4K o 1080p) risoluzione) e modalità colore (come colore nativo o vero sRGB); e per attivare il display viene acceso, spento o in modalità a basso consumo, se supportata.
Puntatori di funzione
Se i fornitori implementano direttamente Composer HAL, SurfaceFlinger chiama le sue funzioni
tramite HIDL IPC. Ad esempio, per creare un livello, SurfaceFlinger chiama
createLayer()
su Composer HAL.
Se i fornitori implementano l'interfaccia hwcomposer2.h
, HAL di Composer richiama i puntatori di funzione hwcomposer2.h
. Nei commenti hwcomposer2.h
,
si fa riferimento alle funzioni dell'interfaccia HWC con nomi in minuscoloCamelCase che non esistono nell'interfaccia come campi denominati. Quasi tutte le funzioni vengono caricate richiedendo un
puntatore a funzione utilizzando getFunction
fornito da
hwc2_device_t
. Ad esempio, la funzione createLayer
è un puntatore di funzione di tipo HWC2_PFN_CREATE_LAYER
, che
quando il valore enumerato HWC2_FUNCTION_CREATE_LAYER
è
passate a getFunction
.
Per la documentazione dettagliata sulle funzioni HAL di Composer e sul passthrough delle funzioni HWC
vedi composer
. Per la documentazione dettagliata
puntatori alle funzioni HWC, consulta
hwcomposer2.h
Handle per livelli e visualizzazione
Livelli e visualizzazioni vengono manipolati tramite i punti di manipolazione generati da HWC. Gli handle sono opachi per SurfaceFlinger.
Quando SurfaceFlinger crea un nuovo livello, chiama createLayer
,
che restituisce il tipo Layer
per le richieste
o hwc2_layer_t
per le implementazioni passthrough. Quando
SurfaceFlinger modifica una proprietà dello strato, SurfaceFlinger passa
Il valore hwc2_layer_t
nella funzione di modifica appropriata
ed eventuali altre informazioni necessarie per apportare la modifica. La
Il tipo di hwc2_layer_t
è abbastanza grande da contenere un puntatore o un
di Google.
I display fisici vengono creati tramite il collegamento a caldo. Quando un display fisico viene collegato tramite hotplug, l'HWC crea un handle e lo passa a SurfaceFlinger tramite il callback hotplug. I display virtuali vengono creati da SurfaceFlinger chiamando createVirtualDisplay()
per richiedere un display. Se l'HWC
supporta la composizione in display virtuale, restituisce un handle. Quindi, SurfaceFlinger
delega la composizione dell'esposizione all'HWC. Se l'HWC non supporta la composizione del display virtuale, SurfaceFlinger crea l'handle e compone il display.
Operazioni di composizione della visualizzazione
Una volta per VSYNC, SurfaceFlinger si riattiva se ha nuovi contenuti da composito. Questi nuovi contenuti possono essere nuovi buffer di immagini da app o una modifica delle proprietà di uno o più strati. Quando SurfaceFlinger lo attiva:
- Gestisce le transazioni, se presenti.
- Memorizza i nuovi buffer grafici, se presenti.
- Esegue una nuova composizione, se il passaggio 1 o 2 ha comportato una modifica ai contenuti del display.
Per eseguire una nuova composizione, SurfaceFlinger crea e
distrugge gli strati o modifica gli stati dei livelli, a seconda dei casi. Inoltre, si aggiorna
con i loro contenuti attuali, usando chiamate come
setLayerBuffer
o setLayerColor
. Dopo che tutti i livelli vengono
aggiornato, SurfaceFlinger chiama validateDisplay
, che indica
la HWC per esaminare lo stato degli strati e determinare come la composizione
procedere. Per impostazione predefinita, SurfaceFlinger tenta di configurare ogni livello in modo che venga composto dall'HWC. Tuttavia, in alcune circostanze, SurfaceFlinger compone i livelli tramite il fallback della GPU.
Dopo la chiamata a validateDisplay
, SurfaceFlinger chiama
getChangedCompositionTypes
per vedere se l'HWC
desidera modificare uno qualsiasi dei tipi di composizione dei livelli prima di eseguire
composizione. Per accettare le modifiche, SurfaceFlinger chiama
acceptDisplayChanges
.
Se alcuni strati sono contrassegnati per la composizione di SurfaceFlinger, SurfaceFlinger
le compone nel buffer di destinazione. SurfaceFlinger chiama quindi
setClientTarget
per trasferire il buffer al display in modo che
il buffer può essere visualizzato sullo schermo o ulteriormente combinato con strati
non sono state contrassegnate per la composizione SurfaceFlinger. Se non è contrassegnato nessun livello
Composizione SurfaceFlinger, SurfaceFlinger ignora la fase della composizione.
Infine, SurfaceFlinger chiama presentDisplay
per indicare
la HWC per completare il processo di composizione e mostrare il risultato finale.
Più display
Android 10 supporta più display fisici. Durante la progettazione di un'implementazione HWC destinata all'uso su Android 7.0 e superiore, esistono alcune restrizioni non presenti nella definizione di HWC:
- Si presume che esista esattamente un display interno. L'interfaccia è il display riportato dalla presa di posizione iniziale durante avvio. Una volta collegato a caldo il display interno non può la disconnessione.
- Oltre al display interno, potrebbe essere collegato a caldo un numero qualsiasi di display esterni
durante il normale funzionamento del dispositivo. Il framework presuppone che tutti
i connettori a caldo dopo il primo display interno sono display esterni, quindi se
vengono aggiunti display interni, sono classificati erroneamente come
Display.TYPE_HDMI
anzichéDisplay.TYPE_BUILT_IN
.
Le operazioni SurfaceFlinger descritte in precedenza vengono eseguite per display, vengono eseguite in sequenza per tutte le visualizzazioni attive anche se i contenuti di un solo display vengono aggiornati.
Ad esempio, se il display esterno viene aggiornato, la sequenza è:
// In Android 9 and lower: // Update state for internal display // Update state for external display validateDisplay(<internal display>) validateDisplay(<external display>) presentDisplay(<internal display>) presentDisplay(<external display>) // In Android 10 and higher: // Update state for internal display // Update state for external display validateInternal(<internal display>) presentInternal(<internal display>) validateExternal(<external display>) presentExternal(<external display>)
Composizione del display virtuale
La composizione del display virtuale è simile a quella del display esterno composizione. La differenza tra composizione in visualizzazione virtuale e fisica composizione display è che i display virtuali inviano l'output a un buffer Gralloc anziché sullo schermo. Hardware Composer (HWC) scrive l'output in un buffer, fornisce la barriera di completamento e invia il buffer a un consumatore (come codificatore video, GPU, CPU e così via). I display virtuali supportano i formati 2D/blitter si sovrappongono se la pipeline di visualizzazione scrive in memoria.
Modalità
Ogni frame è in una delle tre modalità dopo che SurfaceFlinger chiama il metodo
validateDisplay()
metodo HWC:
- GLES: la GPU compone tutti i livelli, scrivendo direttamente nel buffer di output. Il Centro per la salute e il benessere non è coinvolto nella composizione.
- MIX: la GPU compone alcuni strati alla framebuffer e HWC creano il framebuffer e gli strati rimanenti, scrivere direttamente nel buffer di output.
- HWC: HWC compone tutti i livelli e scrive direttamente nel buffer di output.
Formato di output
I formati di output del buffer del display virtuale dipendono dalla relativa modalità:
- Modalità GLES: il driver EGL imposta il buffer di output
nel formato
dequeueBuffer()
, in genereRGBA_8888
. Il consumer deve essere in grado di accettare il formato di output impostato dal driver o la buffer non può essere letto. - Modalità MIXED e HWC: se il consumatore ha bisogno di CPU
l'accesso, il consumatore imposta il formato. In caso contrario, il formato è
IMPLEMENTATION_DEFINED
e Gralloc imposta il formato migliore in base a con i flag di utilizzo. Ad esempio, Gralloc imposta un formato YCbCr se il consumer è il codificatore video e HWC possono scrivere il formato in modo efficiente.
Recinzioni di sincronizzazione
La sincronizzazione delle recinzioni è un aspetto cruciale della grafica Android di un sistema operativo completo. Le barriere consentono al lavoro della CPU di procedere indipendentemente dal lavoro simultaneo della GPU, il blocco solo quando c'è una vera dipendenza.
Ad esempio, quando un'app invia un buffer in produzione alla GPU, invia anche un oggetto recinto di sincronizzazione. Questo recinto segnala quando La GPU ha terminato di scrivere nel buffer.
L'HWC richiede che la GPU completi la scrittura dei buffer prima che questi vengano visualizzati. Le barriere di sincronizzazione vengono fatte passare attraverso la pipeline grafica con i buffer e segnala quando vengono scritti i buffer. Prima che venga visualizzato un buffer, controlla se la barriera di sincronizzazione è stata segnalata e, in caso affermativo, visualizza buffer.
Per ulteriori informazioni sulle barriere di sincronizzazione, consulta Hardware Composer Integrazione.