Gli oggetti Surface consentono alle app di eseguire il rendering delle immagini da presentare sugli schermi. Le interfacce SurfaceHolder consentono alle app di modificare e controllare le superfici.
Superficie
Una superficie è un'interfaccia per un produttore per scambiare buffer con un consumatore.
Il BufferQueue per una superficie di visualizzazione è in genere configurato per il triplo buffer. I buffer vengono allocati su richiesta, quindi se il produttore genera buffer abbastanza lentamente, ad esempio a 30 fps su un display a 60 fps, potrebbero esserci solo due buffer allocati nella coda. L'allocazione dei buffer su richiesta aiuta a ridurre al minimo il consumo di memoria. È possibile visualizzare un riepilogo dei buffer associati a ogni livello nell'output di dumpsys SurfaceFlinger
.
La maggior parte dei client esegue il rendering su superfici utilizzando OpenGL ES o Vulkan . Tuttavia, alcuni client eseguono il rendering su superfici utilizzando una tela.
Rendering su tela
L'implementazione della tela è fornita dalla Skia Graphics Library . Se vuoi disegnare un rettangolo, chiama l'API Canvas, che imposta i byte in un buffer in modo appropriato. Per garantire che un buffer non venga aggiornato da due client contemporaneamente o scritto durante la visualizzazione, bloccare il buffer per accedervi. Utilizzare i seguenti comandi per lavorare con i blocchi della tela:
-
lockCanvas()
blocca il buffer per il rendering sulla CPU e restituisce un Canvas da usare per disegnare. -
unlockCanvasAndPost()
sblocca il buffer e lo invia al compositore. -
lockHardwareCanvas()
blocca il buffer per il rendering sulla GPU e restituisce un'area di disegno da utilizzare per il disegno.
La prima volta che il produttore richiede un buffer da un BufferQueue, il buffer viene allocato e inizializzato a zero. L'inizializzazione è necessaria per evitare di condividere inavvertitamente i dati tra i processi. Tuttavia, se riutilizzi un buffer, i contenuti precedenti sono ancora presenti. Se chiami ripetutamente lockCanvas()
e unlockCanvasAndPost()
senza disegnare nulla, il produttore scorre tra i fotogrammi precedentemente renderizzati.
Il codice di blocco/sblocco della superficie mantiene un riferimento al buffer precedentemente sottoposto a rendering. Se specifichi una regione sporca quando blocchi la superficie, copia i pixel non sporchi dal buffer precedente. SurfaceFlinger o HWC in genere gestiscono il buffer; ma poiché abbiamo solo bisogno di leggere dal buffer, non è necessario attendere l'accesso esclusivo.
Supporto di superficie
Un SurfaceHolder è un'interfaccia utilizzata dal sistema per condividere la proprietà delle superfici con le app. Alcuni client che lavorano con le superfici desiderano un SurfaceHolder, perché le API per ottenere e impostare i parametri delle superfici vengono implementate tramite un SurfaceHolder. Un SurfaceView contiene un SurfaceHolder.
La maggior parte dei componenti che interagiscono con una vista coinvolge un SurfaceHolder. Alcune altre API, come MediaCodec, operano sulla superficie stessa.