Frame Pacing

A biblioteca Android Frame Pacing, também conhecida como Swappy, faz parte do SDK para jogos do Android. Ela ajuda os jogos OpenGL e Vulkan a ter uma renderização uniforme e a corrigir o ritmo de frames no Android.

O ritmo de frame é a sincronização da lógica e do loop de renderização de um jogo com o subsistema de exibição de um SO e o hardware de exibição. O subsistema de exibição do Android foi projetado para evitar artefatos visuais, como tearing. O subsistema de exibição evita a fragmentação da seguinte maneira:

  • Armazenamento em buffer de frames anteriores internamente
  • Como detectar envios de frames atrasados
  • Continuar exibindo o frame atual quando um frame atrasado é detectado

Tempos de exibição de frames inconsistentes são causados pelo loop de renderização de um jogo executado a uma taxa diferente do que o hardware de exibição nativo oferece suporte. Os problemas surgem quando o loop de renderização de um jogo é executado muito lentamente para o hardware de exibição, resultando em tempos de exibição inconsistentes. Por exemplo, quando um jogo em execução a 30 QPS tenta renderizar em um dispositivo que tem suporte nativo a 60 QPS, o loop de renderização do jogo faz com que um frame repetido permaneça na tela por mais 16 ms. Esse tipo de desconexão cria inconsistências substanciais nos tempos de frame, como 33 ms, 16 ms, 49 ms e assim por diante. Cenas extremamente complexas agravam esse problema, porque causam a perda de frames.

A biblioteca Frame Pacing executa estas tarefas:

  • Compensa a renderização lenta devido a frames de jogo curtos.
  • Usa cercas de sincronização para frames longos que causam lentidão e latência.
    • Injeta esperas no app. Elas permitem que o pipeline de exibição seja atualizado, em vez de permitir que a pressão de retorno se acumule.
    • Usa cercas de sincronização (EGL_KHR_fence_sync e VkFence).
  • Escolhe uma taxa de atualização para oferecer flexibilidade e uma apresentação suave, se o dispositivo for compatível com várias taxas de atualização.
  • Fornece estatísticas para depuração e criação de perfil usando estatísticas de frame.

Para saber como configurar a biblioteca para operar em diferentes modos de acordo com o que você precisa, consulte Modos de operação compatíveis.

Para implementar usando o renderizador OpenGL ou Vulkan, consulte

Para saber mais, consulte Alcançar o frame pacing adequado.

Intervenção de limitação de quadros por segundo

A intervenção de limitação de quadros por segundo (QPS) permite que os jogos tenham um ritmo adequado de QPS usando apenas mudanças na plataforma e sem exigir nenhuma ação dos desenvolvedores.

A implementação da intervenção de limitação de QPS usa os seguintes componentes:

GameManagerService

O componente GameManagerService mantém todas as informações por usuário e por jogo do modo de jogo e da intervenção. As informações de QPS são armazenadas no GameManagerService com outras informações de intervenção, como o fator de redução de resolução, em um mapeamento <PACKAGE_NAME, Interventions> para cada perfil de usuário. As informações de QPS são acessadas quando o modo de jogo é alterado ou a intervenção é atualizada. Um UID é exclusivo para cada PACKAGE_NAME e usuário e pode ser convertido em um par <UID, Frame Rate> para enviar ao SurfaceFlinger.

SurfaceFlinger

O componente SurfaceFlinger já oferece suporte ao controle de FPS de um aplicativo, desde que a taxa de frames seja um divisor da taxa de atualização da tela. No caso de um vsync, o SurfaceFlinger verifica a validade do vsync para o aplicativo limitado, verificando se o carimbo de data/hora do vsync está em fase com a taxa de frames do aplicativo. Se a taxa de frames não estiver em fase com o vsync, o SurfaceFlinger vai manter o frame até que a taxa de frames e o vsync estejam em fase.

A figura a seguir descreve a interação entre o GameManagerService e o SurfaceFlinger:

Interação entre o GameManagerService e o SurfaceFlinger

Figura 1. Interação entre o GameServiceManager e o SurfaceFlinger

O SurfaceFinger mantém um mapeamento de par <UID, Frame Rate> para definir uma nova prioridade de limitação de taxa de frames. O UID é exclusivo entre usuários e jogos, de modo que cada usuário em um único dispositivo pode ter configurações diferentes de taxa de frames no mesmo jogo. Para limitar a taxa de frames de um jogo, o GameServiceManager chama o SurfaceFlinger para substituir a taxa de frames de um UID. Com esse mecanismo, o SurfaceFlinger atualiza o mapeamento sempre que o modo de jogo é alterado ou a intervenção é atualizada. O SurfaceFlinger processa a mudança de QPS travando os buffers de acordo.

Para entender melhor a limitação de QPS, consulte Introdução à limitação de QPS.