À partir d'Android 13, de nouveaux framebuffers sont utilisés pendant client sont allouées chaque fois que la résolution d'affichage change. Ce l'allocation est effectuée par SurfaceFlinger lors du prochain cycle d'invalidation après un changement de résolution.
Gestion du framebuffer lors des changements de résolution
Un changement de résolution se produit pour l'une des raisons suivantes : deux scénarios:
Un événement de plug-in à chaud initiée par Hardware Composer (HWC), qui se produit lors du passage d'un compte afficher sur un autre écran externe avec une résolution par défaut différente.
Lors d'un événement de plug-in à chaud, les poignées des anciens framebuffers sont libérées. lorsque les anciennes données display sont libérées.
Un changement de mode d'affichage déclenché par SurfaceFlinger, qui se produit lorsque l'utilisateur modifie la résolution dans les paramètres utilisateur, ou si une application modifie la résolution avec
preferredDisplayModeId
.Lors d'un changement de mode d'affichage, gère les framebuffers du client existants. sont publiés par SurfaceFlinger avant d'appeler
setActiveConfig
. ousetActiveConfigWithConstraints
.
Pour éviter des problèmes catastrophiques, tels que la fragmentation de la mémoire, sur les appareils qui ne réservent pas assez de mémoire pour l'ancien et le nouveau framebuffer, il est essentiel que le HWC cesse d'utiliser les anciens framebuffers et libère toute vers ces framebuffers, comme illustré dans les cas suivants:
Pour les événements de plug-ins à chaud, juste avant d'appeler
onHotplug
.Pour les changements de mode, immédiatement après l'appel à
setActiveConfig
ousetActiveConfigWithConstraints
.
Le fait de libérer les poignées permet de désallouer entièrement la mémoire du tampon de trame avant l'allocation de nouveaux framebuffers exécutés par SurfaceFlinger au cours du prochain cycle d'invalidation.
Recommandations pour la gestion du tampon de frames
Si le HWC ne libère pas les poignées sur les anciens tampons de frames à temps, La nouvelle allocation du framebuffer a lieu avant l'ancien framebuffer et la désallocation. Cela peut entraîner des problèmes catastrophiques en cas d'échec de la nouvelle allocation en raison de la fragmentation ou d'autres problèmes. Pire encore, si Le matériel ne libère pas du tout ces poignées, une fuite de mémoire peut se produisent.
Pour éviter les échecs d'allocation catastrophiques, suivez les recommandations suivantes:
Si le matériel doit continuer à utiliser les anciens framebuffers client jusqu'à ce que le nouveau les framebuffers du client sont fournis, il est essentiel de réserver suffisamment de mémoire pour l'ancien et le nouveau framebuffers, et exécuter éventuellement une défragmentation sur l'espace mémoire du framebuffer.
Allouer un pool de mémoire dédié aux framebuffers distinct le reste de la mémoire tampon graphique. C’est important car entre la désallocation et la réaffectation des tampons de trame, un processus tiers peut d'allouer de la mémoire graphique. Si le même pool de mémoires graphiques utilisée par le framebuffer. Si la mémoire graphique est saturée, le serveur tiers peut occuper la mémoire graphique précédemment allouée par un framebuffer, il reste donc une mémoire insuffisante pour la réaffectation du tampon de trames, fragmenter l'espace mémoire.
Tester la gestion du framebuffer
Il est recommandé aux OEM de tester la gestion de la mémoire du tampon de trame client contacteurs de résolution pour leur appareil, décrits comme suit:
Pour les branchements à chaud, il suffit de débrancher et de rebrancher deux écrans différents avec avec différentes résolutions.
Pour changer de mode, utilisez
ModeSwitchingTestActivity
CTS. Test de l'outil de vérification pour lancer un changement de mode afin de tester le comportement de la mémoire tampon du framebuffer. Ce test permet d'identifier visuellement les problèmes difficiles à détecter de manière programmatique.