A partir do Android 13, novos framebuffers, usados durante a composição do cliente , são alocados sempre que a resolução da tela muda. Essa alocação é executada pelo SurfaceFlinger no próximo ciclo de invalidação após uma alteração na resolução.
Gerenciamento de framebuffer durante trocas de resolução
As alterações de resolução ocorrem devido a um dos dois cenários a seguir:
Um evento hotplug , iniciado pelo Hardware Composer (HWC), que ocorre ao trocar de um monitor externo para um monitor externo diferente que possui uma resolução padrão diferente.
Durante um evento hotplug, os identificadores dos framebuffers antigos são liberados quando os dados de exibição antigos são desalocados.
Uma alternância de modo de exibição iniciada por SurfaceFlinger, que ocorre quando o usuário altera a resolução com user settings ou um aplicativo altera a resolução com
preferredDisplayModeId
.Durante uma alternância de modo de exibição, os identificadores para framebuffers de cliente existentes são liberados pelo SurfaceFlinger antes de chamar
setActiveConfig
ousetActiveConfigWithConstraints
.
Para evitar problemas catastróficos, como fragmentação de memória, em dispositivos que não reservam memória suficiente para os framebuffers antigos e novos, é fundamental que o HWC pare de usar os framebuffers antigos e libere quaisquer identificadores para esses framebuffers, conforme mostrado nos seguintes casos:
Para eventos hotplug, imediatamente antes de chamar
onHotplug
.Para alternâncias de modo, imediatamente após a chamada para
setActiveConfig
ousetActiveConfigWithConstraints
.
A liberação dos identificadores permite que a memória do framebuffer seja totalmente desalocada antes da alocação de novos framebuffers que o SurfaceFlinger executa durante o próximo ciclo de invalidação .
Recomendações para gerenciamento de framebuffer
Se o HWC não liberar identificadores para framebuffers antigos a tempo, a nova alocação do framebuffer ocorrerá antes da desalocação do framebuffer antigo. Isto pode causar problemas catastróficos quando a nova alocação falha devido à fragmentação ou outros problemas. Pior ainda, se o HWC não liberar esses identificadores, poderá ocorrer um vazamento de memória.
Para evitar falhas catastróficas de alocação, siga estas recomendações:
Se o HWC precisar continuar usando os framebuffers do cliente antigo até que os novos framebuffers do cliente sejam fornecidos, então é fundamental reservar memória suficiente para os framebuffers antigos e novos e possivelmente executar algoritmos de desfragmentação no espaço de memória do framebuffer.
Aloque um pool de memória dedicado para os framebuffers que seja separado do restante da memória do buffer gráfico. Isto é importante porque entre a desalocação e a realocação dos framebuffers, um processo de terceiros pode tentar alocar memória gráfica. Se o mesmo pool de memória gráfica for utilizado pelo framebuffer e se a memória gráfica estiver cheia, o processo de terceiros pode ocupar a memória gráfica previamente alocada por um framebuffer, deixando memória insuficiente para a realocação do framebuffer ou, possivelmente, fragmentando o espaço de memória .
Testar gerenciamento de framebuffer
Os OEMs são aconselhados a testar o gerenciamento adequado da memória do framebuffer do cliente em switches de resolução para seus dispositivos, descritos a seguir:
Para eventos hotplug, basta desconectar e reconectar dois monitores diferentes com resoluções diferentes.
Para alternâncias de modo, use o teste
ModeSwitchingTestActivity
CTS Verifier para iniciar uma alternância de modo para testar o comportamento da memória do framebuffer. Este teste pode identificar visualmente problemas que são difíceis de detectar programaticamente.