그래픽 스택에서 레이어별 버퍼 캐시는 IPC를 통해 파일 설명자를 전송하는 데 드는 오버헤드를 줄이기 위해 Composer HAL과 SurfaceFlinger 사이에 존재합니다. Android 14 이전에는 MediaCodec이 SurfaceView에서 연결 해제될 때와 같이 GraphicBufferProducer가 SurfaceFlinger GraphicBufferConsumer에서 연결 해제될 때 이 버퍼 캐시가 삭제되지 않았습니다. Android 14부터는 그래픽 메모리 소비를 줄이기 위해 이 버퍼 캐시를 강제로 삭제할 수 있습니다.
다음 두 가지 옵션 중 하나를 선택하세요.
Android 14 이상을 실행하는 기기의 경우 Composer HAL API 버전 3.2를 새로 구현해야 합니다. 이 옵션은 기본적으로 활성화되며 가장 많은 메모리가 절약됩니다. Android 14 이상으로 업그레이드하는 기기도 이 옵션을 사용하여 메모리의 이점을 모두 얻을 수 있습니다.
Composer HAL 3.2 API를 구현하지 않고 Android 14로 업그레이드하는 기기는 하위 호환성 옵션을 사용 설정하면 됩니다. 이 옵션은 이전 옵션과 거의 비슷한 양의 메모리를 절약합니다.
다음 두 섹션은 각 옵션을 구현하는 방법을 설명합니다.
Composer HAL 3.2 API 구현
그래픽 버퍼 메모리의 이점을 모두 얻으려면 다음을 실행해야 합니다.
Composer HAL 구현을 3.2 버전으로 업데이트합니다.
목록에 있는 슬롯 번호로 표시된 버퍼 캐시 항목을 삭제하여 LayerCommand::bufferSlotsToClear를 처리합니다.
LayerCommand:bufferSlotsToClear를 포함하여 그래픽 버퍼 메모리와 관련된 Composer HAL 3.2 API는 LayerCommand.aidl-에 있습니다.
하위 호환성 옵션 사용 설정
하위 호환성 메모리 감소 옵션은 캐시 슬롯에 있는 실제 버퍼를 1x1 자리표시자 버퍼로 대체하며, 그 결과 삭제된 모든 슬롯의 메모리가 절약됩니다(현재 활성 상태의 버퍼 슬롯 제외). 메모리 절약의 이점을 일부 얻으려면 surface_flinger.clear_slots_with_set_layer_buffer sysprop를 true로 설정하여 하위 호환 옵션을 사용 설정하면 됩니다. 이 sysprop는 property_contexts 파일에서 찾을 수 있습니다.
이 sysprop를 설정하려면 현재 단일 주기의 동일 레이어에 대해 여러 setLayerBuffer 명령어를 올바르게 처리할 수 있도록 Composer HAL을 구현해야 합니다.
하위 호환성 옵션을 사용 설정하면 다음과 같은 영향이 있습니다.
AIDL HAL: SurfaceFlinger가 단일 레이어에 여러 LayerCommand 인스턴스를 전송합니다. 각 인스턴스에는 하나의 BufferCommand가 포함됩니다. 각 BufferCommand에는 1x1 자리표시자 버퍼 핸들과 삭제해야 하는 캐시 버퍼 슬롯의 슬롯 번호가 포함됩니다.
HIDL HAL: SurfaceFlinger가 여러 SELECT_DISPLAY, SELECT_LAYER, SET_BUFFER 명령어를 전송합니다. 이러한 명령어에는 1x1 자리표시자 버퍼 핸들과 삭제해야 하는 캐시 버퍼 슬롯의 슬롯 번호가 포함됩니다.
일부 기기에서는 하위 호환성 옵션으로 인해 Composer HAL이 다운될 수 있습니다. Composer HAL을 수정해서 이 문제를 해결할 수도 있습니다. 이 동작을 제어하는 코드는 아래에서 찾을 수 있습니다.
HAL 구현으로 캐시 슬롯이 삭제되었는지는 테스트로 확인할 수 없습니다. 그러나 디버깅 도구를 사용하여 그래픽 버퍼 사용량을 모니터링할 수는 있습니다. 사용량을 모니터링하면 YouTube에서 여러 다른 동영상을 빠르게 연달아 중지하고 시작하는 시나리오에서 메모리 부족 오류가 더 적어진 것을 알 수 있습니다.
VTS 테스트는 HAL 구현이 하위 호환성 구현을 위해 기능적으로 새 API 호출(HAL 버전 3.2 이상) 또는 여러 setLayerBuffer 명령어를 수신할 수 있는지 확인할 수 있습니다. 하지만, 일부 기기는 이러한 VTS 테스트를 통과하더라도 실제 사용 사례에서 실패가 발생하므로 정상적인 작동을 위해 충분한 테스트가 이루어졌다고 할 수 없습니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-07-27(UTC)
[null,null,["최종 업데이트: 2025-07-27(UTC)"],[],[],null,["# Reduce graphics memory consumption\n\nIn the graphics stack, a per-layer buffer cache sits between Composer HAL and\nSurfaceFlinger to reduce the overhead associated with sending file descriptors\nover IPC. Prior to Android 14, this buffer cache\nwasn't purged when a\n[`GraphicBufferProducer`](https://android.googlesource.com/platform/frameworks/native/+/android16-release/libs/gui/include/gui/IGraphicBufferProducer.h) disconnects from a SurfaceFlinger\n[`GraphicBufferConsumer`](https://android.googlesource.com/platform/frameworks/native/+/android16-release/libs/gui/include/gui/IGraphicBufferConsumer.h), such as when a\nMediaCodec is disconnected from a SurfaceView. Starting with Android\n14, you can forcefully purge this buffer cache to\nreduce graphics memory consumption.\n| **Note:** The benefits of this feature are most apparent when a user is starting and stopping videos within an app on a device with a high-resolution display and limited memory, such as a television.\n\nChoose from one of the two following options:\n\n- 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.\n- 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.\n\nThe following two sections explain how to implement each option.\n\nImplement the Composer HAL 3.2 API\n----------------------------------\n\nTo achieve full graphics buffer memory benefits, you must:\n\n1. Update your Composer HAL implementation to version 3.2.\n2. Process `LayerCommand::bufferSlotsToClear` by purging buffer cache entries indicated by the slot numbers found in the list.\n\nThe Composer HAL 3.2 APIs related to graphic buffer memory, including\n`LayerCommand:bufferSlotsToClear`, are in\n[`LayerCommand.aidl-`](https://cs.android.com/android/platform/superproject/+/android-latest-release:hardware/interfaces/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl).\n\nEnable the backward-compatible option\n-------------------------------------\n\nThe backward-compatible memory reduction option replaces a real buffer in\nthe cache slot with a 1x1 placeholder buffer, resulting in memory savings\nfor all purged slots, except for the current active buffer slot. To achieve\npartial memory saving benefits, enable the backward-compatible option by\nsetting the `surface_flinger.clear_slots_with_set_layer_buffer` sysprop to\n`true`. This sysprop is found in the\n[`property_contexts`](https://cs.android.com/android/platform/superproject/+/android-latest-release:system/sepolicy/private/property_contexts?q=%22surface_flinger.clear_slots_with_set_layer_buffer%22)\nfile.\n\nSetting this sysprop requires your Composer HAL implementation to correctly\nhandle multiple `setLayerBuffer` commands for the same layer in a single\npresent cycle.\n\nEnabling the backward-compatible option has the following affects:\n\n- For AIDL HALs: SurfaceFlinger sends multiple `LayerCommand` instances for a\n single layer, each with a single `BufferCommand`. Each `BufferCommand` contains a 1x1\n placeholder buffer handle and a slot number for the cache buffer slot that\n needs to be purged.\n\n- For HIDL HALs: SurfaceFlinger sends multiple `SELECT_DISPLAY`,\n `SELECT_LAYER`, `SET_BUFFER` commands. These commands contain a 1x1 placeholder\n buffer handle and a slot number for the cache buffer slot that needs to be\n purged.\n\nThe backward-compatible option might cause the Composer HAL to crash on some\ndevices. You might be able to modify your Composer HAL to solve this issue. The\ncode controlling this behavior is found here:\n\n- [SurfaceFlinger code for AIDL HALs](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp#854)\n\n- [SurfaceFlinger code for HIDL HALs](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp#718)\n\nTest graphics buffer cache memory consumption\n---------------------------------------------\n\nTests can't verify whether the cache slots are purged by HAL\nimplementations. However, you can use your debugging tools to monitor\ngraphic buffer usage. As you monitor, you should notice that there are fewer\nout-of-memory errors in scenarios where multiple different videos are stopped\nand started in quick succession on YouTube.\n\nVTS tests are available that verify that the HAL implementation is\nfunctionally capable of receiving the new API calls (HAL version 3.2+) or\nmultiple `setLayerBuffer` commands for the backward-compatible\nimplementation. However, this shouldn't be considered sufficient testing for\nproper functionality, as some devices pass these VTS tests,\nbut fail during real-world use cases.\n\nFor new VTS tests, navigate to the following links:\n\n- HIDL compatible: [`GraphicsComposerHidlCommandTest::SET_LAYER_BUFFER_multipleTimes`](https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/android16-release/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp#891)\n\n- AIDL 3.1 compatible: [`GraphicsComposerAidlCommandTest::SetLayerBufferMultipleTimes`](https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/android16-release/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp#1817)\n\n- AIDL 3.2: [`GraphicsComposerAidlCommandV2Test::SetLayerBufferSlotsToClear`](https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/android16-release/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp#1770)"]]