Grafica

Icona HAL di Android Graphics

Il framework Android offre una serie di API di rendering grafico per 2D e 3D che interagiscono con le implementazioni dei driver grafici dei produttori, pertanto è importante comprendere bene il funzionamento di queste API a un livello superiore. Questa pagina introduce il livello di astrazioni hardware (HAL) grafico su cui sono basati questi driver. Prima di continuare con questa sezione, acquisisci familiarità con i seguenti termini:

canvas (termine generico), Canvas (elemento API)
Una canvas è una superficie di disegno che gestisce la composizione dei bit effettivi rispetto a una bitmap o a un oggetto Surface. Canvas ha metodi per il disegno di bitmap, linee, cerchi, rettangoli, testo e così via su computer standard ed è associato a una bitmap o una superficie. Una tela è il modo più semplice per disegnare oggetti 2D sullo schermo. La classe di base è Canvas.
drawable
Un drawable è una risorsa visiva compilata che può essere utilizzata come sfondo, titolo o altra parte dello schermo. Un elemento Drawable viene in genere caricato in un altro elemento dell'interfaccia utente, ad esempio come immagine di sfondo. Un drawable non è in grado di ricevere eventi, ma assegna varie altre proprietà, come stato e pianificazione, per attivare sottoclassi come oggetti di animazione o librerie di immagini. Molti oggetti Drawable vengono caricati dai file di risorse Drawable (file XML o bitmap che descrivono l'immagine). Le risorse Drawable vengono compilate in sottoclassi di android.graphics.drawable. Per ulteriori informazioni sugli elementi drawable e su altre risorse, consulta Risorse.
Risorsa di layout
Una risorsa di layout è un file XML che descrive il layout di una schermata dell'attività. Per ulteriori informazioni, consulta la sezione Risorsa layout.
nine-patch (9-patch, NinePatch)
Un nine-patch è una risorsa bitmap ridimensionabile che può essere utilizzata per sfondi o altre immagini sul dispositivo. Per ulteriori informazioni, consulta la sezione Anniversarie.
OpenGL ES
OpenGL ES è un'API multipiattaforma per il rendering di grafica 2D e 3D. Android fornisce librerie OpenGL ES per il rendering 3D con accelerazione hardware. Per il rendering 2D, una tela è l'opzione più semplice. OpenGL ES è disponibile nel Native Development Kit (NDK) per Android. I pacchetti android.opengl e javax.microedition.khronos.opengles espongono la funzionalità OpenGL ES.
surface (termine generico), Surface (elemento API)
Una superficie rappresenta un blocco di memoria che viene composto sullo schermo. Una superficie contiene una tela per il disegno e fornisce vari metodi di assistenza per disegnare i livelli e ridimensionare l'oggetto Surface. Utilizza la classe SurfaceView anziché la classe Surface direttamente.
visualizzazione della superficie (termine generico), SurfaceView (elemento API)
Una visualizzazione di superficie è un oggetto View che racchiude un oggetto Surface per il disegno ed espone metodi per specificarne le dimensioni e il formato in modo dinamico. Una visualizzazione della superficie offre un modo per disegnare indipendentemente dal thread dell'interfaccia utente per operazioni che richiedono molte risorse, come giochi o anteprime della fotocamera, ma utilizza una memoria aggiuntiva. Una visualizzazione della superficie supporta sia la grafica canvas sia quella OpenGL ES. La classe di base per un oggetto SurfaceView è SurfaceView.
theme
Un tema è un insieme di proprietà, come dimensioni del testo e colore di sfondo, raggruppate per definire varie impostazioni di visualizzazione predefinite. Android fornisce alcuni temi standard, elencati in R.style e preceduti da Theme_.
view (termine generico), View (elemento API)
Una visualizzazione disegna un'area rettangolare sullo schermo e gestisce gli eventi di clic, tasti e altre interazioni. La classe View è la classe di base per la maggior parte dei componenti di layout di un'attività o di una schermata di dialogo, come le caselle di testo e le finestre. Un oggetto View riceve chiamate dal suo oggetto principale (vedi ViewGroup) per disegnare se stesso e informa l'oggetto principale sulle sue dimensioni e sulla sua posizione preferite, che potrebbero non essere rispettate dall'oggetto principale. Per ulteriori informazioni, consulta View.
gruppo di visualizzazioni (termine generico), ViewGroup (elemento API)
Un gruppo di visualizzazioni raggruppa un insieme di visualizzazioni secondarie. Il gruppo di visualizzazioni è responsabile di decidere dove devono essere posizionate le visualizzazioni secondarie e le relative dimensioni, nonché di chiamarle ciascuna per disegnare se stessa, se opportuno. Alcuni gruppi di visualizzazione sono invisibili e sono destinati solo al layout, mentre altri hanno un'interfaccia utente intrinseca, ad esempio una casella di elenco con scorrimento. I gruppi di visualizzazione sono nel pacchetto widget ma estendono la classe ViewGroup.
Gerarchia di visualizzazione
Una gerarchia di visualizzazioni è un'organizzazione di oggetti View e ViewGroup che definisce l'interfaccia utente per ogni componente di un'app. La gerarchia è costituita da gruppi di visualizzazioni che contengono una o più visualizzazioni o gruppi di visualizzazioni secondari. Puoi ottenere una rappresentazione visiva di una gerarchia di visualizzazioni per il debugging e l'ottimizzazione utilizzando il Hierarchy Viewer fornito con l'SDK Android.
Vulkan
Vulkan è un'API multipiattaforma a basso overhead per la grafica 3D ad alte prestazioni.
widget
Un widget è uno di un insieme di sottoclassi di visualizzazioni completamente implementate che visualizzano elementi di modulo e altri componenti dell'interfaccia utente, come una casella di testo o un menu popup. Poiché un widget è completamente implementato, gestisce la misurazione, il disegno e la risposta agli eventi sullo schermo. I widget sono nel pacchetto android.widget.
window (termine generico), Window (elemento API)
In un'app per Android, una finestra è un oggetto derivato dalla classe astratta Window che specifica gli elementi di una finestra generica, come l'aspetto, il testo della barra del titolo, la posizione e i contenuti dei menu. Le finestre di dialogo e le attività utilizzano un'implementazione della classe Window per eseguire il rendering di un oggetto Window. Non è necessario implementare la classe Window o utilizzare finestre nell'app.

