Graphismes

Icône HAL des graphismes Android

Le framework Android propose diverses API de rendu graphique 2D et 3D qui interagissent avec les implémentations des pilotes graphiques par les fabricants. Il est donc important de bien comprendre le fonctionnement de ces API à un niveau supérieur. Cette page présente la couche d'abstraction matérielle (HAL) graphique sur laquelle ces pilotes sont basés. Avant de poursuivre cette section, familiarisez-vous avec les termes suivants :

canvas (terme générique), Canvas (élément d'API)
Un canevas est une surface de dessin qui gère la composition des bits réels par rapport à un bitmap ou un objet Surface. La classe Canvas comporte des méthodes de dessin informatique standard pour les bitmaps, les lignes, les cercles, les rectangles, le texte, etc., et est liée à un bitmap ou à une surface. Un canevas est le moyen le plus simple et le plus facile de dessiner des objets 2D à l'écran. La classe de base est Canvas.
drawable
Un élément graphique est une ressource visuelle compilée qui peut être utilisée comme arrière-plan, titre ou autre partie de l'écran. Un élément graphique est généralement chargé dans un autre élément d'UI, par exemple en tant qu'image de fond. Un élément drawable ne peut pas recevoir d'événements, mais il attribue diverses autres propriétés telles que l'état et la planification, pour activer les sous-classes telles que les objets d'animation ou les bibliothèques d'images. De nombreux objets drawable sont chargés à partir de fichiers de ressources drawable (fichiers XML ou bitmap décrivant l'image). Les ressources drawables sont compilées en sous-classes de android.graphics.drawable. Pour en savoir plus sur les drawables et autres ressources, consultez Présentation des ressources d'application.
ressource de mise en page
Une ressource de mise en page est un fichier XML qui décrit la mise en page d'un écran d'activité. Pour en savoir plus, consultez Ressource de mise en page.
nine-patch (9-patch, NinePatch)
Une image Nine-Patch est une ressource bitmap redimensionnable qui peut être utilisée pour les arrière-plans ou d'autres images sur l'appareil. Pour en savoir plus, consultez Nine-patch.
OpenGL ES
OpenGL ES est une API multiplate-forme permettant le rendu de graphismes 2D et 3D. Android fournit des bibliothèques OpenGL ES pour le rendu 3D avec accélération matérielle. Pour le rendu 2D, un canevas est l'option la plus simple. OpenGL ES est disponible dans le kit de développement natif (NDK) Android. Les packages android.opengl et javax.microedition.khronos.opengles exposent la fonctionnalité OpenGL ES.
surface (terme générique), Surface (élément d'API)
Une surface représente un bloc de mémoire qui est composé sur l'écran. Une surface contient un canevas pour le dessin et fournit diverses méthodes d'assistance pour dessiner des calques et redimensionner l'objet Surface. Utilisez la classe SurfaceView au lieu de la classe Surface directement.
vue de surface (terme générique), SurfaceView (élément d'API)
Une vue de surface est un objet View qui encapsule un objet Surface pour le dessin et expose des méthodes permettant de spécifier sa taille et son format de manière dynamique. Une surface view permet de dessiner indépendamment du thread UI pour les opérations gourmandes en ressources, telles que les jeux ou les aperçus de caméras, mais elle utilise de la mémoire supplémentaire. Une surface view est compatible avec les graphiques canvas et OpenGL ES. La classe de base d'un objet SurfaceView est SurfaceView.
thème
Un thème est un ensemble de propriétés, telles que la taille du texte et la couleur de l'arrière-plan, regroupées pour définir différents paramètres d'affichage par défaut. Android fournit quelques thèmes standards, listés dans R.style et précédés de Theme_.
view (terme générique), View (élément d'API)
Une vue dessine une zone rectangulaire à l'écran et gère les événements de clic, de frappe et autres événements d'interaction. La classe View est la classe de base pour la plupart des composants de mise en page d'un écran d'activité ou de boîte de dialogue, tels que les zones de texte et les fenêtres. Un objet View reçoit des appels de son objet parent (voir ViewGroup) pour se dessiner et informe son objet parent de sa taille et de son emplacement préférés, qui peuvent ne pas être respectés par le parent. Pour en savoir plus, consultez View.
afficher le groupe (terme générique), ViewGroup (élément d'API)
Un groupe de vues regroupe un ensemble de vues enfants. Le groupe de vues est responsable de la décision concernant l'emplacement et la taille des vues enfants, ainsi que de l'appel de chacune d'elles pour qu'elles se dessinent elles-mêmes le cas échéant. Certains groupes de vues sont invisibles et ne servent qu'à la mise en page, tandis que d'autres ont une UI intrinsèque, comme une zone de liste à défilement. Les groupes de vues se trouvent dans le package android.widget, mais étendent la classe ViewGroup.
hiérarchie des vues
Une hiérarchie de vues est un arrangement d'objets de vue et de groupe de vues qui définit l'interface utilisateur pour chaque composant d'une application. La hiérarchie se compose de groupes de vues qui contiennent une ou plusieurs vues ou groupes de vues enfants. Vous pouvez obtenir une représentation visuelle d'une hiérarchie de vues pour le débogage et l'optimisation à l'aide de Hierarchy Viewer fourni avec le SDK Android.
Vulkan
Vulkan est une API multiplate-forme simple d'utilisation pour les graphismes 3D hautes performances.
widget
Un widget fait partie d'un ensemble de sous-classes de vue entièrement implémentées qui affichent des éléments de formulaire et d'autres composants d'UI, tels qu'une zone de texte ou un menu pop-up. Étant donné qu'un widget est entièrement implémenté, il gère lui-même la mesure, le dessin et la réponse aux événements d'écran. Les widgets se trouvent dans le package android.widget.
fenêtre (terme générique), Window (élément d'API)
Dans une application Android, une fenêtre est un objet dérivé de la classe abstraite Window qui spécifie les éléments d'une fenêtre générique, tels que l'apparence, le texte de la barre de titre, ainsi que l'emplacement et le contenu des menus. Les boîtes de dialogue et les activités utilisent une implémentation de la classe Window pour afficher un objet Window. Vous n'avez pas besoin d'implémenter la classe Window ni d'utiliser des fenêtres dans votre application.

Les développeurs d'applications dessinent des images à l'écran de trois manières : avec Canvas, OpenGL ES ou Vulkan.

Composants graphiques Android

Quelle que soit l'API de rendu utilisée par les développeurs, tout est rendu sur une surface. La surface représente le côté producteur d'une file d'attente de tampon qui est souvent consommée par SurfaceFlinger. Chaque fenêtre créée sur la plate-forme Android est soutenue par une surface. Toutes les surfaces visibles affichées sont composées sur l'écran par SurfaceFlinger.

Le schéma suivant montre comment les principaux composants fonctionnent ensemble :

composants de rendu d'image

Figure 1 : Mode d'affichage des surfaces.

Les principaux composants sont décrits dans les sections suivantes.

Producteurs de flux d'images

Un producteur de flux d'images peut être n'importe quel élément qui produit des tampons graphiques pour la consommation. Il peut s'agir, par exemple, des décodeurs vidéo OpenGL ES, Canvas 2D et mediaserver.

Consommateurs de flux d'images

Le consommateur le plus courant de flux d'images est SurfaceFlinger, le service système qui consomme les surfaces actuellement visibles et les compose sur l'écran à l'aide des informations fournies par le gestionnaire de fenêtres. SurfaceFlinger est le seul service qui peut modifier le contenu de l'écran. SurfaceFlinger utilise OpenGL et le Hardware Composer (HWC) pour composer un groupe de surfaces.

D'autres applications OpenGL ES peuvent également consommer des flux d'images, comme l'application de caméra qui consomme un flux d'images d'aperçu de caméra. Les applications non GL peuvent également être des consommateurs, par exemple la classe ImageReader.

Hardware Composer

Abstraction matérielle pour le sous-système d'affichage. SurfaceFlinger peut déléguer certains travaux de composition au HWC pour décharger OpenGL et le GPU. SurfaceFlinger agit comme un autre client OpenGL ES. Ainsi, lorsque SurfaceFlinger compose activement un ou deux tampons dans un troisième, par exemple, il utilise OpenGL ES. Cela permet de réduire la consommation d'énergie par rapport à une situation où le GPU effectue tous les calculs.

Le HAL du compositeur matériel effectue l'autre moitié du travail et constitue le point central de tout le rendu graphique Android. Le HWC doit prendre en charge les événements, dont VSync (et hotplug pour la prise en charge HDMI plug-and-play).

Gralloc

L'allocateur de mémoire graphique (Gralloc) est nécessaire pour allouer la mémoire demandée par les producteurs d'images. Pour en savoir plus, consultez BufferQueue et Gralloc.

Flux de données

Le diagramme suivant représente le pipeline graphique Android :

Flux de données graphiques

Figure 2. Flux de données graphiques dans Android.

Les objets de gauche sont des renderers qui produisent des tampons graphiques, tels que l'écran d'accueil, la barre d'état et l'UI système. SurfaceFlinger est le compositeur et HWC est le compositeur.

BufferQueue

Les BufferQueues assurent la cohésion entre les composants graphiques Android. Il s'agit d'une paire de files d'attente qui servent d'intermédiaire dans le cycle constant de tampons du producteur au consommateur. Une fois que les producteurs ont transmis leurs tampons, SurfaceFlinger est responsable de la composition de l'ensemble sur l'écran.

Le schéma suivant illustre le processus de communication BufferQueue :

Processus de communication BufferQueue

Figure 3. Processus de communication BufferQueue.

BufferQueue contient la logique qui relie les producteurs de flux d'images et les consommateurs de flux d'images. Par exemple, les aperçus de caméra produits par le HAL de la caméra ou les jeux OpenGL ES. Voici quelques exemples de consommateurs d'images : SurfaceFlinger ou une autre application qui affiche un flux OpenGL ES, comme l'application de l'appareil photo qui affiche le viseur de la caméra.

BufferQueue est une structure de données qui combine un pool de mémoire tampon avec une file d'attente et utilise la communication entre processus (IPC) Binder pour transmettre les tampons entre les processus. L'interface du producteur, ou ce que vous transmettez à une personne qui souhaite générer des tampons graphiques, est IGraphicBufferProducer (qui fait partie de SurfaceTexture). BufferQueue est souvent utilisé pour effectuer le rendu sur une surface et consommer avec un GL Consumer, entre autres tâches.

BufferQueue peut fonctionner dans trois modes différents :

mode de type synchrone
Par défaut, BufferQueue fonctionne en mode synchrone, dans lequel chaque tampon provenant du producteur est transmis au consommateur. Dans ce mode, aucun tampon n'est supprimé. Si le producteur est trop rapide et crée des tampons plus vite qu'ils ne sont vidés, il se bloque et attend des tampons libres.
mode non bloquant
BufferQueue peut également fonctionner en mode non bloquant, où il génère une erreur au lieu d'attendre un tampon dans ces cas. Dans ce mode, aucun tampon n'est jamais supprimé. Cela permet d'éviter les impasses potentielles dans les logiciels d'application qui ne comprennent pas les dépendances complexes du framework graphique.
mode Suppression
BufferQueue peut être configuré pour supprimer les anciens tampons au lieu de générer des erreurs ou d'attendre. Par exemple, si vous effectuez un rendu GL dans une vue de texture et que vous dessinez aussi rapidement que possible, les tampons doivent être supprimés.

Pour effectuer la plupart de ces tâches, SurfaceFlinger agit comme un client OpenGL ES. Ainsi, lorsque SurfaceFlinger compose activement un ou deux tampons dans un troisième, par exemple, il utilise OpenGL ES.

La HAL Hardware Composer effectue l'autre moitié du travail. Cette HAL sert de point central pour tout le rendu graphique Android.