VSYNC 信号可同步显示流水线。显示流水线包括应用渲染、SurfaceFlinger 合成以及硬件合成器 (HWC) 在显示屏上呈现图像。VSYNC 可同步应用唤醒以开始渲染的时间、SurfaceFlinger 唤醒以合成屏幕的时间以及显示屏刷新周期。这种同步可消除画面撕裂现象并提高图形的视觉性能。
HWC 生成 VSYNC 事件,并通过回调将事件发送到 SurfaceFlinger
typedef void (*HWC2_PFN_VSYNC)(hwc2_callback_data_t callbackData, hwc2_display_t display, int64_t timestamp);
SurfaceFlinger 通过调用 setVsyncEnabled
来控制 HWC 是否生成 VSYNC 事件。SurfaceFlinger 启用 setVsyncEnabled
以生成 VSYNC 事件,以便它可以与显示屏的刷新周期同步。当 SurfaceFlinger 与显示屏刷新周期同步时,SurfaceFlinger 会停用 setVsyncEnabled
以停止 HWC 生成 VSYNC 事件。如果 SurfaceFlinger 检测到实际 VSYNC 与之前建立的 VSYNC 之间存在差异,SurfaceFlinger 会重新启用 VSYNC 事件生成。
VSYNC 偏移
同步应用和 SurfaceFlinger 渲染循环到硬件 VSYNC。在 VSYNC 事件中,显示屏开始显示帧 N,而 SurfaceFlinger 开始合成帧 N+1 的窗口。应用处理待处理的输入并生成帧 N+2。
与 VSYNC 同步可提供一致的延迟。它可以减少应用和 SurfaceFlinger 中的错误,并最大限度地减少显示屏彼此之间的相位漂移。这假设应用和 SurfaceFlinger 的每帧时间不会发生很大变化。延迟至少为两帧。
为了解决这个问题,您可以采用 VSYNC 偏移来减少输入到显示的延迟,方法是使应用和合成信号相对于硬件 VSYNC。之所以可行,是因为应用加合成通常需要不到 33 毫秒的时间。
VSYNC 偏移的结果是三个具有相同周期和偏移相位的信号
HW_VSYNC_0
— 显示屏开始显示下一帧。VSYNC
— 应用读取输入并生成下一帧。SF_VSYNC
— SurfaceFlinger 开始合成下一帧。
使用 VSYNC 偏移,SurfaceFlinger 接收缓冲区并合成帧,同时应用同步处理输入和渲染帧。
DispSync
DispSync 维护显示屏基于硬件的周期性 VSYNC 事件模型,并使用该模型在相对于硬件 VSYNC 事件的特定相位偏移处执行回调。
DispSync 是一个软件锁相环 (PLL),即使未从硬件 VSYNC 偏移,它也会生成 Choreographer 和 SurfaceFlinger 使用的 VSYNC 和 SF_VSYNC 信号。

图 1. DispSync 流程
DispSync 具有以下特性
- 参考 — HW_VSYNC_0。
- 输出 — VSYNC 和 SF_VSYNC。
- 反馈 — 来自硬件合成器的 Retire fence 信号时间戳。
VSYNC/retire 偏移
Retire fence 的信号时间戳必须与 HW VSYNC 匹配,即使在不使用偏移相位的设备上也是如此。否则,错误看起来会比实际情况更严重。智能面板通常具有一个增量,其中 retire fence 是对显示内存进行直接内存访问 (DMA) 的结束,但实际的显示切换和 HW VSYNC 会晚一些。
PRESENT_TIME_OFFSET_FROM_VSYNC_NS
在设备的 BoardConfig.mk
makefile 中设置。它基于显示控制器和面板特性。从 retire fence 时间戳到 HW VSYNC 信号的时间以纳秒为单位进行测量。
VSYNC 和 SF_VSYNC 偏移
VSYNC_EVENT_PHASE_OFFSET_NS
和 SF_VSYNC_EVENT_PHASE_OFFSET_NS
根据高负载用例保守设置,例如窗口转换期间的部分 GPU 合成或 Chrome 滚动浏览包含动画的网页。这些偏移允许较长的应用渲染时间和较长的 GPU 合成时间。
超过一毫秒或两毫秒的延迟是明显的。为了在最大限度地减少延迟的同时又不显著增加错误计数,请集成全面的自动化错误测试。