A partire da Android 13, il sistema alloca nuovi framebuffer, utilizzati durante la composizione client, ogni volta che la risoluzione del display cambia. SurfaceFlinger esegue questa allocazione nel ciclo invalidate successivo a una modifica della risoluzione.
Gestione del frame buffer durante i cambi di risoluzione
Le modifiche alla risoluzione si verificano a causa di uno dei due scenari seguenti:
Un evento hotplug, avviato da Hardware Composer (HWC), che si verifica quando si passa da un display esterno a un altro display esterno con una risoluzione predefinita diversa.
Durante un evento hotplug, HWC rilascia gli handle ai vecchi frame buffer quando dealloca i vecchi dati del display.
Un cambio di modalità di visualizzazione avviato da SurfaceFlinger, che si verifica quando modifica la risoluzione utilizzando le impostazioni utente o quando un'app modifica la risoluzione utilizzando
preferredDisplayModeId
.Durante il cambio di modalità di visualizzazione, SurfaceFlinger rilascia gli handle dei frame buffer client esistenti prima di chiamare
setActiveConfig
osetActiveConfigWithConstraints
.
Per evitare problemi catastrofici come la frammentazione della memoria sui dispositivi senza memoria framebuffer sufficiente, HWC deve rilasciare gli handle ai framebuffer precedenti. Questo è fondamentale nei seguenti casi:
Per gli eventi hotplug, immediatamente prima di chiamare
onHotplug
.Per i cambi di modalità, subito dopo aver chiamato il numero
setActiveConfig
osetActiveConfigWithConstraints
.
Il rilascio degli handle consente di deallocare completamente la memoria del framebuffer prima che SurfaceFlinger allochi nuovi framebuffer durante il ciclo di invalidazione successivo.
Consigli per la gestione del framebuffer
Se HWC non rilascia gli handle ai vecchi frame buffer in tempo, la nuova allocazione del frame buffer si verifica prima della deallocazione del vecchio frame buffer. Ciò può causare problemi catastrofici quando la nuova allocazione non riesce a causa di frammentazione o altri problemi. Ancora peggio, se HWC non rilascia questi handle, può verificarsi una perdita di memoria.
Per evitare errori di allocazione catastrofici, segui questi consigli:
Se HWC deve continuare a utilizzare i vecchi framebuffer client finché non vengono forniti nuovi framebuffer client, è fondamentale riservare memoria sufficiente sia per i framebuffer vecchi che per quelli nuovi ed eventualmente eseguire algoritmi di deframmentazione nello spazio di memoria del framebuffer.
Alloca un pool di memoria dedicato per i framebuffer separato dal resto della memoria del buffer grafico. Questo è importante perché un processo di terze parti potrebbe tentare di allocare la memoria grafica tra la deallocazione e la riallocazione del framebuffer. Se il framebuffer utilizza lo stesso pool di memoria grafica e se la memoria grafica è piena, il processo di terze parti può occupare la memoria precedentemente allocata da un framebuffer. Ciò può comportare una memoria insufficiente per la riallocazione del framebuffer o la frammentazione della memoria.
Test della gestione del framebuffer
Si consiglia agli OEM di testare la corretta gestione della memoria del framebuffer del client in tutti i cambi di risoluzione per il proprio dispositivo, come descritto di seguito:
Per gli eventi hotplug, scollega e ricollega due display diversi con risoluzioni diverse.
Per i cambi di modalità, utilizza il test
ModeSwitchingTestActivity
CTS Verifier per avviare un cambio di modalità per testare il comportamento della memoria del framebuffer. Questo test può identificare visivamente problemi difficili da rilevare a livello di programmazione.