La libreria Frame Pacing per Android, nota anche come Swappy, fa parte dell'SDK Android Game. Aiuta i giochi OpenGL e Vulkan a ottenere un rendering fluido e un pacing corretto dei frame su Android.
La sincronizzazione dei fotogrammi è la sincronizzazione del loop di rendering e della logica di un gioco con il sottosistema di visualizzazione di un sistema operativo e l'hardware di visualizzazione sottostante. Il sottosistema di visualizzazione Android è stato progettato per evitare determinati artefatti visivi, come lo sfarfallio. Il sottosistema di visualizzazione evita lo sfarfallio nel seguente modo:
- Buffering interno dei frame precedenti
- Rilevamento di fotogrammi inviati in ritardo
- Continuare a visualizzare il fotogramma corrente quando viene rilevato un fotogramma in ritardo
I tempi di visualizzazione dei frame incoerenti sono causati dal ciclo di rendering di un gioco che viene eseguito a una frequenza diversa da quella supportata dall'hardware di visualizzazione nativo. I problemi si verificano quando il loop di rendering di un gioco viene eseguito troppo lentamente per l'hardware di visualizzazione sottostante, con tempi di visualizzazione incoerenti. Ad esempio, quando un gioco a 30 FPS tenta di eseguire il rendering su un dispositivo che supporta nativamente 60 FPS, il loop di rendering del gioco fa sì che un fotogramma ripetuto rimanga sullo schermo per 16 ms in più. Questo tipo di disconnessione crea incoerenze sostanziali nei tempi dei fotogrammi, ad esempio 33 ms, 16 ms, 49 ms e così via. Le scene eccessivamente complesse acuiscono questo problema perché causano la perdita di frame.
La libreria Frame Pacing esegue le seguenti attività:
- Compensa la balbuzie dovuta a frame di gioco brevi.
- Aggiunge i timestamp della presentazione in modo che i frame vengano presentati in tempo, non in anticipo.
- Utilizza le estensioni dei timestamp della presentazione
EGL_ANDROID_presentation_time
eVK_GOOGLE_display_timing
.
- Utilizza recinti di sincronizzazione per frame lunghi che causano balbuzie e latenza.
- Inserisce delle interruzioni nell'app. Queste consentono alla pipeline di visualizzazione di recuperare, anziché accumulare una pressione inversa.
- Utilizza recinti di sincronizzazione (
EGL_KHR_fence_sync
eVkFence
).
- Se il tuo dispositivo supporta più frequenze di aggiornamento, scegli una frequenza per offrire flessibilità e una presentazione fluida.
- Fornisce statistiche per il debug e la profilazione utilizzando le statistiche frame.
Per scoprire come configurare la libreria in modo che funzioni in modalità diverse in base alle tue esigenze, consulta Modalità di funzionamento supportate.
Per implementare l'utilizzo del renderer OpenGL o Vulkan, consulta
- Integrare la funzionalità Frame Pacing di Android nel renderer OpenGL
- Integrare la funzionalità di pacing dei frame di Android nel renderer Vulkan
Per scoprire di più, consulta Ottenere un pacing corretto dei fotogrammi.
Intervento di throttling dei frame al secondo
L'intervento di throttling dei frame al secondo (FPS) consente ai giochi di avere un ritmo adeguato con un FPS appropriato utilizzando solo modifiche lato piattaforma e senza richiedere alcun intervento da parte degli sviluppatori.
L'implementazione dell'intervento di limitazione FPS utilizza i seguenti componenti:
GameManagerService
Il componente
GameManagerService gestisce tutte le informazioni per utente e per partita relative alla modalità di gioco e all'intervento in-game. Le informazioni relative ai FPS vengono memorizzate in GameManagerService insieme ad altre informazioni sull'intervento, ad esempio il fattore di riduzione della risoluzione, in una mappatura <PACKAGE_NAME, Interventions>
per ogni profilo utente.
Le informazioni relative ai FPS vengono visualizzate quando la modalità di gioco viene modificata o l'intervento viene aggiornato. Un UID
è univoco per ogni PACKAGE_NAME
e utente e può essere ulteriormente tradotto in una coppia <UID, Frame Rate>
da inviare a SurfaceFlinger.
SurfaceFlinger
Il componente SurfaceFlinger supporta già la limitazione dei FPS di un'applicazione, a condizione che la frequenza dei fotogrammi sia un divisore della frequenza di aggiornamento del display. In caso di vsync, SurfaceFlinger ne verifica la validità per l'applicazione limitata controllando se il timestamp vsync è in fase con la frequenza frame dell'applicazione. Se la frequenza fotogrammi non è in fase con la sincronizzazione verticale, SurfaceFlinger mantiene il fotogramma finché la frequenza fotogrammi e la sincronizzazione verticale non sono in fase.
La figura seguente descrive l'interazione tra GameManagerService e SurfaceFlinger:

Figura 1. Interazione tra GameServiceManager e SurfaceFlinger
SurfaceFinger gestisce una mappatura di coppie <UID, Frame Rate>
per impostare una nuova priorità di throttling della frequenza frame. Il valore UID
è univoco per gli utenti e i giochi, in modo che ogni
utente su un singolo dispositivo possa avere impostazioni diverse della frequenza frame per lo stesso gioco. Per limitare la frequenza fotogrammi di un gioco, GameServiceManager chiama SurfaceFlinger per eseguire l'override della frequenza fotogrammi per un UID. Con questo meccanismo, SurfaceFlinger aggiorna la mappatura ogni volta che viene modificata la modalità di gioco o viene aggiornato l'intervento. SurfaceFlinger gestisce la variazione di FPS bloccando i buffer di conseguenza.
Per saperne di più sulla limitazione FPS, consulta la sezione Introduzione alla limitazione FPS.