Начиная с Android 13, система выделяет новые фреймбуферы, используемые при компоновке клиентского приложения , при каждом изменении разрешения экрана. SurfaceFlinger выполняет это выделение в следующем цикле Invalidate после изменения разрешения.
Управление кадровым буфером при переключении разрешения
Изменения разрешения происходят по одному из следующих двух сценариев:
Событие горячего подключения , инициированное Hardware Composer (HWC), которое происходит при переключении с одного внешнего дисплея на другой внешний дисплей, имеющий другое разрешение по умолчанию.
Во время события горячего подключения HWC освобождает дескрипторы старых буферов кадров, когда он освобождает старые данные отображения.
Переключение режима отображения, инициированное SurfaceFlinger, которое происходит, когда вы изменяете разрешение с помощью пользовательских настроек или приложение изменяет разрешение с помощью
preferredDisplayModeId
.Во время переключения режима отображения SurfaceFlinger освобождает дескрипторы существующих клиентских буферов кадров перед вызовом
setActiveConfig
илиsetActiveConfigWithConstraints
.
Чтобы предотвратить катастрофические проблемы, такие как фрагментация памяти на устройствах с недостаточным объёмом фреймбуфера, HWC должен освободить дескрипторы старых фреймбуферов. Это критически важно в следующих случаях:
Для событий горячего подключения — непосредственно перед вызовом
onHotplug
.Для переключения режимов — сразу после вызова
setActiveConfig
илиsetActiveConfigWithConstraints
.
Освобождение дескрипторов позволяет полностью освободить память буфера кадра до того, как SurfaceFlinger выделит новые буферы кадра во время следующего цикла аннулирования .
Рекомендации по управлению кадровым буфером
Если HWC не освобождает дескрипторы старых буферов кадра вовремя, выделение нового буфера кадра происходит до освобождения старого. Это может привести к катастрофическим проблемам, если выделение нового буфера кадра не удастся из-за фрагментации или других проблем. Хуже того, если HWC вообще не освобождает эти дескрипторы, может произойти утечка памяти.
Чтобы избежать катастрофических сбоев при распределении ресурсов, следуйте следующим рекомендациям:
Если HWC необходимо продолжать использовать старые клиентские буферы кадров до тех пор, пока не будут предоставлены новые клиентские буферы кадров, крайне важно зарезервировать достаточно памяти как для старых, так и для новых буферов кадров и, по возможности, запустить алгоритмы дефрагментации в пространстве памяти буфера кадров.
Выделите отдельный пул памяти для фреймбуферов, отдельный от остальной памяти графического буфера. Это важно, поскольку сторонний процесс может попытаться выделить графическую память в промежутках между освобождением и перераспределением фреймбуфера. Если фреймбуфер использует тот же пул графической памяти, и графическая память заполнена, сторонний процесс может занять память, ранее выделенную фреймбуфером. Это может привести к нехватке памяти для перераспределения фреймбуфера или к фрагментации памяти.
Тестовое управление кадровым буфером
Производителям оригинального оборудования рекомендуется протестировать правильность управления памятью клиентского буфера кадров на всех переключателях разрешения своих устройств, как описано ниже:
В случае горячего подключения отключите и снова подключите два разных дисплея с разным разрешением.
Для переключения режимов используйте тест
ModeSwitchingTestActivity
CTS Verifier, чтобы инициировать переключение режима и проверить поведение памяти фреймбуфера. Этот тест позволяет визуально выявить проблемы, которые сложно обнаружить программно.