屏幕垂直同步信号(VSYNC)
屏幕的垂直同步信号(Vertical Sync,简称 VSYNC) 是硬件层面由屏幕显示控制器发出的周期性同步触发信号,是协调 CPU/GPU 渲染节奏与屏幕刷新节奏的核心机制,直接决定了 UI 渲染的流畅性。
一、 VSYNC 的核心背景:屏幕显示原理
要理解 VSYNC,首先要知道屏幕的逐帧刷新机制:
屏幕的刷新方式:无论是手机、电脑显示器,本质都是逐行扫描像素来显示一帧画面。
- 对 LCD/OLED 屏幕,显示控制器会从屏幕左上角开始,逐行向像素发送显示数据,直到右下角,完成一帧画面的扫描。
- 扫描完成后,显示控制器会回到左上角,准备扫描下一帧,这个「回到起点」的过程称为 垂直消隐期(Vertical Blank Interval, VBI)。
刷新率(Refresh Rate):屏幕每秒能完成的「整帧扫描次数」就是刷新率,单位是 Hz。
- 常见的屏幕刷新率:60Hz(每 16.67ms 刷新一次)、90Hz(11.11ms)、120Hz(8.33ms)、144Hz(6.94ms)。
- 刷新率是屏幕的硬件属性,决定了 VSYNC 信号的周期。
二、 VSYNC 信号的本质与作用
1. 信号本质
VSYNC 信号是在每帧扫描完成、进入垂直消隐期时,由显示控制器发出的一个硬件中断信号。
- 触发时机:刚好在「上一帧显示完成,下一帧准备开始」的临界点。
- 信号周期:等于屏幕的帧间隔时间,例如 60Hz 屏幕的 VSYNC 周期是
1000ms / 60 ≈ 16.67ms。
2. 核心作用:解决「撕裂」与「浪费」
没有 VSYNC 时,CPU/GPU 渲染完一帧数据就直接提交给屏幕,会导致两个严重问题:
| 问题 | 现象 | 危害 |
|---|---|---|
| 画面撕裂 | 屏幕正在显示上一帧的下半部分时,GPU 提交了新帧的上半部分,导致屏幕上下两部分显示不同帧的内容,出现明显的「分割线」 | 严重影响视觉体验,动画 / 滑动时尤为明显 |
| 资源浪费 | CPU/GPU 渲染速度远超屏幕刷新率(如 GPU 10ms 渲染一帧,屏幕 16.67ms 刷新一次),多余的渲染帧会被丢弃 | 白白消耗 CPU/GPU 资源,增加功耗 |
VSYNC 信号的核心价值就是强制 CPU/GPU 的渲染节奏与屏幕刷新节奏对齐:
- 只有收到 VSYNC 信号,CPU/GPU 才会开始渲染下一帧数据。
- 渲染完成后,刚好赶上屏幕的下一次刷新,直接显示新帧,既避免撕裂,又减少资源浪费。
三、 VSYNC 在 Android 系统中的工作流程
在 Android 中,VSYNC 信号不仅是屏幕的硬件信号,还会通过系统服务传递给应用层,成为 Choreographer 调度 UI 渲染的核心触发源,完整流程如下:
硬件层触发 VSYNC
显示控制器完成一帧扫描,进入垂直消隐期,发出 VSYNC 硬件信号。
系统层分发信号
Android 系统的 SurfaceFlinger(负责屏幕合成的核心服务)接收 VSYNC 信号,一方面触发屏幕刷新新帧,另一方面通过 DisplayEventReceiver 将信号分发到应用进程。
应用层响应信号
应用进程的
Choreographer接收到 VSYNC 信号后,按优先级执行四大任务队列(INPUT → ANIMATION → TRAVERSAL → COMMIT),其中TRAVERSAL队列会触发 View 树的measure/layout/draw流程,生成新的帧数据。提交渲染数据
应用将渲染好的帧数据提交给 SurfaceFlinger,SurfaceFlinger 合成后,等待下一个 VSYNC 信号到来时,将新帧显示到屏幕上。
Android 应用的 UI 渲染**不是主动触发的,而是被动等待 VSYNC 信号触发的,Choreographer 就是这个等待机制的「调度者」。
四、 VSYNC 与流畅性的关系
UI 流畅的核心标准是 「每帧渲染耗时 ≤ VSYNC 周期」:
- 对 60Hz 屏幕,每帧渲染必须在 16.67ms 内完成,否则会掉帧(错过当前 VSYNC 周期,只能等到下一个周期显示,相当于 2 个周期显示 1 帧,帧率降到 30Hz)。
- 对 120Hz 屏幕,每帧渲染需在 8.33ms 内完成,对性能要求更高,但流畅度也更好。
举个例子:
- 正常情况:60Hz 屏幕,每 16.67ms 收到一次 VSYNC,CPU/GPU 10ms 完成渲染,准时显示 → 帧率 60Hz,流畅。
- 卡顿情况:某一帧因为主线程阻塞(如执行耗时 I/O),渲染耗时 20ms → 错过本次 VSYNC,只能等下一次 → 这 33.34ms 只显示 1 帧,帧率降到 30Hz → 视觉上出现卡顿。
五、 关键补充:「垂直同步」开关的含义
很多游戏或视频应用会有「垂直同步」开关,其本质是:
- 开启:强制 GPU 渲染节奏与 VSYNC 同步,避免画面撕裂,但如果渲染速度跟不上刷新率,会导致帧率被限制在刷新率(如 60Hz)。
- 关闭:GPU 渲染不受 VSYNC 限制,渲染速度快于刷新率时会出现画面撕裂,但帧率可能超过屏幕刷新率(适合追求极限帧率的场景)。
而 Android 应用的 UI 渲染默认是强制开启 VSYNC 同步的,无法手动关闭,这是保证系统 UI 流畅性的基础。