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:
- Update your Composer HAL implementation to version 3.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 singleBufferCommand
. EachBufferCommand
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:
HIDL compatible:
GraphicsComposerHidlCommandTest::SET_LAYER_BUFFER_multipleTimes
AIDL 3.1 compatible:
GraphicsComposerAidlCommandTest::SetLayerBufferMultipleTimes
AIDL 3.2:
GraphicsComposerAidlCommandV2Test::SetLayerBufferSlotsToClear