在图形堆栈中,每层缓冲区缓存位于 Composer HAL 和 SurfaceFlinger 之间,以减少通过 IPC 发送文件描述符相关的开销。在 Android 14 之前,当 GraphicBufferProducer
与 SurfaceFlinger GraphicBufferConsumer
断开连接时(例如当 MediaCodec 与 SurfaceView 断开连接时),此缓冲区缓存不会被清除。从 Android 14 开始,您可以强制清除此缓冲区缓存,以减少图形内存消耗。
从以下两个选项中选择一个
- 对于搭载 Android 14 及更高版本推出的设备,您必须实现新的 Composer HAL API 版本 3.2。默认情况下,此选项处于启用状态,并且可以节省最多的内存。升级到 14 及更高版本的设备也可以使用此选项来实现全面的内存优势。
- 对于要升级到 Android 14 但又不想实现 Composer HAL 3.2 API 的设备,您可以启用向后兼容选项。此选项几乎可以节省与之前选项一样多的内存。
以下两节将介绍如何实现每个选项。
实现 Composer HAL 3.2 API
要实现完整的图形缓冲区内存优势,您必须
- 将您的 Composer HAL 实现更新到 3.2 版本。
- 处理
LayerCommand::bufferSlotsToClear
,方法是清除列表中指示的槽号所指示的缓冲区缓存条目。
与图形缓冲区内存相关的 Composer HAL 3.2 API,包括 LayerCommand:bufferSlotsToClear
,位于 LayerCommand.aidl-
中。
启用向后兼容选项
向后兼容的内存缩减选项会将缓存槽中的真实缓冲区替换为 1x1 占位符缓冲区,从而为所有清除的槽(当前活动缓冲区槽除外)节省内存。要实现部分内存节省优势,请将 surface_flinger.clear_slots_with_set_layer_buffer
系统属性设置为 true
,从而启用向后兼容选项。此系统属性位于 property_contexts
文件中。
设置此系统属性要求您的 Composer HAL 实现正确处理单个 present 周期中同一图层的多个 setLayerBuffer
命令。
启用向后兼容选项具有以下影响
对于 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 测试,但在实际使用场景中却失败了。
对于新的 VTS 测试,请导航到以下链接