Android 11 aggiunge il supporto per i dispositivi con più frequenze di aggiornamento. Questa funzionalità è composta da tre componenti principali:
- Nuove API HAL introdotte in
android.hardware.graphics.composer@2.4
. - Codice della piattaforma per analizzare le configurazioni dei dispositivi per diverse frequenze di aggiornamento e impostare la frequenza di aggiornamento desiderata
- Nuove API SDK e NDK per consentire alle app di impostare il frame rate desiderato
Implementazione
È stato aggiunto il supporto dedicato per il cambio della frequenza di aggiornamento a
android.hardware.graphics.composer@2.4 HAL
.
Ti consigliamo vivamente di utilizzare questa versione, poiché le versioni precedenti di
composer HAL supportano in modo limitato il cambio della frequenza di aggiornamento.
Gruppi di configurazione
È stato aggiunto un nuovo attributo CONFIG_GROUP
a
IComposerClient::Attribute
, che può essere interrogato utilizzando l'API
getDisplayAttribute_2_4
. Questo attributo consente ai fornitori di raggruppare
le configurazioni di visualizzazione. Le configurazioni nello stesso gruppo consentono
di passare facilmente da una all'altra nella maggior parte dei casi. Il gruppo di configurazione viene utilizzato
dalla piattaforma per distinguere le configurazioni tra cui è possibile passare
per modificare la frequenza di aggiornamento e non altri attributi per una
configurazione.
Considera il seguente esempio che mostra i vantaggi dell'utilizzo dei gruppi di configurazione con un dispositivo che supporta quattro configurazioni di visualizzazione:
- 1080p a 60 Hz
- 1080p a 90 Hz
- 1080i a 72 Hz
- 1080i a 48 Hz
Anche se il dispositivo supporta frequenze di aggiornamento di 48 Hz, 60 Hz, 72 Hz e 90 Hz, il display funziona in una modalità diversa e il passaggio da 60 Hz a 72 Hz modifica la configurazione del display da 1080p a 1080i, il che potrebbe non essere il comportamento desiderato. Questo problema viene risolto utilizzando i gruppi di configurazione. Raggruppando 60 Hz e 90 Hz in un unico gruppo di configurazione e 48 Hz e 72 Hz in un altro gruppo di configurazione. La piattaforma sa che può passare da 60 Hz a 90 Hz e da 48 Hz a 72 Hz, ma non da 60 Hz a 72 Hz, perché ciò comporterebbe una modifica della configurazione anziché semplicemente la modifica della frequenza di aggiornamento.


