Les couches composites HAL de Hardware Composer (HWC) reçues de SurfaceFlinger, ce qui réduit la quantité de composition OpenGL ES (GLES) et les performances du GPU
Le HWC extrait des objets, tels que des superpositions et des blitters 2D, en objets composites et communique avec du matériel spécialisé pour la composition de fenêtres des fenêtres composites. Utilisez le HWC pour des 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:
- 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)
- Mélange alpha prémultiplié simultané par pixel et par plan
- Chemin matériel pour la lecture vidéo protégée
- Ordre de conditionnement RVBA, formats YUV et mosaïque, tourbillon et foulée propriétés
Pour implémenter le matériel:
- Implémentez un HWC non opérationnel et envoyez toutes les tâches de composition à GLES :
- Implémentez un algorithme pour déléguer progressivement la composition au matériel. 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:
- 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 dans GLES au lieu du matériel pour économiser de l'énergie. Lorsque l'écran des mises à jour, continuez à décharger la composition vers le matériel.
- Se préparer aux cas d'utilisation courants tels que:
- Écran d'accueil, qui comprend la barre d'état, la barre système, la fenêtre de l'application et les 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 HWC fournit deux primitives, les couches et les écrans, pour représenter le travail de composition et son interaction avec le matériel d'affichage. La Le matériel permet également de contrôler VSYNC et de rappeler SurfaceFlinger. pour l'avertir 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
ancienne interface hwcomposer2.h
. Si les fournisseurs fournissent une HAL pour Composer
du HWC, Composer HAL 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 pour déterminer les propriétés d'un affichage donné. à Basculer entre différentes configurations d'affichage (4K ou 1080p, par exemple) la résolution) et les modes de couleur (couleur native ou vrai sRVB, par exemple) ; et pour activer ou désactiver l'écran s'allume, l'éteint ou passe en mode d'économie d'énergie, le cas échéant.
Pointeurs de fonction
Si les fournisseurs implémentent directement l'HAL de Composer, SurfaceFlinger appelle ses fonctions
via HIDL IPC. Par exemple, pour créer une couche, SurfaceFlinger appelle createLayer()
sur le HAL Composer.
Si les fournisseurs implémentent l'interface hwcomposer2.h
, l'HAL Composer
dans 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
pointeur de fonction utilisant getFunction
fourni par
hwc2_device_t
Par exemple, la fonction createLayer
est un pointeur de fonction de type HWC2_PFN_CREATE_LAYER
, qui est
affiché lorsque la valeur énumérée HWC2_FUNCTION_CREATE_LAYER
est
transmis à 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 un type Layer
pour les implémentations directes ou hwc2_layer_t
pour les implémentations de passthrough. Quand ?
SurfaceFlinger modifie une propriété de ce calque, qui transmet
la valeur hwc2_layer_t
dans la fonction de modification appropriée ;
ainsi que toute autre information
nécessaire à la modification. La
Le type de hwc2_layer_t
est suffisamment grand pour contenir un pointeur ou un
de l'index.
Les écrans physiques sont créés grâce au branchement à chaud. Lorsqu'un écran physique est
branché à un chaud, le HWC crée une poignée et la transmet à SurfaceFlinger
via le rappel Hotplug. Les écrans virtuels sont créés par SurfaceFlinger
en appelant createVirtualDisplay()
pour demander un affichage. Si le matériel
prend en charge la composition d'écran virtuel, elle 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. Ce nouveau contenu peut être de nouveaux tampons d'image d'applications ou une modification des propriétés d'une 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 matériel
souhaite que l'un des types de composition des calques soit modifié avant d'effectuer la
la composition. Pour accepter les modifications, SurfaceFlinger appelle
acceptDisplayChanges
Si des calques sont marqués pour la composition SurfaceFlinger, SurfaceFlinger les compose 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 indiquer
le matériel pour terminer le processus
de composition et 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:
- Nous partons du principe qu'il y a exactement un écran interne. L'écran interne est celui que le hotplug initial signale au démarrage. Une fois l'écran interne branché à chaud, être déconnectés.
- En plus de l'écran interne, un nombre illimité d'écrans externes peut être connecté en mode "hot-plug" 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'écran virtuel
La composition de l'écran virtuel est semblable à celle de l'écran externe la composition. Différence entre la composition de l'écran virtuel et la composition physique La composition de l'affichage 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 la 2D/blitter ou se superpose si le pipeline d'affichage écrit en 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, en écrivant directement dans le tampon de sortie. Le matériel n'est pas impliqué dans la composition.
- MIXÉ : le GPU compile certaines couches avec le Le framebuffer et HWC composent le framebuffer et les couches restantes. en écrivant directement dans le tampon de sortie.
- HWC : HWC compose toutes les couches et écrit directement dans le 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 MIXTE et HWC : si le consommateur a besoin d'un processeur
le client définit le format. Sinon, le format est
IMPLEMENTATION_DEFINED
, et Gralloc définit le meilleur format en fonction les options 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 clôtures permettent au processeur de fonctionner indépendamment du travail simultané du GPU, uniquement lorsqu'il existe une véritable dépendance.
Par exemple, lorsqu'une application envoie un tampon généré sur le GPU, il envoie également un objet de clôture de synchronisation. Cette barrière indique quand le GPU a terminé 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.