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