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, the system did not purge this buffer cache when a GraphicBufferProducer disconnects from SurfaceFlinger's GraphicBufferConsumer, for example, when a MediaCodec disconnects 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 activates by default and saves the maximum amount of memory. Devices upgrading to 14 and higher can also use this option to achieve the 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 nearly 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 the LayerCommand.aidl file.

Enable the backward-compatible option

The backward-compatible memory reduction option replaces a real buffer in the cache slot with a 1x1 placeholder buffer. This results 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 effects:

  • 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 requires purging.

  • 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 requires purging.

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 cannot verify whether HAL implementations purge the cache slots. However, you can use your debugging tools to monitor graphic buffer usage. As you monitor, you might notice fewer out-of-memory errors in scenarios where multiple different videos are stopped and started rapidly 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, see the following links: