Ab Android 13 werden bei jeder Änderung der Bildschirmauflösung neue Framebuffer zugewiesen, die während der Client- Komposition verwendet werden. Diese Zuweisung wird von SurfaceFlinger beim nächsten Ungültigmachungszyklus nach einer Auflösungsänderung durchgeführt.
Framebuffer-Verwaltung während Auflösungswechseln
Auflösungsänderungen treten aufgrund eines der folgenden zwei Szenarios auf:
Ein von Hardware Composer (HWC) initiiertes Hotplug-Ereignis , das beim Wechsel von einem externen Display zu einem anderen externen Display mit einer anderen Standardauflösung auftritt.
Während eines Hotplug-Ereignisses werden die Handles für die alten Framebuffer freigegeben, wenn die alten Anzeigedaten freigegeben werden.
Ein von SurfaceFlinger initiierter Wechsel des Anzeigemodus, der auftritt, wenn der Benutzer die Auflösung mit user Settings ändert oder eine App die Auflösung mit
preferredDisplayModeId
ändert.Während eines Anzeigemoduswechsels werden die Handles für vorhandene Client-Framebuffer von SurfaceFlinger freigegeben, bevor
setActiveConfig
odersetActiveConfigWithConstraints
aufgerufen wird.
Um katastrophale Probleme wie Speicherfragmentierung auf Geräten zu vermeiden, die nicht genügend Speicher für die alten und neuen Framebuffer reservieren, ist es wichtig, dass HWC die Verwendung der alten Framebuffer einstellt und alle Handles für diese Framebuffer freigibt, wie in den folgenden Fällen gezeigt:
Bei Hotplug-Ereignissen unmittelbar vor dem Aufruf von
onHotplug
.Bei Moduswechseln unmittelbar nach dem Aufruf von
setActiveConfig
odersetActiveConfigWithConstraints
.
Durch das Freigeben der Handles kann der Framebuffer-Speicher vollständig freigegeben werden, bevor neue Framebuffer zugewiesen werden, die SurfaceFlinger während des nächsten Invalidierungszyklus durchführt.
Empfehlungen für die Framebuffer-Verwaltung
Wenn HWC Handles für alte Framebuffer nicht rechtzeitig freigibt, erfolgt die neue Framebuffer-Zuweisung vor der Freigabe des alten Framebuffers. Dies kann zu katastrophalen Problemen führen, wenn die neue Zuweisung aufgrund von Fragmentierung oder anderen Problemen fehlschlägt. Schlimmer noch: Wenn HWC diese Handles überhaupt nicht freigibt, kann es zu einem Speicherverlust kommen.
Befolgen Sie diese Empfehlungen, um katastrophale Zuordnungsfehler zu vermeiden:
Wenn HWC die alten Client-Framebuffer weiterhin verwenden muss, bis die neuen Client-Framebuffer bereitgestellt werden, ist es wichtig, ausreichend Speicher sowohl für die alten als auch für die neuen Framebuffer zu reservieren und möglicherweise Defragmentierungsalgorithmen auf dem Framebuffer-Speicherplatz auszuführen.
Weisen Sie den Framebuffer einen dedizierten Speicherpool zu, der vom Rest des Grafikpufferspeichers getrennt ist. Dies ist wichtig, da zwischen der Aufhebung der Zuweisung und der Neuzuweisung der Framebuffer ein Prozess eines Drittanbieters versuchen kann, Grafikspeicher zuzuweisen. Wenn derselbe Grafikspeicherpool vom Framebuffer verwendet wird und der Grafikspeicher voll ist, kann der Drittanbieterprozess den zuvor von einem Framebuffer zugewiesenen Grafikspeicher belegen, sodass nicht mehr genügend Speicher für die Neuzuweisung des Framebuffers übrig bleibt oder der Speicherplatz möglicherweise fragmentiert wird .
Testen Sie die Framebuffer-Verwaltung
OEMs wird empfohlen, die ordnungsgemäße Client-Framebuffer-Speicherverwaltung über Auflösungsschalter für ihr Gerät hinweg zu testen, wie folgt beschrieben:
Bei Hotplug-Ereignissen trennen Sie einfach zwei verschiedene Displays mit unterschiedlichen Auflösungen und schließen sie wieder an.
Verwenden Sie für Moduswechsel den
ModeSwitchingTestActivity
CTS Verifier-Test, um einen Moduswechsel zum Testen des Framebuffer-Speicherverhaltens zu initiieren. Mit diesem Test können Probleme visuell identifiziert werden, die programmgesteuert schwer zu erkennen sind.