Travamento de buffers não sinalizados com a AutoSingleLayer

O Android 13 adiciona uma nova configuração chamada AutoSingleLayer para travar buffers não sinalizados. Essa configuração permite que o SurfaceFlinger use um buffer não sinalizado quando uma única camada está sendo atualizada, mas não para os casos que ocorrem em várias camadas, como mudanças de geometria ou transações de sincronização.

Antes do Android 13, a flag debug.sf.latch_unsignaled no AOSP permitia que o SurfaceFlinger travasse todos os buffers não sinalizados, independentemente do caso de uso. Quando essa configuração está ativada, há efeitos colaterais indesejados, como interromper transações de sincronização e congelar a tela inteira enquanto aguardam buffers incompletos.

Com o modo AutoSingleLayer, apenas um buffer de uma única superfície é atualizado em um frame. Esse modo permite que jogos e outros apps de tela cheia aproveitem o benefício de fixar buffers não sinalizados e reduzir o travamento do app, sem serem afetados por congelamentos de tela.

Configurações do modo AutoSingleLayer

No Android 13, AutoSingleLayer é o modo padrão para o recurso de buffer não sinalizado de trava. Esse modo é controlado pela propriedade do sistema debug.sf.auto_latch_unsignaled.

O SurfaceFlinger lê LatchUnsignaledConfig na inicialização. Veja as configurações possíveis:

  • LatchUnsignaledConfig::AutoSingleLayer

    Nesse modo padrão do AOSP, a fixação de buffers não sinalizados é permitida quando uma única camada é atualizada em um frame e a atualização inclui apenas uma atualização de buffer sem transações de sincronização ou mudanças de geometria. Nesse modo, debug.sf.auto_latch_unsignaled é definido como true por padrão.

  • LatchUnsignaledConfig::Disabled

    Esse modo desativa o comportamento não sinalizado da trava e fixa apenas transações sinalizadas. Esse modo também desativa o modo AutoSingleLayer. Para configurar esse modo, defina debug.sf.latch_unsignaled e debug.sf.auto_latch_unsignaled como false.

  • LatchUnsignaledConfig::Always

    Nesse modo, todos os buffers são bloqueados sem sinal. Para configurar esse modo, defina debug.sf.latch_unsignaled como true.

Teste AutoSingleLayer

Para testar se um buffer está travado sem sinalização, procure os seguintes rastros do SurfaceFlinger no Perfetto:

Rastreamento de buffer não sinalizado travado

Figura 1. Rastreamento de um buffer não sinalizado travado no Perfetto