La libreria Android Frame Pacing, nota anche come Swappy, fa parte dell'Android Game SDK. 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:
- Memorizzazione interna dei frame precedenti
- Rilevamento degli invii di frame 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 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 aggravano ulteriormente il problema perché causano la perdita di frame.
La libreria Frame Pacing esegue queste 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_timeeVK_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_synceVkFence).
- 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à 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à 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 degli FPS di un'applicazione, purché la frequenza fotogrammi sia un divisore della frequenza di aggiornamento del display. In caso di VSync, SurfaceFlinger controlla la validità del VSync per l'applicazione limitata verificando se il timestamp VSync è in fase con la frequenza fotogrammi dell'applicazione. Se la frequenza fotogrammi non è in fase con la sincronizzazione verticale, SurfaceFlinger mantiene il frame finché la frequenza fotogrammi e la sincronizzazione verticale 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> mappata per impostare una nuova priorità di limitazione della frequenza fotogrammi. Il UID è
univoco per utenti e giochi, in modo che ogni utente su un singolo dispositivo possa avere
impostazioni diverse di frequenza fotogrammi nello stesso gioco. Per limitare la frequenza fotogrammi di un gioco, GameManagerService chiama SurfaceFlinger per sostituire la frequenza fotogrammi 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.