Las capacidades de visualización (como los modos de visualización y los tipos de HDR admitidos) pueden cambiar dinámicamente en los dispositivos que tienen pantallas conectadas externamente (a través de HDMI o DisplayPort), como los decodificadores (STB) y over-the-top (OTT) de Android TV. dispositivos. Este cambio puede ocurrir como resultado de una señal de conexión en caliente HDMI, como cuando el usuario cambia de una pantalla a otra o inicia el dispositivo sin una pantalla conectada. Desde Android 12 en adelante, se han realizado cambios en el marco para manejar las capacidades de visualización dinámica y conexión en caliente.
Esta página cubre cómo manejar las conexiones en caliente de la pantalla y los cambios en las capacidades de visualización en la implementación de Composer HAL. Además, analiza cómo administrar el framebuffer asociado y evitar condiciones de carrera en estas situaciones.
Actualización de las capacidades de visualización
Esta sección describe cómo el marco de Android maneja los cambios en las capacidades de visualización iniciados por Composer HAL.
Antes de que Android pueda manejar los cambios en las capacidades de visualización correctamente, el OEM debe implementar Composer HAL de modo que use onHotplug(display, connection=CONNECTED)
para notificar al marco de trabajo cualquier cambio en las capacidades de visualización. Una vez que se implementa, Android maneja los cambios en las capacidades de visualización de la siguiente manera:
- Al detectar un cambio en las capacidades de visualización, el marco recibe una
onHotplug(display, connection=CONNECTED)
. - Al recibir la notificación, el marco elimina su estado de visualización y lo vuelve a crear con las nuevas capacidades de la HAL mediante los
getActiveConfig
,getDisplayConfigs
,getDisplayAttribute
,getColorModes
,getHdrCapabilities
ygetDisplayCapabilities
. - Una vez que el marco recrea un nuevo estado de visualización, envía la devolución de llamada
onDisplayChanged
a las aplicaciones que están escuchando dichos eventos.
El marco reasigna los framebuffers en onHotplug(display, connection=CONNECTED)
subsiguientes. Consulte Administrar la memoria del búfer de cuadros para obtener más información sobre cómo manejar esto.
Manejo de escenarios de conexión comunes
Esta sección cubre cómo manejar correctamente varios escenarios de conexión en sus implementaciones cuando la pantalla principal está conectada y desconectada.
Habiendo sido creado para dispositivos móviles, el marco de trabajo de Android no tiene soporte integrado para una pantalla principal desconectada. En su lugar, la HAL debe reemplazar la pantalla principal con una pantalla de marcador de posición en sus interacciones con el marco en el caso de que una pantalla principal esté físicamente desconectada.
Los siguientes escenarios pueden ocurrir en decodificadores y dongles de TV que tienen pantallas conectadas externamente que se pueden desconectar. Para implementar el soporte para estos escenarios, utilice la información de la siguiente tabla:
Guión | Manejo |
---|---|
Sin pantalla conectada en el momento del arranque |
|
La pantalla principal está conectada físicamente |
|
La pantalla principal está físicamente desconectada |
|
Gestión de la memoria del búfer de fotogramas
Cuando una pantalla ya conectada recibe un evento de notificación onHotplug(display, connection=CONNECTED)
subsiguiente, el marco reasigna los framebuffers asociados con esta pantalla. Las implementaciones de dispositivos deben anticipar este comportamiento y administrar adecuadamente la memoria de framebuffer. Use las siguientes pautas en su implementación:
Antes de enviar eventos de notificación
onHotplug(display, connection=CONNECTED)
subsiguientes, asegúrese de liberar identificadores de los framebuffers para que el sistema pueda desasignarlos correctamente, antes de reasignarlos. Si la desasignación no se realiza correctamente, la reasignación puede fallar debido a la falta de memoria.Recomendamos asignar un grupo de memoria dedicado para los framebuffers que esté separado del resto del búfer de memoria gráfica.
Esto es importante porque entre la desasignación y reasignación de los framebuffers, un proceso de terceros puede intentar asignar la memoria gráfica. Si el framebuffer utiliza el mismo grupo de memoria de gráficos y si la memoria de gráficos está llena, el proceso de terceros puede ocupar la memoria de gráficos previamente asignada por un framebuffer, dejando así memoria insuficiente para la reasignación de framebuffer (o posiblemente fragmentando el espacio de memoria) .
Uso de ID de configuración secuenciales para evitar condiciones de carrera
Pueden surgir condiciones de carrera si Composer HAL actualiza las configuraciones de visualización admitidas simultáneamente con el marco que llama a setActiveConfig
o setActiveConfigWithConstraints
. La solución es implementar Composer HAL para usar ID secuenciales y evitar este problema.
Esta sección describe cómo pueden ocurrir las condiciones de carrera, seguida de detalles sobre cómo implementar Composer HAL para que use ID secuenciales para evitar tales condiciones.
Considere la siguiente secuencia de eventos, cuando NO se asignan nuevos ID secuenciales a las nuevas configuraciones de pantalla, lo que provoca una condición de carrera:
Los ID de configuración de visualización admitidos son:
- identificación=1 , 1080x1920 60hz
- identificación=2 , 1080x1920 50hz
El marco llama a
setActiveConfig(display, config=1)
.Al mismo tiempo, Composer HAL procesa un cambio de configuración de pantalla y actualiza su estado interno a un nuevo conjunto de configuraciones de pantalla, que se muestra a continuación:
- identificación=1 , 2160x3840 60hz
- identificación=2 , 2160x3840 50hz
- identificación=3 , 1080x1920 60hz
- identificación=4 , 1080x1920 50hz
Composer HAL envía un evento
onHotplug
al marco para notificar que el conjunto de modos admitidos ha cambiado.Composer HAL recibe
setActiveConfig(display, config=1)
(del paso 2).HAL interpreta que el marco ha solicitado un cambio de configuración a 2160x3840 60hz , aunque en realidad se deseaba 1080x1920 60hz .
El proceso que usa asignaciones de ID no secuenciales termina aquí con una mala interpretación del cambio de configuración deseado.
Configuración de Composer HAL para usar ID secuenciales
Para evitar tales condiciones de carrera, el OEM debe implementar Composer HAL de la siguiente manera:
- Cuando Composer HAL actualiza las configuraciones de pantalla admitidas, asigna nuevos ID secuenciales a las nuevas configuraciones de pantalla.
- Cuando el marco llama a
setActiveConfig
osetActiveConfigWithConstraints
con una ID de configuración no válida, Composer HAL ignora la llamada.
Estos pasos sirven para prevenir condiciones de carrera como se muestra en la siguiente discusión.
Considere la siguiente secuencia de eventos, cuando se asignan nuevos ID secuenciales a las nuevas configuraciones de pantalla:
Los ID de configuración de visualización admitidos son:
- identificación=1 , 1080x1920 60hz
- identificación=2 , 1080x1920 50hz
El marco llama a
setActiveConfig(display, config=1)
.Cuando se procesa un cambio de configuración de pantalla, el siguiente conjunto de ID de configuración se asigna a partir del siguiente entero no utilizado, que se muestra a continuación:
identificación=3 , 2160x3840 60hz
identificación=4 , 2160x3840 50hz
identificación=5 , 1080x1920 60hz
identificación=6 , 1080x1920 50hz
Composer HAL envía un evento
onHotplug
al marco para notificar que el conjunto de modos admitidos ha cambiado.Composer HAL recibe
setActiveConfig(display, config=1)
(del paso 2).Composer HAL ignora la llamada porque la ID ya no es válida.
El marco recibe y procesa el evento
onHotplug
del paso 4. Llama al Composer HAL usando las funcionesgetDisplayConfigs
ygetDisplayAttribute
. Con estas funciones el framework identifica el nuevo ID (5) para la resolución deseada y tasa de refresco de 1080x1920 y 60Hz.El marco envía otro evento
setActiveConfig
con una ID actualizada de 5.Composer HAL recibe
setActiveConfig(display, config=5)
del paso 5.HAL interpreta correctamente que el marco ha solicitado un cambio de configuración a 1080x1920 60hz.
Como se muestra en el ejemplo anterior, el proceso que utiliza asignaciones de ID secuenciales garantiza que se evite la condición de carrera y se actualice el cambio de configuración de visualización correcto.