Gestion du framebuffer client

À partir d'Android 13, de nouveaux framebuffers, utilisés lors de la composition du client , sont alloués chaque fois que la résolution d'affichage change. Cette 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

Les changements de résolution se produisent en raison de l’un des deux scénarios suivants :

  • Un événement hotplug , initié par Hardware Composer (HWC), qui se produit lors du passage d'un écran externe à un autre écran externe ayant une résolution par défaut différente.

    Lors d'un événement hotplug, les handles des anciens framebuffers sont libérés lorsque les anciennes données d'affichage sont libérées.

  • Un changement de mode d'affichage initié par SurfaceFlinger, qui se produit lorsque l'utilisateur modifie la résolution avec user settings ou qu'une application modifie la résolution avec preferredDisplayModeId .

    Lors d'un changement de mode d'affichage, les handles des framebuffers clients existants sont libérés par SurfaceFlinger avant d'appeler setActiveConfig ou setActiveConfigWithConstraints .

Pour éviter des problèmes catastrophiques, tels que la fragmentation de la mémoire, sur les appareils qui ne réservent pas suffisamment de mémoire pour les anciens et les nouveaux framebuffers, il est essentiel que HWC cesse d'utiliser les anciens framebuffers et libère tous les handles de ces framebuffers, comme indiqué dans les cas suivants :

La libération des poignées permet à la mémoire du framebuffer d'être entièrement libérée avant l'allocation de nouveaux framebuffers que SurfaceFlinger effectue lors du prochain cycle d'invalidation .

Recommandations pour la gestion du framebuffer

Si HWC ne libère pas les handles des anciens framebuffers à temps, la nouvelle allocation du framebuffer a lieu avant la désallocation de l'ancien framebuffer. Cela peut entraîner des problèmes catastrophiques lorsque la nouvelle allocation échoue en raison d'une fragmentation ou d'autres problèmes. Pire encore, si HWC ne libère pas du tout ces handles, une fuite de mémoire peut se produire.

Pour éviter des échecs d’allocation catastrophiques, suivez ces recommandations :

  • Si HWC doit continuer à utiliser les anciens framebuffers clients jusqu'à ce que les nouveaux framebuffers client soient fournis, il est alors essentiel de réserver suffisamment de mémoire pour les anciens et les nouveaux framebuffers, et éventuellement d'exécuter des algorithmes de défragmentation sur l'espace mémoire du framebuffer.

  • Allouez un pool de mémoire dédié aux framebuffers, distinct du reste de la mémoire tampon graphique. Ceci est important car entre la désallocation et la réallocation des framebuffers, un processus tiers peut tenter d'allouer de la mémoire graphique. Si le même pool de mémoire graphique est utilisé par le framebuffer et si la mémoire graphique est pleine, le processus tiers peut occuper la mémoire graphique précédemment allouée par un framebuffer, laissant ainsi une mémoire insuffisante pour la réallocation du framebuffer ou, éventuellement fragmentant l'espace mémoire. .

Tester la gestion du framebuffer

Il est conseillé aux OEM de tester la gestion appropriée de la mémoire du framebuffer client sur les commutateurs de résolution de leur appareil, décrit comme suit :

  • Pour les événements hotplug, débranchez et reconnectez simplement deux écrans différents avec des résolutions différentes.

  • Pour les commutateurs de mode, utilisez le test ModeSwitchingTestActivity CTS Verifier pour lancer un changement de mode afin de tester le comportement de la mémoire du framebuffer. Ce test peut identifier visuellement les problèmes difficiles à détecter par programme.