A partir de Android 13, se asignan nuevos framebuffers, utilizados durante la composición del cliente , cada vez que cambia la resolución de la pantalla. SurfaceFlinger realiza esta asignación en el siguiente ciclo de invalidación después de un cambio de resolución.
Gestión de framebuffer durante cambios de resolución
Los cambios de resolución se producen debido a uno de los dos escenarios siguientes:
Un evento de conexión en caliente , iniciado por Hardware Composer (HWC), que se produce al cambiar de una pantalla externa a una pantalla externa diferente que tiene una resolución predeterminada diferente.
Durante un evento de conexión en caliente, los identificadores de los framebuffers antiguos se liberan cuando se desasignan los datos de visualización antiguos.
Un cambio de modo de visualización iniciado por SurfaceFlinger, que ocurre cuando el usuario cambia la resolución con la configuración del usuario o una aplicación cambia la resolución
preferredDisplayModeId
.Durante un cambio de modo de visualización, SurfaceFlinger libera los identificadores de los framebuffers del cliente existente antes de llamar
setActiveConfig
osetActiveConfigWithConstraints
.
Para evitar problemas catastróficos, como la fragmentación de la memoria, en dispositivos que no reservan suficiente memoria para los framebuffers antiguos y nuevos, es fundamental que HWC deje de usar los framebuffers antiguos y libere los identificadores de estos framebuffers, como se muestra en los siguientes casos:
Para eventos hotplug, inmediatamente antes de llamar
onHotplug
.Para cambios de modo, inmediatamente después de la llamada a
setActiveConfig
osetActiveConfigWithConstraints
.
Liberar los controladores permite desasignar completamente la memoria del framebuffer antes de la asignación de nuevos framebuffers que SurfaceFlinger realiza durante el siguiente ciclo de invalidación .
Recomendaciones para la gestión de framebuffer
Si HWC no libera los identificadores de los framebuffers antiguos a tiempo, la nueva asignación del framebuffer se lleva a cabo antes de la desasignación del framebuffer antiguo. Esto puede causar problemas catastróficos cuando la nueva asignación falla debido a fragmentación u otros problemas. Peor aún, si HWC no libera estos identificadores en absoluto, puede ocurrir una pérdida de memoria.
Para evitar errores de asignación catastróficos, siga estas recomendaciones:
Si HWC necesita continuar usando los framebuffers del cliente antiguo hasta que se proporcionen los nuevos framebuffers del cliente, entonces es fundamental reservar suficiente memoria para los framebuffers antiguos y nuevos, y posiblemente ejecutar algoritmos de desfragmentación en el espacio de memoria del framebuffer.
Asigne un grupo de memoria dedicado para los framebuffers que esté separado del resto de la memoria del buffer gráfico. Esto es importante porque entre la desasignación y la reasignación de los framebuffers, un proceso de terceros puede intentar asignar memoria de gráficos. 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 del framebuffer o, posiblemente, fragmentando el espacio de memoria. .
Probar la gestión del framebuffer
Se recomienda a los OEM que prueben la gestión adecuada de la memoria framebuffer del cliente en todos los conmutadores de resolución de su dispositivo, que se describe a continuación:
Para eventos de conexión en caliente, simplemente desconecte y vuelva a conectar dos pantallas diferentes con resoluciones diferentes.
Para cambios de modo, use la prueba
ModeSwitchingTestActivity
CTS Verifier para iniciar un cambio de modo para probar el comportamiento de la memoria framebuffer. Esta prueba puede identificar visualmente problemas que son difíciles de detectar mediante programación.