Reduce graphics memory consumption

In the graphics stack, a per-layer buffer cache sits between Composer HAL and SurfaceFlinger to reduce the overhead associated with sending file descriptors over IPC. Prior to Android 14, this buffer cache wasn't purged when a GraphicBufferProducer disconnects from a SurfaceFlinger GraphicBufferConsumer, such as when a MediaCodec is disconnected from a SurfaceView. Starting with Android 14, you can forcefully purge this buffer cache to reduce graphics memory consumption.

Choose from one of the two following options:

  • For devices launching with Android 14 and higher, you must implement the new Composer HAL API version 3.2. This option is activated by default and saves the most memory. Devices upgrading to 14 and later can also use this option to achieve full memory benefits.
  • For devices upgrading to Android 14 for which you don't want to implement Composer HAL 3.2 API, you can enable the backward-compatible option. This option saves almost as much memory as the previous option.

The following two sections explain how to implement each option.

Implement the Composer HAL 3.2 API

To achieve full graphics buffer memory benefits, you must:

  1. Update your Composer HAL implementation to version 3.2.
  2. Process LayerCommand::bufferSlotsToClear by purging buffer cache entries indicated by the slot numbers found in the list.

The Composer HAL 3.2 APIs related to graphic buffer memory, including LayerCommand:bufferSlotsToClear, are in LayerCommand.aidl-.

Enable the backward-compatible option

The backward-compatible memory reduction option replaces a real buffer in the cache slot with a 1x1 placeholder buffer, resulting in memory savings for all purged slots, except for the current active buffer slot. To achieve partial memory saving benefits, enable the backward-compatible option by setting the surface_flinger.clear_slots_with_set_layer_buffer sysprop to true. This sysprop is found in the property_contexts file.

Setting this sysprop requires your Composer HAL implementation to correctly handle multiple setLayerBuffer commands for the same layer in a single present cycle.

Enabling the backward-compatible option has the following affects:

  • For AIDL HALs: SurfaceFlinger sends multiple LayerCommand instances for a single layer, each with a single BufferCommand. Each BufferCommand contains a 1x1 placeholder buffer handle and a slot number for the cache buffer slot that needs to be purged.

  • For HIDL HALs: SurfaceFlinger sends multiple SELECT_DISPLAY, SELECT_LAYER, SET_BUFFER commands. These commands contain a 1x1 placeholder buffer handle and a slot number for the cache buffer slot that needs to be purged.

The backward-compatible option might cause the Composer HAL to crash on some devices. You might be able to modify your Composer HAL to solve this issue. The code controlling this behavior is found here:

Test graphics buffer cache memory consumption

Tests can't verify whether the cache slots are purged by HAL implementations. However, you can use your debugging tools to monitor graphic buffer usage. As you monitor, you should notice that there are fewer out-of-memory errors in scenarios where multiple different videos are stopped and started in quick succession on YouTube.

VTS tests are available that verify that the HAL implementation is functionally capable of receiving the new API calls (HAL version 3.2+) or multiple setLayerBuffer commands for the backward-compatible implementation. However, this shouldn't be considered sufficient testing for proper functionality, as some devices pass these VTS tests, but fail during real-world use cases.

For new VTS tests, navigate to the following links: