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函数。