3. 显示与合成基础

在 Android 座舱图形系统中,应用绘制的画面并不会直接写入屏幕,而是先进入 SurfaceFlinger 的合成流水线,再通过显示控制器扫描输出。理解 Layer 合成、VSync、Triple Buffer、Fence 与显示时序,是后续定位掉帧、撕裂、延迟和卡顿问题的前提。本节从数据流角度梳理这些基础概念,并给出量产调优中常用的观察点。

一、Layer 合成:从 Surface 到最终帧

每个窗口、视频层、状态栏或仪表卡片,在系统中通常对应一个 Layer。Layer 持有自己的 BufferQueue,应用或渲染线程作为生产者提交图形缓冲,SurfaceFlinger 作为消费者按 Z 序、可见区域、透明度、变换矩阵等属性进行合成。合成方式主要有两种:

  • GPU 合成:SurfaceFlinger 使用 RenderEngine 将多个 Layer 绘制到一张目标缓冲,兼容性强,但消耗 GPU 与带宽。
  • 硬件合成:由显示控制器 DPU/Display 的叠加器直接读取多个 Layer 的物理地址,在扫描输出时完成叠加,功耗和延迟更优,但受层数、格式、缩放比例和跨屏限制。

量产调优中,应优先让关键 Layer 走硬件合成,例如仪表、HUD、倒车影像和视频层。若因格式或缩放导致回退到 GPU 合成,往往会引起带宽上升和帧率波动。可通过以下命令观察合成类型:

adb shell dumpsys SurfaceFlinger --latency
adb shell dumpsys SurfaceFlinger | grep -i "composition"
adb shell dumpsys SurfaceFlinger --list

二、VSync、Triple Buffer 与显示时序

VSync 是显示时序的节拍信号,表示一帧扫描完成、可以开始下一帧的边界。Android 采用 Vsync 调度应用绘制、SurfaceFlinger 合成和显示提交。若只有双缓冲,应用在缓冲被显示占用时无法写入,容易阻塞;Triple Buffer 增加一个缓冲,使应用、合成和显示可以并行推进,从而吸收短时抖动,但也会增加一帧左右的延迟。

显示时序由刷新率、消隐区、扫描行数和像素时钟共同决定。以 60Hz 为例,每帧约 16.67ms;120Hz 则约 8.33ms。帧率不是单一数字,而是应用绘制帧率、合成帧率和显示刷新率共同作用的结果。若应用只能稳定输出 45fps,而屏幕以 60Hz 扫描,就会出现节奏不匹配,表现为抖动或重复帧。

显示与合成流水线:Layer → BufferQueue → SurfaceFlinger → Display 应用 / RenderThread 绘制 Layer 内容 dequeue / queue BufferQueue 生产者 / 消费者 Triple Buffer 缓冲池 SurfaceFlinger Layer 排序 / 合成 GPU 或硬件合成 Display 控制器 扫描输出 / 刷新率 VSync 节拍 Fence 同步链 acquire Fence release Fence present / retire Fence Fence 未就绪 → 合成等待或丢帧 显示时序与帧率关系 VSync VSync VSync VSync VSync VSync App 绘制 SF 合成 Display 扫描 App 绘制 SF 合成

三、Fence 机制:跨模块同步的关键

Fence 是 Android 图形栈中用于跨进程、跨硬件同步的机制。它表示某个缓冲何时可被安全读取或写入。常见类型包括:

  • acquire Fence:消费者在读取缓冲前等待该 Fence 信号,确保生产者已写完。
  • release Fence:生产者等待消费者释放缓冲后才能复用,避免覆盖正在显示的内容。
  • present/retire Fence:用于确认帧是否真正上屏,是分析显示延迟的重要依据。

如果 Fence 长时间未触发,SurfaceFlinger 会等待或跳过该 Layer,表现为合成超时、掉帧或画面冻结。量产问题中,常见根因包括 GPU 负载过高、驱动提交延迟、DMA-BUF 导入失败或显示控制器带宽不足。

四、核心参数与观察点

概念 作用 量产观察点
Layer 窗口或视频层的图形单元 层数、格式、缩放、Z 序
VSync 绘制与显示的节拍基准 相位偏移、丢 VSync、刷新率切换
Triple Buffer 吸收绘制与合成抖动 缓冲占用、延迟增加、内存带宽
Fence 跨模块缓冲同步 等待时长、超时、present 延迟
显示时序 决定扫描与刷新节奏 帧率匹配、撕裂、抖动

五、案例与误区复盘

某座舱项目在 60Hz 屏幕上运行导航与仪表双屏,用户反馈仪表指针偶发跳动。排查发现仪表 Layer 因使用了非硬件支持格式,被回退到 GPU 合成,同时 acquire Fence 等待时间超过 8ms,导致部分帧错过 VSync。优化措施包括:将仪表 Layer 改为硬件合成支持的格式、减少不必要的缩放、把关键 Layer 提升到独立平面,并调整 Triple Buffer 数量以平衡延迟与抖动。

常见误区:把“帧率低”简单归因于应用绘制慢。实际上,VSync 相位错位、Fence 等待、硬件合成回退、显示带宽不足都可能造成掉帧。调优时应先确认瓶颈位于应用、SurfaceFlinger 还是显示控制器,再决定优化方向。

调优建议:优先保证关键 Layer 走硬件合成;用 present Fence 统计端到端延迟;在刷新率切换场景下检查 VSync 相位是否稳定;对 Triple Buffer 的收益与延迟代价做量化评估,而不是盲目增加缓冲。

掌握这些基础概念后,后续分析掉帧、撕裂、延迟和卡顿问题时,就能沿着“应用绘制 → BufferQueue → SurfaceFlinger 合成 → Fence 同步 → 显示扫描”的链路逐段定位,而不是停留在现象层面。