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 bloqueasse todos os buffers não sinalizados, independente do caso de uso. Quando essa configuração está ativada, há efeitos colaterais indesejados, como interrupção das transações de sincronização e congelamento de toda a tela enquanto se aguarda buffers incompletos.

No modo AutoSingleLayer, apenas um buffer de uma única superfície é atualizado em um frame. Esse modo permite que jogos e outros apps em tela cheia aproveitem o benefício de travar buffers não sinalizados e reduzir a instabilidade do app sem serem afetados por travamentos 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. Confira as configurações possíveis:

  • LatchUnsignaledConfig::AutoSingleLayer

    Nesse modo padrão do AOSP, o uso de buffers não sinalizados é permitido 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 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, todos os buffers são travados sem sinalização. 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 rastreamentos do SurfaceFlinger no Perfetto:

Rastreamento de buffer travado não sinalizado

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