Surface et SurfaceHolder

Les objets de surface permettent aux applications de restituer des images à présenter sur les écrans. Les interfaces SurfaceHolder permettent aux applications de modifier et de contrôler les surfaces.

Surface

Une surface est une interface permettant à un producteur d'échanger des tampons avec un consommateur.

Le BufferQueue d’une surface d’affichage est généralement configuré pour une triple mise en mémoire tampon. Les tampons sont alloués à la demande, donc si le producteur génère des tampons assez lentement, par exemple à 30 ips sur un écran à 60 ips, il se peut qu'il n'y ait que deux tampons alloués dans la file d'attente. L'allocation de tampons à la demande permet de minimiser la consommation de mémoire. Vous pouvez voir un résumé des tampons associés à chaque couche dans la sortie dumpsys SurfaceFlinger .

La plupart des clients effectuent le rendu sur des surfaces utilisant OpenGL ES ou Vulkan . Cependant, certains clients effectuent le rendu sur des surfaces à l'aide d'un canevas.

Rendu sur toile

L'implémentation du canevas est fournie par la bibliothèque graphique Skia . Si vous souhaitez dessiner un rectangle, vous appelez l'API Canvas, qui définit les octets dans un tampon de manière appropriée. Pour garantir qu'un tampon n'est pas mis à jour par deux clients à la fois, ou écrit pendant son affichage, verrouillez le tampon pour y accéder. Utilisez les commandes suivantes pour utiliser les verrous de canevas :

  • lockCanvas() verrouille le tampon pour le rendu sur le processeur et renvoie un canevas à utiliser pour le dessin.
  • unlockCanvasAndPost() déverrouille le tampon et l'envoie au compositeur.
  • lockHardwareCanvas() verrouille le tampon pour le rendu sur le GPU et renvoie un canevas à utiliser pour le dessin.

La première fois que le producteur demande un tampon à un BufferQueue, le tampon est alloué et initialisé à zéro. L'initialisation est nécessaire pour éviter de partager par inadvertance des données entre processus. Cependant, si vous réutilisez un tampon, le contenu précédent est toujours présent. Si vous appelez à plusieurs reprises lockCanvas() et unlockCanvasAndPost() sans rien dessiner, le producteur passe d'une image précédemment rendue à une autre.

Le code de verrouillage/déverrouillage de la surface conserve une référence au tampon précédemment rendu. Si vous spécifiez une région sale lors du verrouillage de la surface, les pixels non sales sont copiés du tampon précédent. SurfaceFlinger ou HWC gèrent généralement le tampon ; mais comme nous n'avons besoin que de lire à partir du tampon, il n'est pas nécessaire d'attendre un accès exclusif.

Support de surface

Un SurfaceHolder est une interface que le système utilise pour partager la propriété des surfaces avec des applications. Certains clients qui travaillent avec des surfaces souhaitent un SurfaceHolder, car les API permettant d'obtenir et de définir les paramètres de surface sont implémentées via un SurfaceHolder. Un SurfaceView contient un SurfaceHolder.

La plupart des composants qui interagissent avec une vue impliquent un SurfaceHolder. Certaines autres API, telles que MediaCodec, fonctionnent en surface elle-même.