Le HAL Hardware Composer (HWC) compose les calques reçus de SurfaceFlinger, ce qui réduit la quantité de composition OpenGL ES (GLES) et du GPU.
Le HWC effectue une abstraction des objets, tels que les superpositions et les blitters 2D, pour composer des surfaces et communique avec du matériel de composition de fenêtre spécialisé pour composer des fenêtres. Utilisez le matériel pour les fenêtres composites au lieu d'avoir Composition SurfaceFlinger avec le GPU La plupart des GPU ne sont pas optimisés pour la composition. Lorsque le GPU compose des calques à partir de SurfaceFlinger, les applications ne peuvent pas utiliser le GPU pour leur propre rendu.
Les implémentations HWC doivent être compatibles avec:
- Au moins quatre superpositions:
<ph type="x-smartling-placeholder">
- </ph>
- Barre d'état
- Barre système
- Application
- Fond d'écran/Arrière-plan
- Calques plus grands que l'écran (par exemple, un fond d'écran)
- Combinaison alpha prémultipliée simultanée par pixel et par plan Alpha Blending
- Chemin matériel pour la lecture vidéo protégée
- Ordre d'empaquetage RGBA, formats YUV, et propriétés de mosaïque, de mélange et de pas
Pour implémenter le HWC :
- Implémentez un HWC non opérationnel et envoyez toutes les tâches de composition à GLES
- Implémentez un algorithme pour déléguer la composition au HWC de manière incrémentielle. Par exemple, déléguez uniquement les trois ou quatre premières surfaces à la superposition. le matériel du HWC.
- Optimisez le matériel. Cela peut inclure:
<ph type="x-smartling-placeholder">
- </ph>
- Choisir des surfaces qui maximisent la charge retirée du GPU et en les envoyant au HWC.
- Détecter si l'écran est en cours de mise à jour. Si ce n'est pas le cas, déléguez la composition à GLES au lieu du HWC pour économiser de l'énergie. Lorsque l'écran s'actualise à nouveau, continuez à décharger la composition sur le HWC.
- Préparation aux cas d'utilisation courants, par exemple :
- L'écran d'accueil, qui inclut la barre d'état, la barre système, l'application fenêtre et fonds d'écran animés
- Jeux plein écran en mode portrait et paysage
- Vidéo plein écran avec sous-titres et lecture contrôle
- Lecture de vidéos protégées
- Écran partagé multifenêtre
Primitives HWC
Le matériel fournit deux primitives, les couches et les affichages, pour représentent le travail de composition et son interaction avec le matériel d'affichage. Le HWC permet également de contrôler VSYNC et un rappel vers SurfaceFlinger pour l'informer lorsqu'un événement VSYNC se produit.
Interface HIDL
Android 8.0 et les versions ultérieures utilisent une interface HIDL appelée HAL Composer pour l'IPC liée entre le HWC et SurfaceFlinger. Le HAL de Composer remplace l'ancienne interface hwcomposer2.h
. Si les fournisseurs fournissent une implémentation HAL Composer du HWC, HAL Composer accepte directement les appels HIDL de SurfaceFlinger. Si les fournisseurs proposent une ancienne implémentation du matériel, Composer
HAL charge les pointeurs de fonction à partir de hwcomposer2.h
,
transférer des appels HIDL en appels de pointeurs de fonction.
Le HWC fournit des fonctions permettant de déterminer les propriétés d'un écran donné, de basculer entre différentes configurations d'affichage (telles que la résolution 4K ou 1080p) et des modes de couleur (telles que la couleur native ou le vrai sRGB), et d'allumer, d'éteindre ou de mettre l'écran en mode basse consommation, le cas échéant.
Pointeurs de fonction
Si les fournisseurs implémentent directement le HAL Composer, SurfaceFlinger appelle ses fonctions via l'IPC HIDL. Par exemple, pour créer une couche, SurfaceFlinger appelle
createLayer()
sur le HAL de Composer.
Si les fournisseurs implémentent l'interface hwcomposer2.h
, le HAL Composer appelle les pointeurs de fonction hwcomposer2.h
. Dans hwcomposer2.h
commentaires,
Les fonctions de l'interface
HWC sont
désignés par des noms en minuscule CamelCase qui n'existent pas dans l'interface
sous forme de champs nommés. Presque toutes les fonctions sont chargées en demandant un pointeur de fonction à l'aide de getFunction
fourni par hwc2_device_t
. Par exemple, la fonction createLayer
est un pointeur de fonction de type HWC2_PFN_CREATE_LAYER
, qui est renvoyé lorsque la valeur énumérée HWC2_FUNCTION_CREATE_LAYER
est transmise à getFunction
.
Pour obtenir une documentation détaillée sur les fonctions HAL de Composer et le transfert de fonction HWC
fonctions, consultez la section composer
. Pour une documentation détaillée
pointeurs de fonction HWC, consultez le
hwcomposer2.h
Poignées de calque et d'affichage
Les calques et les écrans sont manipulés par des identifiants générés par le HWC. Les poignées sont opaques pour SurfaceFlinger.
Lorsque SurfaceFlinger crée une couche, il appelle createLayer
,
qui renvoie le type Layer
pour les accès directs
ou hwc2_layer_t
pour les implémentations passthrough. Lorsque SurfaceFlinger modifie une propriété de cette couche, il transmet la valeur hwc2_layer_t
à la fonction de modification appropriée, ainsi que toutes les autres informations nécessaires à la modification. Le type hwc2_layer_t
est suffisamment grand pour contenir un pointeur ou un indice.
Les écrans physiques sont créés grâce au branchement à chaud. Lorsqu'un écran physique est connecté en mode hotplug, le HWC crée un handle et le transmet à SurfaceFlinger via le rappel hotplug. Les écrans virtuels sont créés par SurfaceFlinger
en appelant createVirtualDisplay()
pour demander un affichage. Si le HWC est compatible avec la composition d'écran virtuel, il renvoie un handle. Ensuite, SurfaceFlinger délègue la composition des écrans au HWC. Si le HWC n'est pas compatible avec la composition d'écran virtuel, SurfaceFlinger crée la poignée et compose l'écran.
Afficher les opérations de composition
Une fois par VSYNC, SurfaceFlinger s'active s'il reçoit un nouveau contenu composite. Il peut s'agir de nouveaux tampons d'image issus d'applications un changement des propriétés d'un ou de plusieurs calques. Lorsque SurfaceFlinger l'active :
- Gère les transactions, le cas échéant.
- Ajoute de nouveaux tampons graphiques, s'ils sont présents.
- Effectue une nouvelle composition, si l'étape 1 ou 2 a entraîné une modification au contenu d'affichage.
Pour effectuer une nouvelle composition, SurfaceFlinger crée et
détruit les calques ou modifie leur état, le cas échéant. Elle met également à jour
des couches avec leur contenu actuel, à l'aide d'appels comme
setLayerBuffer
ou setLayerColor
. Une fois que toutes les couches sont
mis à jour, SurfaceFlinger appelle validateDisplay
, ce qui indique
le HWC pour examiner l'état des couches et déterminer comment la composition
continuer. Par défaut, SurfaceFlinger tente de configurer chaque couche
de sorte que la couche soit composée par le HWC ; mais dans certains
SurfaceFlinger compose des couches via le GPU de remplacement.
Après l'appel de validateDisplay
, SurfaceFlinger appelle getChangedCompositionTypes
pour voir si le HWC souhaite modifier l'un des types de composition de calques avant d'effectuer la composition. Pour accepter les modifications, SurfaceFlinger appelle
acceptDisplayChanges
Si des couches sont marquées pour la composition SurfaceFlinger, SurfaceFlinger
les composite dans le tampon cible. SurfaceFlinger appelle ensuite
setClientTarget
pour fournir le tampon à l'écran afin que le
tampon peut être affiché à l'écran ou composé de couches qui
n'ont pas été marquées pour la composition SurfaceFlinger. Si aucun calque n'est marqué pour
Dans la composition SurfaceFlinger, SurfaceFlinger contourne l'étape de composition.
Enfin, SurfaceFlinger appelle presentDisplay
pour demander au HWC de terminer le processus de composition et d'afficher le résultat final.
Écrans multiples
Android 10 est compatible avec plusieurs écrans physiques. Lors de la conception d'une implémentation HWC destinée à être utilisée sur Android 7.0 et plus élevée, certaines restrictions ne sont pas présentes dans la définition HWC:
- On suppose qu'il n'y a qu'un seul écran interne. La couche interne correspond à l'écran signalé par le plug-in Hotplug initial démarrer. Une fois l'écran interne connecté, il ne peut plus être déconnecté.
- En plus de l'écran interne, autant d'écrans externes peuvent être branchés à chaud
pendant le fonctionnement normal de l'appareil. Le framework part du principe que tous
les prises électriques situées après le premier écran interne sont des écrans externes.
des écrans internes sont ajoutés, ils sont classés de manière incorrecte comme
Display.TYPE_HDMI
au lieu deDisplay.TYPE_BUILT_IN
Bien que les opérations SurfaceFlinger décrites ci-dessus soient effectuées elles sont effectuées de manière séquentielle pour tous les écrans actifs, même si le contenu d'un seul affichage est mis à jour.
Par exemple, si l'écran externe est mis à jour, la séquence est la suivante :
// In Android 9 and lower: // Update state for internal display // Update state for external display validateDisplay(<internal display>) validateDisplay(<external display>) presentDisplay(<internal display>) presentDisplay(<external display>) // In Android 10 and higher: // Update state for internal display // Update state for external display validateInternal(<internal display>) presentInternal(<internal display>) validateExternal(<external display>) presentExternal(<external display>)
Composition de l'affichage virtuel
La composition de l'écran virtuel est semblable à celle de l'écran externe la composition. La différence entre la composition d'un écran virtuel et la composition d'un écran physique est que les écrans virtuels envoient la sortie vers un tampon Gralloc au lieu de l'écran. Hardware Composer (HWC) écrit la sortie dans un tampon, fournit la clôture et envoie le tampon à un consommateur (par exemple, encodeur vidéo, GPU, CPU, etc.). Les écrans virtuels peuvent utiliser des 2D/blitter ou des superpositions si le pipeline d'affichage écrit dans la mémoire.
Modes
Chaque frame se trouve dans l'un des trois modes suivants après que SurfaceFlinger a appelé la méthode HWC validateDisplay()
:
- GLES : le GPU compile toutes les couches, écrivant directement dans le tampon de sortie. Le matériel n'est pas impliqué dans la composition.
- MIXED : le GPU compose certaines couches dans le frame buffer, et le HWC compose le frame buffer et les couches restantes, en écrivant directement dans le tampon de sortie.
- HWC : le matériel composite (HWC) compose toutes les couches et écrit directement au tampon de sortie.
Format de sortie
Les formats de sortie du tampon d'affichage virtuel dépendent de leur mode :
- Mode GLES : le pilote EGL définit le tampon de sortie.
au format
dequeueBuffer()
, généralementRGBA_8888
. Le client doit pouvoir accepter le format de sortie défini par le pilote ou le tampon ne peut pas être lu. - Modes MIXED et HWC : si le client a besoin d'un accès au processeur, il définit le format. Sinon, le format est
IMPLEMENTATION_DEFINED
, et Gralloc définit le meilleur format en fonction des indicateurs d'utilisation. Par exemple, Gralloc définit un format YCbCr si l'utilisateur l'encodeur vidéo et le HWC peuvent écrire le format efficacement.
Limites de synchronisation
Les barrières de synchronisation sont un aspect crucial des éléments graphiques Android. du système d'exploitation. Les barrières permettent au travail du processeur de se poursuivre indépendamment du travail du GPU concurrent, et ne se bloquent que lorsqu'il existe une véritable dépendance.
Par exemple, lorsqu'une application envoie un tampon produit sur le GPU, elle envoie également un objet de barrière de synchronisation. Cette clôture indique quand Le GPU a fini d'écrire dans le tampon.
Le HWC exige que le GPU termine l'écriture des tampons avant que les tampons ne soient affiché. Les barrières de synchronisation sont transmises via le pipeline graphique avec des tampons et signaler l'écriture des tampons. Avant l'affichage d'un tampon, le HWC vérifie si la barrière de synchronisation a signalé et, le cas échéant, il affiche le tampon.
Pour en savoir plus sur les barrières de synchronisation, consultez la page Hardware Composer Intégration.