Travamento de buffers não sinalizados com a AutoSingleLayer

O Android 13 introduz 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 apenas uma camada está sendo atualizada. Isso não se aplica a casos que ocorrem em várias camadas, por exemplo, mudanças de geometria ou transações de sincronização.

Antes, a flag debug.sf.latch_unsignaled no Android Open Source Project (AOSP) permitia que o SurfaceFlinger bloqueasse todos os buffers não sinalizados, independente do caso de uso. Quando você ativa essa configuração, ela pode causar efeitos colaterais indesejados, como interromper transações de sincronização e congelar toda a tela enquanto espera 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 da fixação de buffers não sinalizados e da redução de instabilidade do app sem serem afetados por congelamentos da tela.

Configurações do modo AutoSingleLayer

No Android 13, AutoSingleLayer é o modo padrão para o recurso de travamento 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 uso 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 do bloqueio e bloqueia 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, o SurfaceFlinger trava todos os buffers não sinalizados. Para configurar esse modo, defina debug.sf.latch_unsignaled como true.

Teste o AutoSingleLayer

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

Rastreamento de buffer travado não sinalizado

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