Travamento de buffers não sinalizados com a AutoSingleLayer

O Android 13 apresenta 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. Ela não se aplica a casos que ocorrem em várias camadas, por exemplo, mudanças de geometria ou transações de sincronização.

Anteriormente, a flag debug.sf.latch_unsignaled no Android Open Source Project (AOSP, link em inglês) permitia que o SurfaceFlinger travasse todos os buffers não sinalizados, independentemente do caso de uso. Quando você ativa essa configuração, ela pode causar efeitos colaterais indesejados, por exemplo, interromper transações de sincronização e congelar toda a tela enquanto aguarda buffers incompletos.

No modo AutoSingleLayer, o SurfaceFlinger atualiza apenas um buffer de uma única superfície em um frame. Esse modo permite que jogos e outros apps em tela cheia se beneficiem do travamento de buffers não sinalizados e da redução de instabilidade 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. Esse modo é controlado pela propriedade do sistema debug.sf.auto_latch_unsignaled.

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

  • LatchUnsignaledConfig::AutoSingleLayer

    Nesse modo padrão do AOSP, o SurfaceFlinger permite o travamento de buffers não sinalizados quando uma única camada é atualizada em um frame. A atualização precisa incluir apenas uma atualização de buffer sem transações de sincronização ou mudanças de geometria. Por padrão, esse modo define debug.sf.auto_latch_unsignaled como true.

  • LatchUnsignaledConfig::Disabled

    Esse modo desativa o comportamento não sinalizado e trava apenas transações sinalizadas. Ele 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, o SurfaceFlinger trava todos os buffers não sinalizados. Para configurar esse modo, defina debug.sf.latch_unsignaled como true.

Testar o AutoSingleLayer

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

Rastreamento de buffer travado não sinalizado

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