No Android 13 e versões mais recentes, os novos framebuffers, usados durante a composição do cliente, são alocados sempre que a resolução da tela muda. Essa alocação é realizada pelo SurfaceFlinger no próximo ciclo de invalidação após uma mudança de resolução.
Gerenciamento de framebuffer durante trocas de resolução
As alterações de resolução ocorrem devido a um dos seguintes motivos dois cenários:
Um evento de hotplug, iniciado pelo Hardware Composer (HWC), que ocorre na troca de um para outro monitor externo que tenha uma resolução padrão diferente.
Durante um evento de hotplug, os identificadores dos framebuffers antigos são liberados quando os dados de display antigos são desalocados.
Uma chave de modo de exibição iniciada pelo SurfaceFlinger, que ocorre quando o usuário altera a resolução com as configurações do usuário, ou um app muda a resolução com
preferredDisplayModeId
.Durante uma troca de modo de exibição, os identificadores para os framebuffers existentes do cliente são lançados pelo SurfaceFlinger antes de chamar
setActiveConfig
. ousetActiveConfigWithConstraints
.
Para evitar problemas catastróficos, como fragmentação de memória, em dispositivos que não reservar memória suficiente para os framesbuffers antigos e novos, que a HWC pare de usar os framebuffers antigos e libere quaisquer para esses framebuffers, conforme mostrado nos seguintes casos:
Para eventos de hotplug, imediatamente antes de chamar
onHotplug
.Para interruptores de modo, imediatamente após a chamada para
setActiveConfig
ousetActiveConfigWithConstraints
.
A liberação dos identificadores permite que a memória framebuffer seja totalmente desalocada antes da alocação de novos framebuffers que o SurfaceFlinger executa no próximo ciclo de invalidação.
Recomendações para o gerenciamento de framebuffer
Se o HWC não liberar alças para os framebuffers antigos a tempo, a nova alocação do framebuffer ocorre antes do framebuffer antigo a desalocação. Isso pode causar problemas catastróficos quando a nova alocação falha. devido à fragmentação ou outros problemas. Pior ainda, se O HWC não libera essas alças, um vazamento de memória pode antes que ocorram mudanças.
Para evitar falhas de alocação catastróficas, siga estas recomendações:
Se a HWC precisar continuar usando os framebuffers do cliente antigo até que o novo framebuffers de cliente forem fornecidos, é fundamental reservar memória suficiente para os framesbuffers antigo e novo e possivelmente executar desfragmentação no espaço de memória do framebuffer.
Alocar um pool de memória dedicado para os framebuffers que é separado dos o restante da memória do buffer gráfico. Isso é importante porque, entre desalocação e realocação dos framebuffers, um processo de terceiros para alocar memória gráfica. Se o mesmo pool de memória gráfica usada pelo framebuffer. Se a memória gráfica estiver cheia, o servidor pode ocupar a memória gráfica alocada anteriormente por um framebuffer, deixando memória insuficiente para a realocação do framebuffer ou, possivelmente, fragmentando o espaço da memória.
Testar o gerenciamento de framebuffer
Os OEMs são aconselhados a testar o gerenciamento adequado de memória framebuffer do cliente em interruptores de resolução do dispositivo, descrito a seguir:
Para eventos de hotplug, basta desconectar e reconectar duas telas diferentes com com resoluções diferentes.
Para chaves de modo, use o CTS do
ModeSwitchingTestActivity
Teste do verificador para iniciar uma alternância de modo para testar o comportamento da memória do framebuffer. Este teste pode identificar visualmente problemas difíceis de detectar programaticamente.