Couches et affichages

Les calques et les affichages sont deux primitives qui représentent le travail de composition et les interactions avec le matériel d'affichage.

Couches

Un calque est l’unité de composition la plus importante. Un calque est une combinaison d'une surface et d'une instance de SurfaceControl . Chaque calque possède un ensemble de propriétés qui définissent la manière dont il interagit avec les autres calques. Les propriétés des calques sont décrites dans le tableau ci-dessous.

Propriété Description
Positionnel Définit l'endroit où le calque apparaît sur son affichage. Inclut des informations telles que les positions des bords d'un calque et son ordre Z par rapport aux autres calques (s'il doit être devant ou derrière les autres calques).
Contenu Définit la manière dont le contenu affiché sur le calque doit être présenté dans les limites définies par les propriétés de position. Inclut des informations telles que le recadrage (pour agrandir une partie du contenu afin de remplir les limites du calque) et la transformation (pour afficher le contenu pivoté ou retourné).
Composition Définit la façon dont le calque doit être composé avec d’autres calques. Inclut des informations telles que le mode de fusion et une valeur alpha à l'échelle du calque pour la composition alpha .
Optimisation Fournit des informations qui ne sont pas strictement nécessaires pour composer correctement la couche, mais qui peuvent être utilisées par le périphérique Hardware Composer (HWC) pour optimiser la manière dont il effectue la composition. Inclut des informations telles que la région visible du calque et la partie du calque qui a été mise à jour depuis l’image précédente.

Affichages

Un affichage est une autre unité importante de composition. Un système peut avoir plusieurs affichages et des affichages peuvent être ajoutés ou supprimés pendant les opérations normales du système. Des affichages sont ajoutés/supprimés à la demande du HWC ou à la demande du cadre. Le périphérique HWC demande l'ajout ou la suppression d'écrans lorsqu'un écran externe est connecté ou déconnecté du périphérique, ce que l'on appelle hotplugging . Les clients demandent des affichages virtuels , dont le contenu est restitué dans un tampon hors écran plutôt que dans un affichage physique.

Affichages virtuels

SurfaceFlinger prend en charge un écran interne (intégré au téléphone ou à la tablette), des écrans externes (tels qu'un téléviseur connecté via HDMI) et un ou plusieurs écrans virtuels qui rendent la sortie composite disponible au sein du système. Les écrans virtuels peuvent être utilisés pour enregistrer l’écran ou envoyer l’écran sur un réseau. Les images générées pour un affichage virtuel sont écrites dans une BufferQueue.

Les écrans virtuels peuvent partager le même ensemble de couches que l'écran principal (la pile de couches) ou avoir leur propre ensemble. Il n'y a pas de VSYNC pour un affichage virtuel, donc le VSYNC pour l'affichage interne déclenche la composition pour tous les affichages.

Sur les implémentations HWC qui les prennent en charge, les écrans virtuels peuvent être composés avec OpenGL ES (GLES), HWC ou à la fois GLES et HWC. Sur les implémentations non prises en charge, les affichages virtuels sont toujours composés à l'aide de GLES.

Étude de cas : enregistrement d'écran

La commande screenrecord permet à l'utilisateur d'enregistrer tout ce qui apparaît à l'écran sous forme de fichier .mp4 sur le disque. Pour mettre en œuvre cela, le système reçoit des images composites de SurfaceFlinger, les écrit dans l'encodeur vidéo, puis écrit les données vidéo codées dans un fichier. Les codecs vidéo sont gérés par un processus distinct ( mediaserver ), de sorte que de gros tampons graphiques doivent se déplacer dans le système. Pour rendre les choses plus difficiles, l'objectif est d'enregistrer une vidéo à 60 ips en pleine résolution. La clé pour que cela fonctionne efficacement est BufferQueue.

La classe MediaCodec permet à une application de fournir des données sous forme d'octets bruts dans des tampons ou via une surface. Lorsque screenrecord demande l'accès à un encodeur vidéo, le processus mediaserver crée une BufferQueue, se connecte au côté consommateur, puis renvoie le côté producteur à screenrecord en tant que surface.

L'utilitaire screenrecord demande ensuite à SurfaceFlinger de créer un affichage virtuel qui reflète l'affichage principal (c'est-à-dire qu'il comporte toutes les mêmes couches) et lui demande d'envoyer à la surface la sortie provenant du processus mediaserver . Dans ce cas, SurfaceFlinger est le producteur de tampons plutôt que le consommateur.

Une fois la configuration terminée, screenrecord se déclenche lorsque les données codées apparaissent. Au fur et à mesure que les applications dessinent, leurs tampons sont transférés vers SurfaceFlinger, qui les regroupe en un seul tampon envoyé directement à l'encodeur vidéo dans le processus mediaserver . Les images complètes ne sont jamais vues par le processus screenrecord . En interne, le processus mediaserver a sa propre façon de déplacer les tampons qui transmet également les données par handle, minimisant ainsi la surcharge.

Étude de cas : simuler des affichages secondaires

Le WindowManager peut demander à SurfaceFlinger de créer un calque visible pour lequel SurfaceFlinger agit en tant que consommateur BufferQueue. Il est également possible de demander à SurfaceFlinger de créer un affichage virtuel, pour lequel SurfaceFlinger agit en tant que producteur de BufferQueue.

Si vous connectez un affichage virtuel à un calque visible, une boucle fermée est créée à l'endroit où l'écran composé apparaît dans une fenêtre. Cette fenêtre fait désormais partie de la sortie composite, donc lors de la prochaine actualisation, l'image composite à l'intérieur de la fenêtre affiche également le contenu de la fenêtre. Pour voir cela en action, activez les options du développeur dans Paramètres , sélectionnez Simuler les affichages secondaires et activez une fenêtre. Pour voir les affichages secondaires en action, utilisez screenrecord pour capturer l'acte d'activer l'affichage, puis lisez-le image par image.