La libreria Android Frame Pacing, nota anche come Swappy, fa parte dell'SDK Android Game. Consente ai giochi OpenGL e Vulkan di ottenere un rendering fluido e una corretta spaziatura dei frame su Android.
Il frame pacing è la sincronizzazione del ciclo di logica e rendering 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 strappo. Il sottosistema di visualizzazione evita lo strappo dello schermo nel seguente modo:
- Bufferizzazione interna dei frame precedenti
- Rilevamento degli invii di frame in ritardo
- Continua a visualizzare il fotogramma corrente quando viene rilevato un fotogramma in ritardo
Tempi di visualizzazione dei frame incoerenti sono causati da un ciclo di rendering di un gioco in esecuzione a una velocità diversa da quella supportata dall'hardware di visualizzazione nativo. I problemi si verificano quando il ciclo di rendering di un gioco viene eseguito troppo lentamente per l'hardware di visualizzazione sottostante, con conseguenti tempi di visualizzazione incoerenti. Ad esempio, quando un gioco in esecuzione a 30 fps tenta di essere visualizzato su un dispositivo che supporta nativamente 60 fps, il ciclo di rendering del gioco fa sì che un frame ripetuto rimanga sullo schermo per altri 16 ms. Questo tipo di disconnessione crea notevoli incongruenze nei tempi dei frame, come 33 ms, 16 ms e 49 ms. Le scene eccessivamente complesse aggravano ulteriormente questo problema perché causano la perdita di frame.
La libreria Frame Pacing esegue le seguenti attività:
- Compensa lo sfarfallio dovuto 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 barriere di sincronizzazione per i frame lunghi che causano stuttering e latenza.
- Inserisce attese nell'app. Ciò consente alla pipeline di visualizzazione di recuperare invece di consentire l'accumulo di contropressione.
- Utilizza le barriere di sincronizzazione (
EGL_KHR_fence_sync
eVkFence
).
- Sceglie una frequenza di aggiornamento per offrire flessibilità e una presentazione fluida, se il dispositivo supporta più frequenze di aggiornamento.
- Fornisce statistiche per il debug e la profilazione utilizzando le statistiche dei frame.
Per scoprire come configurare la libreria in modo che funzioni in diverse modalità in base alle tue esigenze, consulta Modalità operative supportate.
Per l'implementazione utilizzando il renderer OpenGL o Vulkan, consulta:
- Integrare Android Frame Pacing nel renderer OpenGL
- Integrare Android Frame Pacing nel renderer Vulkan
Per saperne di più, consulta la libreria Frame Pacing.
Intervento di limitazione dei frame al secondo
L'intervento di throttling dei frame al secondo (FPS) consente ai giochi di procedere a un FPS appropriato utilizzando solo modifiche lato piattaforma e senza richiedere alcuna azione da parte degli sviluppatori.
L'implementazione dell'intervento di limitazione degli FPS utilizza i seguenti componenti.
GameManagerService
Il componente
GameManagerService gestisce tutte le informazioni per utente e per gioco della modalità di gioco e dell'intervento di gioco. Le informazioni sugli FPS vengono memorizzate in
GameManagerService insieme ad altre informazioni sull'intervento, come il fattore di riduzione della risoluzione,
in una mappatura <PACKAGE_NAME, Interventions>
per ogni profilo utente.
Le informazioni sugli FPS vengono consultate quando la modalità 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 degli FPS di un'applicazione, purché il frame rate sia un divisore della frequenza di aggiornamento del display. In caso di VSync, SurfaceFlinger verifica la validità del VSync per l'applicazione limitata controllando se il timestamp VSync è in fase con il frame rate dell'applicazione. Se il frame rate non è in fase con VSync, SurfaceFlinger mantiene il frame finché il frame rate e VSync non sono in fase.
La seguente figura descrive l'interazione tra GameManagerService e SurfaceFlinger:

Figura 1. Interazione tra GameServiceManager e SurfaceFlinger.
SurfaceFinger mantiene una mappatura della coppia <UID, Frame Rate>
per impostare una nuova
priorità di limitazione del frame rate. Il UID
è univoco tra utenti e giochi, in modo che ogni
utente su un singolo dispositivo possa avere impostazioni diverse di frame rate nello stesso gioco. Per limitare la
frequenza fotogrammi di un gioco, GameServiceManager chiama SurfaceFlinger per sostituire la frequenza fotogrammi per
un UID. Con questo meccanismo, SurfaceFlinger aggiorna la mappatura ogni volta che
la modalità di gioco viene modificata o l'intervento viene aggiornato. SurfaceFlinger gestisce la modifica degli FPS
agganciando i buffer di conseguenza.
Per saperne di più sulla limitazione degli FPS, consulta Limitazione degli FPS.