Android 4.1(Jelly Bean)
引入了
Vsync(Vertical Syncronization)
用于渲染同步,使得
App UI
和
SurfaceFlinger
可以按硬件产生的
VSync
节奏来进行工作。
图
1 VSync
模型
上述模型存在以下问题:
1.
对于一帧内容,必须先等
App UI
画完了,
SurfaceFlinger
才能对其进行合并渲染。这样对于同一帧内容,第一个
VSync
信号时
App UI
的数据开始准备,第二个
VSync
信号时
SurfaceFlinger
工作,第三个
VSync
信号时用户看到内容,这样就两个
VSync period(
每个
16ms)
过去了。这会影响用户体验。
2.
计算机资源是有限的,大家一起做事,都抢资源,必然导致工作加倍的慢。
为了解决上述问题,增加系统的流畅性,
Android 4.4(KitKat)
引入了
VSync
的虚拟化,
SF
和
App
不再直接使用
HW vsync
。
KitKat
建立了一个
vsync
模型,该模型对硬件
VSync
进行采样、处理,然后产生带有相位偏移的两个
vsync
信号供
SF
和
APP
使用。模型如下图所示:
图
2 DispSync
的
PLL
模型
需要注意的是
DispSync
内部统计了产生的
SW vsync
和
HW vsync
的误差,在不需要
HW vsync
时会关闭
HW vsync
,在误差太大的情况下会重
新使能
HW vsync
,对
HW vsync
进行重新采样、更新模型参数,这样
SW vsync
能与
HW vsync
更加的精确,不至于误差太大。
VSYNC
工作时序图如下:
图
3 vsync
工作时序图
这样,
APP
和
SF
既保持一定的节拍,又可以相互错开,一前一后保持着节奏。需要注意的是其中两个
Phase offset
参数(即
VSYNC_EVENT_PHASE_OFFSET_NS
和
SF_VSYNC_EVENT_PHASE_OFFSET_NS
)是可调的。
相关的类图如下:
图
4 vsync
模型类图
DispSync
类表示了一个基于硬件
VSync
信号的同步模型,它会根据从
HWComposer
来的硬件
VSync
信号的采样来进行同步。其它两个
EventThread
分别用了两个不同的虚拟
VSync
信号源(用
DispSyncSource
表示,其中包含了与真实
VSync
信号的偏移),这两个
VSync
信号源就是被虚拟出来分别用于控制
App UI
和
SurfaceFlinger
渲染的。在
EventThread
的线程循环中,如果有需要就会向
DispSync
注册相应的
listener
。
DispSyncThread
在主循环中会先通过已经向
DispSync
注册的
listener
计算下一个要产生的虚拟
VSync
信号还要多久,等待相应时间后就会调用相应
listener
的
callback
函数。