Gli sviluppatori di app disegnano le immagini sullo schermo in tre modi: con Canvas, OpenGL ES o Vulkan.

Componenti grafici Android

Indipendentemente dall'API di rendering utilizzata dagli sviluppatori, tutto viene visualizzato su una superficie. La superficie rappresenta il lato del produttore di una fila di buffer spesso utilizzata da SurfaceFlinger. Ogni finestra creata sulla piattaforma Android è supportata da una superficie. Tutte le superfici visibili visualizzate vengono composte sul display da SurfaceFlinger.

Il seguente diagramma mostra l'interazione tra i componenti chiave:

componenti di rendering delle immagini

Figura 1. Come vengono visualizzate le superfici.

I componenti principali sono descritti di seguito:

Produttori di stream di immagini

Un produttore di stream di immagini può essere qualsiasi cosa produca buffer grafici per il consumo. Alcuni esempi sono OpenGL ES, Canvas 2D e decodificatori video mediaserver.

Utenti di flussi di immagini

Il consumatore più comune di stream di immagini è SurfaceFlinger, il servizio di sistema che utilizza le superfici attualmente visibili e le compone sul display utilizzando le informazioni fornite dal gestore delle finestre. SurfaceFlinger è l'unico servizio che può modificare i contenuti del display. SurfaceFlinger utilizza OpenGL e il compositore hardware per comporre un gruppo di superfici.

Anche altre app OpenGL ES possono utilizzare stream di immagini, ad esempio l'app Fotocamera che utilizza uno stream di immagini di anteprima della fotocamera. Anche le app non GL possono essere consumatori, ad esempio la classe ImageReader.

Hardware Composer