Aggiornamenti dell'API Composer
- getDisplayVsyncPeriod
- Per un migliore controllo e prevedibilità quando si modificano le frequenze di aggiornamento
getDisplayVsyncPeriod
è stato aggiunto.getDisplayVsyncPeriod
restituisce l'attuale frequenza di aggiornamento (in termini di periodo di sincronizzazione verticale) a cui opera il display. Ciò è particolarmente utile durante la transizione tra la frequenza di aggiornamento e la frequenza di aggiornamento corrente è necessaria alla piattaforma per decidere quando iniziare il frame successivo. - setActiveConfigWithConstraints
- Il metodo
setActiveConfigWithConstraints
è una nuova estensione del metodosetActiveConfig
esistente e fornisce maggiori informazioni sulla modifica della configurazione. I vincoli vengono forniti come parte dei parametrivsyncPeriodChangeConstraints
e contengono i seguenti parametri. - desiredTimeNanos
- L'ora in
CLOCK_MONOTONIC
dopo la quale il periodo di sincronizzazione verticale può cambiare (ovvero il periodo di sincronizzazione verticale non deve cambiare prima di questa ora). Questa operazione è utile quando la piattaforma vuole pianificare in anticipo una modifica della frequenza di aggiornamento, ma ha già alcuni buffer nella coda da presentare. La piattaforma imposta questo orario di conseguenza per tenere conto di questi buffer e assicurarsi che la transizione della frequenza di aggiornamento sia il più fluida possibile. - seamlessRequired
- Se è true, richiede che la modifica del periodo di sincronizzazione verticale avvenga senza problemi
senza artefatti visivi evidenti. Questo flag viene utilizzato dalla piattaforma quando è necessario
modificare la frequenza di aggiornamento a seguito di una modifica dei contenuti (ad esempio, il
dispositivo è inattivo e l'animazione inizia). In questo modo il fornitore ha la possibilità di
non consentire determinate modifiche alla configurazione quando potrebbero comportare un artefatto
visivo evidente. Se le configurazioni non possono essere modificate senza problemi e
seamlessRequired
è impostato sutrue
, l'implementazione deve restituireSEAMLESS_NOT_POSSIBLE
come codice restituito e chiamare il nuovo callbackonSeamlessPossible
quando la stessa modifica della configurazione può essere eseguita senza problemi. In caso di esito positivo, l'implementazione restituisce un
VsyncPeriodChangeTimeline
che indica alla piattaforma quando prevedere la modifica della frequenza di aggiornamento. I parametrinewVsyncAppliedTimeNanos
devono essere impostati sull'ora inCLOCK_MONOTONIC
in cui il nuovo display inizierà ad aggiornarsi al nuovo periodo di sincronizzazione verticale. Questo, insieme adesiredTimeNanos
, consente alla piattaforma di pianificare in anticipo il cambio della frequenza di aggiornamento e di iniziare a eseguire il tick delle app per la nuova frequenza di aggiornamento in anticipo. Ciò consente una transizione fluida della frequenza di aggiornamento.Alcune implementazioni richiedono l'invio di un frame di aggiornamento prima che possa essere inviato il frame rate. A questo scopo, l'HAL dispone del parametro
refreshRequired
per indicare che è necessario un frame di aggiornamento e direfreshTimeNanos
per indicare la prima sincronizzazione verticale dopo la quale deve essere inviato un frame di aggiornamento.- onVsyncPeriodTimingChanged [callback]
- Una nuova callback che può essere chiamata dall'HAL per indicare alla piattaforma che alcuni parametri della sequenza temporale sono cambiati e che la piattaforma deve modificare la sequenza temporale. Questo callback dovrebbe essere chiamato se per qualche motivo la vecchia sequenza temporale è stata mancata a causa di un lungo tempo di elaborazione sull'HAL o di un frame di aggiornamento tardivo.
In che modo la piattaforma decide di modificare la frequenza di aggiornamento?
La selezione della frequenza di aggiornamento avviene nei seguenti due servizi di sistema:
- DisplayManager
DisplayManager
imposta la policy di alto livello relativa alla frequenza di aggiornamento. Imposta una configurazione di visualizzazione predefinita, uguale a quella della configurazione HAL del compositore. Inoltre, imposta un intervallo di valori minimo e massimo perSurfaceFlinger
da scegliere come frequenza di aggiornamento.- SurfaceFlinger
- Determina la frequenza di aggiornamento impostando una configurazione che si trova nello stesso gruppo di configurazione della configurazione predefinita e con una frequenza di aggiornamento compresa nell'intervallo min/max.
Display Manager esegue i seguenti passaggi per determinare i criteri:
- Trova l'ID configurazione predefinito eseguendo una query sulla configurazione attiva da
SurfaceFlinger
- Limitare l'intervallo di valori minimo e massimo iterando le
condizioni di sistema
- Impostazione della frequenza di aggiornamento predefinita: il valore della frequenza di aggiornamento predefinita
è impostato nell'overlay di configurazione
R.integer.config_defaultRefreshRate
. Questo valore viene utilizzato per determinare la frequenza di aggiornamento standard del dispositivo per le animazioni e le interazioni touch. - Impostazione della frequenza di aggiornamento di picco: il valore della frequenza di aggiornamento di picco
viene letto da
Settings.System.PEAK_REFRESH_RATE
. Questo valore viene modificato in fase di runtime per riflettere l'impostazione corrente del dispositivo (ad esempio da un'opzione di menu). Il valore predefinito è impostato nell'overlay di configurazioneR.integer.config_defaultPeakRefreshRate
. - Impostazione della frequenza di aggiornamento minima: il valore della frequenza di aggiornamento minima
viene letto da
Settings.System.MIN_REFRESH_RATE
. Questo valore può essere modificato in fase di runtime per riflettere l'impostazione corrente del dispositivo (ad esempio da un'opzione di menu). Il valore predefinito è 0, quindi non esiste un minimo predefinito. - Application requested ModeId: le app possono impostare
WindowManager.LayoutParams.preferredDisplayModeId
per riflettere una configurazione preferita in cui il display deve funzionare. Nella maggior parte delle condizioni,DisplayManager
imposta l'ID configurazione predefinito di conseguenza e imposta la frequenza di aggiornamento minima e massima in modo che corrisponda alla frequenza di aggiornamento della configurazione. - Risparmio energetico: la frequenza di aggiornamento è limitata a 60 Hz o
inferiore quando il dispositivo è in modalità di risparmio energetico, indicata da
Settings.Global.LOW_POWER_MODE.
- Impostazione della frequenza di aggiornamento predefinita: il valore della frequenza di aggiornamento predefinita
è impostato nell'overlay di configurazione
Una volta che DisplayManager
imposta il criterio,
SurfaceFlinger
imposta la frequenza di aggiornamento in base ai livelli attivi (livelli che mettono in coda
gli aggiornamenti dei frame). Se il proprietario del livello imposta una frequenza dei fotogrammi, SurfaceFlinger
tenta di impostare la frequenza di aggiornamento su un valore che sia un multiplo di questa frequenza.
Ad esempio, se due livelli attivi impostano la frequenza dei fotogrammi su 24 e 60, SurfaceFlinger
sceglierà 120 Hz se disponibili. Se questa frequenza di aggiornamento non è disponibile per
SurfaceFlinger, verrà selezionata la frequenza di aggiornamento con l'errore
minimo per il frame rate. Per maggiori informazioni, consulta la documentazione per gli sviluppatori su developer.android.com.
SurfaceFlinger
gestisce i seguenti flag per
controllare la modalità di determinazione della frequenza di aggiornamento:
ro.surface_flinger.use_content_detection_for_refresh_rate:
Se impostato, la frequenza di aggiornamento viene decisa in base ai livelli attivi, anche se non è stata impostata una frequenza dei fotogrammi. SurfaceFlinger mantiene un'euristica in cui trova gli fps medi con cui il livello pubblica i buffer esaminando il timestamp di presentazione allegato al buffer.ro.surface_flinger.set_touch_timer_ms
: se > 0, la frequenza di aggiornamento predefinita verrà utilizzata quando un utente tocca lo schermo per il timeout configurato. Questa euristica viene eseguita per preparare la frequenza di aggiornamento predefinita per le animazioni.ro.surface_flinger.set_idle_timer_ms
: se > 0, la frequenza di aggiornamento minima verrà utilizzata quando non ci sono aggiornamenti dello schermo per il timeout configurato.ro.surface_flinger.set_display_power_timer_ms
: se > 0, la frequenza di aggiornamento predefinita verrà utilizzata quando si accende il display (o quando si esce dalla modalità AOD) per il timeout configurato.
API Frame Rate
L'API frame rate consente alle app di comunicare alla piattaforma Android il frame rate previsto ed è disponibile nelle app che hanno come target Android 11. Per saperne di più sull'API Frame Rate, consulta la documentazione per gli sviluppatori su developer.android.com.
Opzioni sviluppatore

Al menu è stata aggiunta una nuova opzione sviluppatore che attiva/disattiva una sovrapposizione sul display con l'attuale frequenza di aggiornamento. La nuova opzione si trova in Impostazioni > Sistema > Opzioni sviluppatore > Mostra frequenza di aggiornamento.