Как уменьшить потребление графической памяти

В стеке графики буферный кеш для каждого слоя находится между Composer HAL и SurfaceFlinger, чтобы уменьшить издержки, связанные с отправкой дескрипторов файлов через IPC. В версиях до Android 14 система не очищала этот кеш буфера, когда GraphicBufferProducer отключался от GraphicBufferConsumer SurfaceFlinger, например когда MediaCodec отключался от SurfaceView. Начиная с Android 14, вы можете принудительно очистить этот буферный кеш, чтобы уменьшить потребление памяти графическим процессором.

Выберите один из следующих вариантов:

  • Для устройств с Android 14 и более поздних версий необходимо реализовать новую версию 3.2 API HAL Composer. Этот вариант включен по умолчанию и позволяет максимально сэкономить память. Устройства, обновленные до Android 14 и более поздних версий, также могут использовать этот параметр, чтобы получить все преимущества от оптимизации памяти.
  • Если вы не хотите реализовывать API Composer HAL 3.2 для устройств, которые обновляются до Android 14, можно включить параметр обратной совместимости. Этот вариант позволяет сэкономить почти столько же памяти, сколько и предыдущий.

В следующих двух разделах рассказывается, как реализовать каждый из этих вариантов.

Как реализовать Composer HAL 3.2 API

Чтобы в полной мере воспользоваться преимуществами буфера графики, необходимо:

  1. Обновите реализацию Composer HAL до версии 3.2.
  2. Обработайте LayerCommand::bufferSlotsToClear, удалив записи кеша буфера , указанные номерами слотов в списке.

API Composer HAL 3.2, связанные с памятью графического буфера, включая LayerCommand::bufferSlotsToClear, находятся в файле LayerCommand.aidl.

Включите параметр обратной совместимости

При использовании варианта уменьшения объема памяти с обратной совместимостью реальный буфер в слоте кеша заменяется буфером-плейсхолдером размером 1 x 1. Это позволяет экономить память для всех очищенных слотов, кроме текущего активного слота буфера. Чтобы частично сэкономить память, включите обратную совместимость, задав для системного свойства surface_flinger.clear_slots_with_set_layer_buffer значение true. Это системное свойство находится в файле property_contexts.

Для этого системного свойства требуется, чтобы реализация HAL Composer корректно обрабатывала несколько команд setLayerBuffer для одного слоя в течение одного цикла отрисовки.

Если включить параметр, произойдет следующее:

  • Для AIDL HAL: SurfaceFlinger отправляет несколько экземпляров LayerCommand для одного слоя, каждый с одним BufferCommand. Каждый BufferCommand содержит дескриптор буфера-заполнителя размером 1 x 1 и номер слота для слота буфера кеша, который необходимо очистить.

  • Для HIDL HAL: SurfaceFlinger отправляет несколько команд SELECT_DISPLAY, SELECT_LAYER, SET_BUFFER. Эти команды содержат буферный дескриптор-заполнитель размером 1 x 1 и номер слота для слота буфера кеша, который необходимо очистить.

Обратно совместимый вариант может привести к сбою HAL Composer на некоторых устройствах. Возможно, вам удастся устранить проблему, изменив HAL Composer. Код, управляющий этим поведением, находится здесь:

Как проверить потребление памяти кешем буфера графики

Тесты не могут проверить, очищают ли реализации HAL слоты кеша. Однако вы можете использовать инструменты отладки, чтобы отслеживать использование графического буфера. В ходе мониторинга вы можете заметить, что количество ошибок, связанных с нехваткой памяти, уменьшилось в сценариях, когда на YouTube быстро останавливаются и запускаются несколько разных видео.

Доступны тесты VTS, которые проверяют, может ли реализация HAL принимать новые вызовы API (HAL версии 3.2 и выше) или несколько команд setLayerBuffer для реализации с обратной совместимостью. Однако этого недостаточно для проверки правильной работы, поскольку некоторые устройства проходят эти тесты VTS, но не справляются с реальными задачами.

Новые тесты VTS можно найти по следующим ссылкам: