A biblioteca Android Frame Pacing, também conhecida como Swappy, faz parte do Android Game SDK . Ajuda os jogos OpenGL e Vulkan a obter uma renderização suave e um ritmo de quadro correto no Android.
O ritmo de quadros é a sincronização da lógica de um jogo e do loop de renderização com o subsistema de exibição de um sistema operacional e o hardware de exibição subjacente. O subsistema de exibição do Android foi projetado para evitar certos artefatos visuais, como tearing. O subsistema de exibição evita rasgos fazendo o seguinte:
- Buffer de frames anteriores internamente
- Detectando envios de frames atrasados
- Continuando a exibir o quadro atual quando um quadro atrasado for detectado
Tempos de exibição de quadros inconsistentes são causados pelo loop de renderização do jogo sendo executado em uma taxa diferente daquela suportada pelo hardware de exibição nativo. Os problemas surgem quando o loop de renderização de um jogo é executado muito lentamente para o hardware de exibição subjacente, levando a tempos de exibição inconsistentes. Por exemplo, quando um jogo rodando a 30 fps tenta renderizar em um dispositivo que suporta nativamente 60 fps, o loop de renderização do jogo faz com que um quadro repetido permaneça na tela por mais 16 ms. Esse tipo de desconexão cria inconsistências substanciais nos tempos de quadro, como 33 ms, 16 ms, 49 ms e assim por diante. Cenas excessivamente complexas agravam ainda mais esse problema porque causam a ocorrência de quadros perdidos.
A biblioteca Frame Pacing executa estas tarefas:
- Compensa a gagueira devido a frames de jogo curtos.
- Adiciona carimbos de data e hora de apresentação para que os quadros sejam apresentados no prazo, e não antes.
- Usa extensões de carimbo de data/hora de apresentação
EGL_ANDROID_presentation_time
eVK_GOOGLE_display_timing
.
- Usa barreiras de sincronização para quadros longos que causam interrupções e latência.
- Injeta esperas no aplicativo. Isso permite que o pipeline de exibição se atualize, em vez de permitir o aumento da contrapressão.
- Usa cercas de sincronização (
EGL_KHR_fence_sync
eVkFence
).
- Escolhe uma taxa de atualização para fornecer flexibilidade e uma apresentação suave, se o seu dispositivo suportar múltiplas taxas de atualização.
- Fornece estatísticas para depuração e criação de perfil usando estatísticas de quadro .
Para saber como configurar a biblioteca para operar em diferentes modos de acordo com sua necessidade, consulte Modos de operação suportados .
Para implementar usando o renderizador OpenGL ou Vulkan, consulte
- Integre o Android Frame Pacing ao seu renderizador OpenGL
- Integre o Android Frame Pacing ao seu renderizador Vulkan
Para ler mais, consulte Alcançar o ritmo adequado de quadros .
Intervenção de limitação de quadros por segundo
A intervenção de aceleração de quadros por segundo (FPS) permite que os jogos tenham um ritmo de FPS apropriado usando apenas alterações no lado da plataforma e sem exigir qualquer ação por parte dos desenvolvedores.
A implementação da intervenção de aceleração FPS utiliza os seguintes componentes:
Serviço GameManager
O componente GameManagerService mantém todas as informações por usuário e por jogo do modo de jogo e da intervenção no jogo. As informações do FPS 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 do FPS 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 ainda ser traduzido em um par <UID, Frame Rate>
para enviar ao SurfaceFlinger.
SurfaceFlinger
O componente SurfaceFlinger já suporta a aceleração do FPS de um aplicativo, desde que a taxa de quadros 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 acelerado, verificando se o carimbo de data/hora do vsync está em fase com a taxa de quadros do aplicativo. Se a taxa de quadros não estiver em fase com o vsync, o SurfaceFlinger mantém o quadro até que a taxa de quadros e o vsync estejam em fase.
A figura a seguir descreve a interação entre GameManagerService e SurfaceFlinger:
O SurfaceFinger mantém um mapeamento de par <UID, Frame Rate>
para definir uma nova prioridade de aceleração da taxa de quadros. O UID
é único entre usuários e jogos, de modo que cada usuário em um único dispositivo pode ter diferentes configurações de taxa de quadros no mesmo jogo. Para limitar a taxa de quadros de um jogo, o GameServiceManager chama o SurfaceFlinger para substituir a taxa de quadros de um UID. Com este mecanismo, o SurfaceFlinger atualiza o mapeamento sempre que o modo de jogo é alterado ou a intervenção é atualizada. O SurfaceFlinger lida com a mudança de FPS travando os buffers de acordo.
Para entender mais sobre a otimização de FPS, consulte Introdução à otimização de FPS .