Implementare Hardware Composer HAL

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:

  1. Implementa un HWC non operativo e invia tutto il lavoro di composizione a GLES.
  2. 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.
  3. 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:

  1. Gestisce le transazioni, se presenti.
  2. Memorizza i nuovi buffer grafici, se presenti.
  3. 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 genere RGBA_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.
di Gemini Advanced.

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.