在图形堆栈中,每层的缓冲区缓存位于混合渲染器 HAL 和 SurfaceFlinger 之间,从而减少与通过 IPC 发送文件描述符相关的开销。在 Android 14 之前的版本中,当 GraphicBufferProducer
与 SurfaceFlinger GraphicBufferConsumer
断开连接时(例如 MediaCodec 与 SurfaceView 断开连接时),此缓冲区缓存不会被完全清除。从 Android 14 开始,您可以强制完全清除此缓冲区缓存,以减少图形的内存消耗。
从以下两个选项中选择一项:
- 对于发布时搭载 Android 14 及更高版本的设备,您必须实现新的 3.2 版混合渲染器 HAL API。此选项在默认情况下处于启用状态,并能最大限度地节省内存。升级到 Android 14 及更高版本的设备也可以使用此选项来实现全部内存优势。
- 对于升级到 Android 14 的设备,如果您不想实现混合渲染器 HAL 3.2 API,可以改为启用向后兼容选项。此选项节省的内存几乎与上一个选项一样多。
以下两部分介绍了如何实现各个选项。
实现混合渲染器 HAL 3.2 API
如需实现全部图形缓冲区内存优势,您必须:
- 将混合渲染器 HAL 实现更新到版本 3.2。
- 在列表中找到相应的槽号,通过完全清除其所指示的缓冲区缓存条目来处理
LayerCommand::bufferSlotsToClear
。
与图形缓冲区内存相关的混合渲染器 HAL 3.2 API(包括 LayerCommand:bufferSlotsToClear
)位于 LayerCommand.aidl-
。
启用向后兼容选项
向后兼容的内存节省选项将缓存槽中的实际缓冲区替换为 1x1 占位符缓冲区,从而节省所有已完全清除的槽(当前活跃缓冲区槽除外)的内存。如需实现部分内存节省优势,请通过将 surface_flinger.clear_slots_with_set_layer_buffer
sysprop 设为 true
来启用向后兼容选项。此 sysprop 位于 property_contexts
文件内。
若要设置此 sysprop,您的混合渲染器 HAL 实现必须能在单个当前周期中正确处理同一层的多个 setLayerBuffer
命令。
启用向后兼容选项会产生以下影响:
对于 AIDL HAL:SurfaceFlinger 为单个层发送多个
LayerCommand
实例,其中每个实例都包含一个BufferCommand
。每个BufferCommand
都包含 1x1 占位符缓冲区句柄和需要完全清除的缓存缓冲区槽的槽号。对于 HIDL HAL:SurfaceFlinger 发送多个
SELECT_DISPLAY
、SELECT_LAYER
、SET_BUFFER
命令。这些命令都包含 1x1 占位符缓冲区句柄和需要完全清除的缓存缓冲区槽的槽号。
向后兼容的选项可能会导致混合渲染器 HAL 在某些设备上崩溃。您或许可以通过修改混合渲染器 HAL 来解决此问题。用于控制此行为的代码的位置如下:
测试图形缓冲区缓存内存消耗
测试无法验证缓存槽是否已被 HAL 实现完全清除。不过,您可以使用调试工具来监控图形缓冲区使用情况。在监控过程中,您应该会注意到,在 YouTube 上连续快速停止和开始播放多个不同的视频时,内存不足的错误减少了。
VTS 测试可验证 HAL 实现在功能上能否接收新的 API 调用(HAL 版本 3.2 及更高版本)或多个 setLayerBuffer
命令,以实现向后兼容。不过,这不应被视为对功能正常的充分测试,因为某些设备可能通过了这些 VTS 测试,但在实际用例中却失败了。
对于新的 VTS 测试,请导航至以下链接: