BufferQueue et Gralloc

La classe BufferQueue connecte les composants qui génèrent des tampons de données graphiques ( producteurs ) aux composants qui acceptent les données pour l'affichage ou un traitement ultérieur ( consommateurs ). Presque tout ce qui déplace les tampons de données graphiques à travers le système repose sur BufferQueue.

L'allocateur de mémoire Gralloc effectue des allocations de tampon et est implémenté via deux interfaces HIDL spécifiques au fournisseur (voir hardware/interfaces/graphics/allocator/ et hardware/interfaces/graphics/mapper/ ). La fonction allocate() prend les arguments attendus (largeur, hauteur, format de pixel) ainsi qu'un ensemble d'indicateurs d'utilisation.

Producteurs et consommateurs de BufferQueue

Les consommateurs créent et possèdent la structure de données BufferQueue et peuvent exister dans des processus différents de ceux de leurs producteurs. Lorsqu'un producteur a besoin d'un tampon, il demande un tampon gratuit à BufferQueue en appelant dequeueBuffer() , en spécifiant la largeur, la hauteur, le format de pixel et les indicateurs d'utilisation des tampons. Le producteur remplit ensuite le tampon et renvoie le tampon dans la file d'attente en appelant queueBuffer() . Ensuite, le consommateur acquiert le tampon avec acquireBuffer() et utilise le contenu du tampon. Lorsque le consommateur a terminé, il renvoie le tampon dans la file d'attente en appelant releaseBuffer() . Le framework de synchronisation contrôle la façon dont les tampons se déplacent dans le pipeline graphique Android.

Certaines caractéristiques du BufferQueue, comme le nombre maximum de tampons qu'il peut contenir, sont déterminées conjointement par le producteur et le consommateur. Cependant, BufferQueue alloue des tampons selon ses besoins. Les tampons sont conservés sauf si les caractéristiques changent ; par exemple, si un producteur demande des tampons d'une taille différente, les anciens tampons sont libérés et de nouveaux tampons sont alloués à la demande.

Le contenu du tampon n'est jamais copié par BufferQueue, car déplacer autant de données est inefficace. Au lieu de cela, les tampons sont toujours transmis par un handle.

Suivre BufferQueue avec Systrace

Pour comprendre comment les tampons graphiques se déplacent, utilisez Systrace , un outil qui enregistre l'activité des appareils sur une courte période de temps. Le code graphique au niveau du système est bien instrumenté, tout comme une grande partie du code du framework d'application concerné.

Pour utiliser Systrace, activez les balises gfx , view et sched . Les objets BufferQueue sont affichés dans la trace. À titre d'exemple, si vous effectuez une trace pendant l'exécution de la vidéo Play de Grafika (SurfaceView) , la ligne intitulée SurfaceView vous indique combien de tampons ont été mis en file d'attente à un moment donné.

La valeur s'incrémente lorsque l'application est active, ce qui déclenche le rendu des images par le décodeur MediaCodec. La valeur décrémente pendant que SurfaceFlinger fonctionne et consomme des tampons. Lors de l'affichage d'une vidéo à 30 ips, la valeur de la file d'attente varie de 0 à 1 car l'affichage à ~60 ips peut suivre la source. SurfaceFlinger ne se réveille que lorsqu'il y a du travail à effectuer, et non 60 fois par seconde. Le système essaie d'éviter le travail et désactive VSYNC si rien ne met à jour l'écran.

Si vous passez à la vidéo Play de Grafika (TextureView) et récupérez une nouvelle trace, vous voyez une ligne intitulée com.android.grafika / com.android.grafika.PlayMovieActivity . Il s'agit de la couche principale de l'interface utilisateur, qui est une autre BufferQueue. Étant donné que TextureView s'affiche dans la couche d'interface utilisateur plutôt que dans une couche distincte, toutes les mises à jour vidéo sont affichées ici.

Gralloc

L'allocateur Gralloc HAL hardware/libhardware/include/hardware/gralloc.h effectue des allocations de tampon via des indicateurs d'utilisation. Les indicateurs d'utilisation incluent des attributs tels que :

  • À quelle fréquence la mémoire sera accédée à partir du logiciel (CPU)
  • À quelle fréquence la mémoire sera accessible à partir du matériel (GPU)
  • Si la mémoire sera utilisée comme texture OpenGL ES (GLES)
  • Si la mémoire sera utilisée par un encodeur vidéo

Par exemple, si le format de tampon d'un producteur spécifie RGBA_8888 pixels et que le producteur indique que le tampon sera accessible à partir d'un logiciel (ce qui signifie qu'une application touchera les pixels du processeur), Gralloc crée un tampon avec 4 octets par pixel dans l'ordre RGBA. Si, à la place, un producteur spécifie que son tampon ne sera accessible qu'à partir du matériel et en tant que texture GLES, Gralloc peut faire tout ce que le pilote GLES veut, comme l'ordre BGRA, les mises en page swizzled non linéaires et les formats de couleurs alternatifs. Permettre au matériel d'utiliser son format préféré peut améliorer les performances.

Certaines valeurs ne peuvent pas être combinées sur certaines plateformes. Par exemple, l'indicateur de l'encodeur vidéo peut nécessiter des pixels YUV, donc l'ajout d'un accès logiciel et la spécification RGBA_8888 échouent.

Le handle renvoyé par Gralloc peut être transmis entre les processus via Binder.

Tampons protégés

L'indicateur d'utilisation Gralloc GRALLOC_USAGE_PROTECTED permet au tampon graphique d'être affiché uniquement via un chemin protégé par le matériel. Ces plans de superposition sont le seul moyen d'afficher le contenu DRM (les tampons protégés par DRM ne sont pas accessibles par SurfaceFlinger ou le pilote OpenGL ES).

La vidéo protégée par DRM ne peut être présentée que sur un plan de superposition. Les lecteurs vidéo prenant en charge le contenu protégé doivent être implémentés avec SurfaceView. Les logiciels exécutés sur du matériel non protégé ne peuvent ni lire ni écrire le tampon ; les chemins protégés par le matériel doivent apparaître sur la superposition Hardware Composer (c'est-à-dire que les vidéos protégées disparaissent de l'affichage si Hardware Composer passe à la composition OpenGL ES).

Pour plus de détails sur le contenu protégé, voir DRM .