Les capacités d'affichage (telles que les modes d'affichage et les types HDR compatibles) peuvent changer de manière dynamique sur les appareils dotés d'écrans connectés en externe (avec HDMI ou DisplayPort), tels que les décodeurs Android TV et les appareils OTT (Over-the-Top). Ce changement peut se produire à la suite d'un signal HDMI hotplug, par exemple lorsque l'utilisateur passe d'un écran à un autre ou démarre l'appareil sans écran connecté. Android 12 et versions ultérieures incluent des modifications dans le framework pour gérer le branchement à chaud et les capacités d'affichage dynamique.
Cette page décrit la gestion des branchements à chaud d'écran et des modifications des capacités d'affichage dans l'implémentation Composer HAL. Il explique également comment gérer le framebuffer associé et éviter les conditions de concurrence dans ces situations.
Mettre à jour les capacités d'affichage
Cette section décrit comment le framework Android gère les modifications des capacités d'affichage initiées par Composer HAL.
Avant qu'Android puisse gérer correctement les modifications des capacités d'affichage, l'OEM doit implémenter Composer HAL de manière à ce qu'il utilise onHotplug(display, connection=CONNECTED)
pour informer le framework de toute modification des capacités d'affichage. Une fois cette implémentation effectuée, Android gère les modifications apportées aux capacités d'affichage comme suit :
- Lorsqu'un changement de capacités d'affichage est détecté, le framework reçoit une notification
onHotplug(display, connection=CONNECTED)
. - À la réception de la notification, le framework supprime son état d'affichage et le recrée avec les nouvelles fonctionnalités du HAL en utilisant les méthodes
getActiveConfig
,getDisplayConfigs
,getDisplayAttribute
,getColorModes
,getHdrCapabilities
etgetDisplayCapabilities
. - Une fois que le framework a recréé un nouvel état d'affichage, il envoie le rappel
onDisplayChanged
aux applications qui écoutent de tels événements.
Le framework réaffecte les framebuffers lors des événements onHotplug(display, connection=CONNECTED)
suivants. Pour savoir comment gérer correctement la mémoire du framebuffer afin d'éviter les échecs lors de l'allocation de nouveaux framebuffers, consultez Gestion du framebuffer client.
Gérer les scénarios de connexion courants
Cette section explique comment gérer correctement différents scénarios de connexion dans vos implémentations lorsque l'écran principal est connecté et déconnecté.
Étant donné qu'il a été conçu pour les appareils mobiles, le framework Android n'est pas compatible avec un écran principal déconnecté. Au lieu de cela, le HAL doit remplacer l'écran principal par un espace réservé dans ses interactions avec le framework lorsqu'un écran principal est physiquement déconnecté.
Les scénarios suivants peuvent se produire dans les décodeurs et les clés TV connectés à des écrans externes qui peuvent être déconnectés. Pour implémenter la compatibilité avec ces scénarios, utilisez les informations du tableau ci-dessous :
Scénario | Manipulation |
---|---|
Aucun écran connecté au moment du démarrage |
|
L'écran principal est physiquement connecté |
|
L'écran principal est physiquement déconnecté |
|
Considérations relatives aux connexions non HDMI
Android TV n'est compatible qu'avec les résolutions suivantes :
- 720 x 1 280
- 1 080 x 1 920
- 2 160 x 3 840
- 4320 x 7680
Lorsqu'un boîtier décodeur ou un dongle TV tente d'afficher une résolution non compatible, telle que 480i sur une connexion CVBS, un message d'erreur s'affiche.
Si le décodeur ou le dongle TV dispose à la fois de connexions HDMI et non HDMI, la connexion HDMI est l'écran principal et la connexion non HDMI est inactive. Par conséquent, si la connexion HDMI est déconnectée alors que la connexion non HDMI est toujours active, un événement est envoyé à SurfaceFlinger et les capacités de l'écran non HDMI doivent être reflétées par le biais de getDisplayAttribute
et d'autres API iComposerClient
(telles que getHdrCapabilities
).
Utiliser des ID de configuration séquentiels pour éviter les conditions de concurrence
Des conditions de course peuvent survenir si le HAL Composer met à jour les configurations d'affichage compatibles en même temps que le framework appelle setActiveConfig
ou setActiveConfigWithConstraints
.
La solution consiste à implémenter Composer HAL pour utiliser des ID séquentiels et éviter ce problème.
Cette section décrit comment les conditions de course peuvent se produire, puis explique comment implémenter Composer HAL afin qu'il utilise des ID séquentiels pour éviter de telles conditions.
Prenons l'exemple de la séquence d'événements suivante, dans laquelle de nouveaux ID séquentiels ne sont PAS attribués aux nouvelles configurations d'affichage, ce qui provoque une condition de concurrence :
Voici les ID de configuration d'affichage acceptés :
- id=1, 1080x1920 60 Hz
- id=2, 1080x1920 50 Hz
Le framework appelle
setActiveConfig(display, config=1)
.Parallèlement, le HAL du compositeur traite un changement de configurations d'affichage et met à jour son état interne vers un nouvel ensemble de configurations d'affichage, comme suit :
- id=1, 2 160 x 3 840 à 60 Hz
- id=2, 2 160 x 3 840 50 Hz
- id=3, 1 080 x 1 920 60 Hz
- id=4, 1080x1920 50 Hz
Le HAL du compositeur envoie un événement
onHotplug
au framework pour indiquer que l'ensemble des modes compatibles a changé.Le HAL Composer reçoit
setActiveConfig(display, config=1)
(à partir de l'étape 2).Le HAL interprète que le framework a demandé un changement de configuration vers 2160x3840 60 Hz, alors qu'en réalité, 1080x1920 60 Hz était souhaité.
Le processus utilisant des attributions d'ID non séquentielles se termine ici par une mauvaise interprétation de la modification de configuration souhaitée.
Configurer Composer HAL pour utiliser des ID séquentiels
Pour éviter de telles conditions de concurrence, l'OEM doit implémenter le HAL du compositeur comme suit :
- Lorsque le HAL Composer met à jour les configurations d'affichage compatibles, il attribue de nouveaux ID séquentiels aux nouvelles configurations d'affichage.
- Lorsque le framework appelle
setActiveConfig
ousetActiveConfigWithConstraints
avec un ID de configuration non valide, le HAL Composer ignore l'appel.
Ces étapes permettent d'éviter les conditions de concurrence, comme indiqué dans la discussion suivante.
Prenons l'exemple de la séquence d'événements suivante, lorsque de nouveaux ID séquentiels sont attribués aux nouvelles configurations d'affichage :
Voici les ID de configuration d'affichage acceptés :
- id=1, 1080x1920 60 Hz
- id=2, 1080x1920 50 Hz
Le framework appelle
setActiveConfig(display, config=1)
.Lorsqu'une modification des configurations d'affichage est traitée, l'ensemble suivant d'ID de configuration est attribué à partir du prochain entier inutilisé, comme suit :
id=3, 2 160 x 3 840 à 60 Hz
id=4, 2 160 x 3 840 50 Hz
id=5, 1 080 x 1 920 60 Hz
id=6, 1080x1920 50 Hz
Le HAL Composer envoie un événement
onHotplug
au framework pour indiquer que l'ensemble des modes compatibles a changé.Le HAL Composer reçoit
setActiveConfig(display, config=1)
(à partir de l'étape 2).Le HAL Composer ignore l'appel, car l'ID n'est plus valide.
Le framework reçoit et traite l'événement
onHotplug
de l'étape 4. Il appelle le HAL Composer à l'aide des fonctionsgetDisplayConfigs
etgetDisplayAttribute
. Avec ces fonctions, le framework identifie le nouvel ID (5) pour la résolution et la fréquence d'actualisation souhaitées de 1 080 x 1 920 et 60 Hz.Le framework envoie un autre événement
setActiveConfig
avec un ID mis à jour (5).Le HAL Composer reçoit
setActiveConfig(display, config=5)
de l'étape 5.La HAL interprète correctement le fait que le framework a demandé un changement de configuration à 1 080 x 1 920 60 Hz.
Comme indiqué dans l'exemple ci-dessus, le processus utilisant des attributions d'ID séquentielles garantit que la condition de concurrence est évitée et que la modification de la configuration de l'affichage est correctement mise à jour.