L'astrazione hardware per il sottosistema di visualizzazione. SurfaceFlinger può delegato alcune operazioni di composizione all'Hardware Composer per scaricare il lavoro da OpenGL e dalla GPU. SurfaceFlinger agisce come un altro client OpenGL ES. Pertanto, quando SurfaceFlinger compone attivamente uno o due buffer in un terzo, ad esempio, utilizza OpenGL ES. In questo modo, il compositing richiede meno potenza rispetto a quando è la GPU a eseguire tutti i calcoli.

L'Hardware Composer HAL esegue l'altra metà del lavoro ed è il punto di riferimento per tutto il rendering grafico di Android. Il compositore hardware deve supportare gli eventi, uno dei quali è VSYNC (un altro è hotplug per il supporto HDMI plug-and-play).

Gralloc

L'allocatore della memoria grafica (Gralloc) è necessario per allocare la memoria richiesta dai produttori di immagini. Per maggiori dettagli, vedi HAL Gralloc.

Flusso di dati

Consulta il seguente diagramma per una rappresentazione della pipeline grafica di Android:

flusso di dati grafici

Figura 2. Flusso di dati grafici tramite Android

Gli oggetti a sinistra sono renderer che producono buffer grafici, come la schermata Home, la barra di stato e l'interfaccia utente di sistema. SurfaceFlinger è il compositore e Hardware Composer è il compositore.

BufferQueue

Le code di buffer forniscono il collegamento tra i componenti grafici di Android. Si tratta di una coppia di code che mediano il ciclo costante dei buffer dal produttore al consumatore. Una volta che i produttori hanno consegnato i propri buffer, SurfaceFlinger è responsabile della composizione di tutto sul display.

Consulta il seguente diagramma per la procedura di comunicazione di BufferQueue.

Processo di comunicazione di BufferQueue

Figura 3. Processo di comunicazione BufferQueue

BufferQueue contiene la logica che lega i produttori e i consumatori di stream di immagini. Alcuni esempi di produttori di immagini sono le anteprime della fotocamera prodotte dall'HAL della fotocamera o dai giochi OpenGL ES. Alcuni esempi di consumatori di immagini sono SurfaceFlinger o un'altra app che mostra uno stream OpenGL ES, come l'app della fotocamera che mostra il mirino della fotocamera.

BufferQueue è una struttura di dati che combina un pool di buffer con una coda e utilizza Binder IPC per passare i buffer tra i processi. L'interfaccia del produttore, ovvero ciò che viene passato a chi vuole generare buffer grafici, è IGraphicBufferProducer (parte di SurfaceTexture). BufferQueue viene spesso utilizzato per eseguire il rendering su una superficie e per il consumo con un consumatore GL, tra le altre attività.

BufferQueue può funzionare in tre diverse modalità:

Modalità simile a sincrona: per impostazione predefinita, BufferQueue opera in una modalità simile a sincrona, in cui ogni buffer in arrivo dal produttore viene inviato al consumatore. In questa modalità non viene mai eliminato alcun buffer. Se il produttore è troppo veloce e crea buffer più velocemente di quanto vengano svuotati, si bloccherà e attenderà buffer liberi.

Modalità non bloccante: BufferQueue può funzionare anche in una modalità non bloccante, in cui genera un errore anziché attendere un buffer in questi casi. Anche in questa modalità non viene mai eliminato alcun buffer. Questo è utile per evitare potenziali deadlock nel software dell'applicazione che potrebbe non comprendere le complesse dipendenze del framework grafico.

Modalità di eliminazione: infine, BufferQueue può essere configurato per eliminare i buffer vecchi anziché generare errori o attendere. Ad esempio, se esegui l'elaborazione GL in una visualizzazione della trama e disegni il più rapidamente possibile, i buffer devono essere eliminati.

Per eseguire la maggior parte di questo lavoro, SurfaceFlinger agisce come un altro client OpenGL ES. Pertanto, quando SurfaceFlinger compone attivamente uno o due buffer in un terzo, ad esempio, utilizza OpenGL ES.

L'HAL Hardware Composer esegue l'altra metà del lavoro. Questo HAL funge da punto centrale per tutto il rendering grafico di Android.