Surface et SurfaceHolder

Les objets de surface permettent aux applications de rendre des images à présenter sur des é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.

La BufferQueue d'une surface d'affichage est généralement configurée pour une triple mise en 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 affichage à 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 en utilisant OpenGL ES ou Vulkan . Cependant, certains clients effectuent le rendu sur des surfaces à l'aide d'un canevas.

Rendu du canevas

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 vous assurer 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 travailler avec les verrous de canevas:

  • lockCanvas() verrouille le tampon pour le rendu sur le CPU et renvoie un Canvas à 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 à une BufferQueue, le tampon est alloué et initialisé à zéro. L'initialisation est nécessaire pour éviter de partager des données par inadvertance entre les 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 en boucle entre les images précédemment rendues.

Le code de verrouillage / déverrouillage de 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, il copie les pixels non sales 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.

SurfaceHolder

Un SurfaceHolder est une interface que le système utilise pour partager la propriété des surfaces avec les applications. Certains clients qui travaillent avec des surfaces veulent un SurfaceHolder, car les API pour obtenir et 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 sur la surface elle-même.