Superficie e SurfaceHolder

Gli oggetti di superficie 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 attraverso la quale un produttore può scambiare buffer con un consumatore.

BufferQueue per una superficie di visualizzazione è in genere configurato per il triplo buffering. I buffer vengono allocati su richiesta, quindi se il produttore genera buffer abbastanza lentamente, ad esempio a 30 fps su uno schermo a 60 fps, potrebbero esserci solo due buffer allocati in coda. L'allocazione dei buffer su richiesta aiuta a ridurre al minimo il consumo di memoria. Puoi vedere un riepilogo dei buffer associati a ogni livello nell'output dumpsys SurfaceFlinger .

La maggior parte dei client esegue il rendering su superfici utilizzando OpenGL ES o Vulkan . Tuttavia, alcuni client eseguono il rendering sulle superfici utilizzando una tela.

Rendering della tela

L'implementazione del canvas è fornita dalla Skia Graphics Library . Se vuoi disegnare un rettangolo, chiami 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 mentre viene visualizzato, bloccare il buffer per accedervi. Utilizza i seguenti comandi per lavorare con i blocchi della tela:

  • lockCanvas() blocca il buffer per il rendering sulla CPU e restituisce una tela da utilizzare per il disegno.
  • unlockCanvasAndPost() sblocca il buffer e lo invia al compositore.
  • lockHardwareCanvas() blocca il buffer per il rendering sulla GPU e restituisce una tela da utilizzare per il disegno.

La prima volta che il produttore richiede un buffer da BufferQueue, il buffer viene allocato e inizializzato a zero. L'inizializzazione è necessaria per evitare la condivisione inavvertita di dati tra processi. Tuttavia, se riutilizzi un buffer, il contenuto precedente sarà ancora presente. Se chiami ripetutamente lockCanvas() e unlockCanvasAndPost() senza disegnare nulla, il produttore passa ciclicamente tra i fotogrammi renderizzati in precedenza.

Il codice di blocco/sblocco della superficie mantiene un riferimento al buffer precedentemente renderizzato. 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é dobbiamo solo leggere dal buffer, non è necessario attendere l'accesso esclusivo.

SurfaceHolder

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 della superficie vengono implementate tramite un SurfaceHolder. Un SurfaceView contiene un SurfaceHolder.

La maggior parte dei componenti che interagiscono con una vista coinvolgono un SurfaceHolder. Alcune altre API, come MediaCodec, operano sulla superficie stessa.