Systrace 工具分析Vsync

408 阅读3分钟

这篇文章通俗地讲解了 Android 中 Vsync(垂直同步)机制的核心原理,以及如何通过 Systrace 工具观察和分析 Vsync 信号对屏幕渲染的影响,核心内容如下:

一、Vsync:屏幕刷新的 “指挥家”

Vsync 是一种周期性信号(如 60Hz 屏幕对应 16.6ms / 次),作用是同步应用渲染和屏幕刷新,避免画面撕裂或卡顿,就像乐队指挥确保乐器演奏节奏一致:

  • 硬件生成:由 HWC(硬件合成器)产生原始 Vsync 信号,分为两类:

    • VSYNC_APP:通知应用 “可以开始渲染新一帧”(如微信界面刷新)。
    • VSYNC_SF:通知 SurfaceFlinger “可以合成已渲染的帧并显示到屏幕”(如将微信界面与状态栏合成)。
  • 关键作用:若应用渲染和屏幕刷新不同步,会导致卡顿(如滑动列表时画面跳帧)。

二、Vsync 如何协调渲染流程?

以滑动微信列表为例,流程如下:

  1. 应用渲染阶段

    • 手机收到 VSYNC_APP 信号,微信主线程开始计算列表位置、绘制图标(measure/layout/draw)。
    • 渲染完成后,将画面数据存入 BufferQueue(类似 “待显示的画稿仓库”)。
  2. 屏幕合成阶段

    • 约 16.6ms 后,SurfaceFlinger 收到 VSYNC_SF 信号,从 BufferQueue 取出微信的画稿,与状态栏、导航栏合成,发送到屏幕显示。
  3. 理想状态:每 16.6ms 完成一次 “渲染 + 合成”,实现 60fps 流畅效果。

三、Systrace 中的 Vsync 信号长啥样?

通过 Systrace 可看到两种绿色标记:

  • VSYNC-app:应用进程中的绿色凸起,代表应用开始渲染新一帧。

  • VSYNC-sf:SurfaceFlinger 进程中的绿色凸起,代表开始合成帧。

  • 关键观察点

    • 正常情况下,两者周期均为 16.6ms,且间隔固定。
    • 若 VSYNC-app 后应用渲染耗时超过 16.6ms,会导致下一次 VSYNC-sf 时无新画稿,出现掉帧(卡顿)。

四、Offset:优化渲染时机的 “时间差”

厂商可配置 VSYNC_APP 和 VSYNC_SF 的时间差(Offset),类似调整快递员和收件人的时间差:

  • 案例

    • 若 Offset=4ms,应用先收到 VSYNC_APP 开始渲染,4ms 后 SurfaceFlinger 收到 VSYNC_SF 开始合成。
    • 若应用渲染快(<4ms),合成时能拿到新画稿,提前显示,减少延迟。
  • 风险

    • 若 Offset 设太短(如 1ms),应用可能没渲染完,合成时仍拿旧画稿,反而增加延迟。
    • 设太长则失去优化意义,因此多数厂商默认不配置。

五、图形数据流:从渲染到显示的 “流水线”

  1. 应用端

    • 收到 VSYNC_APP → 主线程计算布局 → 渲染线程画图标 → 存入 BufferQueue。
  2. 系统端

    • 收到 VSYNC_SF → SurfaceFlinger 取出画稿 → 与其他图层合成 → 发送到屏幕。

  • Systrace 中的阶段

    • 应用端:绿色 Frame 标记(渲染完成)。
    • 系统端:SurfaceFlinger 的 onMessageReceived(合成开始)。

六、如何用 Vsync 分析卡顿?

  1. 看信号间隔

    • 若 VSYNC-app 周期变长(如 > 16.6ms),说明应用渲染慢(如列表数据过多)。
  2. 看队列状态

    • BufferQueue 中 “Ready Buffer” 数量为 0,说明应用没及时渲染,SurfaceFlinger 拿不到新画稿。
  3. 看 Offset 效果

    • 配置合理 Offset 后,VSYNC-sf 能提前拿到画稿,减少显示延迟(如游戏场景更跟手)。

七、总结:Vsync 是流畅体验的 “心跳”

Vsync 就像手机的 “心跳”,每 16.6ms 跳动一次,协调应用和屏幕同步工作。通过 Systrace 观察 Vsync 信号和 Offset 配置,可定位渲染瓶颈(如应用主线程卡顿、合成延迟),帮助优化滑动流畅度、游戏帧率等体验。理解这套机制后,开发者能更精准地解决 “滑动卡顿”“画面撕裂” 等问题。