La libreria Android Frame Pacing, nota anche come Swappy, fa parte dell'Android Game SDK. Aiuta i giochi OpenGL e Vulkan a 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
- Continuare a visualizzare il frame corrente quando viene rilevato un frame in ritardo
I 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 del display sottostante, causando tempi di visualizzazione incoerenti. Ad esempio, quando un gioco in esecuzione a 30 fps tenta di eseguire il rendering 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 incoerenze nei tempi dei frame, ad esempio 33 ms, 16 ms e 49 ms. Le scene eccessivamente complesse peggiorano ulteriormente il 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. In questo modo, la pipeline di visualizzazione può 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.
Si accede alle informazioni sugli FPS quando viene modificata la modalità di gioco o quando 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 coppia <UID, Frame Rate>
mapping per impostare una nuova priorità di limitazione del frame rate. Il UID
è
univoco per utenti e giochi, in modo che ogni utente su un singolo dispositivo possa avere
impostazioni diverse del frame rate nello stesso gioco. Per limitare il frame rate di un gioco, GameManagerService chiama SurfaceFlinger per sostituire il frame rate di un UID. Con questo meccanismo, SurfaceFlinger aggiorna la mappatura
ogni volta che la modalità 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 la sezione Limitazione degli FPS.