VSync的虚拟化
由上面的介绍可以知道,VSync其实起源于显示屏,但是想想如果每个App和SurfaceFlinger都去从硬件驱动中直接监听VSync,那未免有点太复杂了,而且耦合性太高,不行。那怎么办呢?
因此,最好是有一个模块去专门跟驱动沟通,再由它将VSync信号广播给大家,就像一个hub一样。但是VSync频率这么高,每次从kernel到userspace的消耗也不少,而且VSync是周期性的,很容易猜,所以没必要一直从kernel监听,但是系统是一直需要VSync来控制绘制合成的,所以有必要搞一个虚拟的VSync来模拟硬件VSync了。大概架构如下图:
其中SurfaceFlinger中的DisplayVSync(Android S后改名为VsyncController)就是虚拟的VSync源,其需要两个参数来保证与硬件VSync的同步性,第一是参考点,第二就是周期。这些都可以开启硬件VSync同步解决。
VSync的同步
VSync虚拟化的实质就是在软件层面模拟硬件VSync,既然是软件模拟,那么就会存在误差,如果误差比较大,那么就需要开启硬件VSync同步来进行校准。那么就存在两个问题,怎么发现自己误差比较大?以及怎么来同步?
首先是如何发现误差比较大?答案是通过fence机制。SurfaceFlinger在每一帧交给HWC的时候,同时都会从HWC那里得到此帧的PresentFence,它是在此帧开始刷新至屏幕的时候signal的。那驱动什么时候开始刷新一帧至屏幕呢,答案是屏幕VSync来的时候。所以这下就能串起来了。根据PresentFence的signal时间就可以知道真实的VSync时间,那么之后的事情就简单了。
在HWComposer::presentAndGetReleaseFences中获取PresentFence,
获取到fence之后就会对齐进行监测
一旦不准就开硬件VSync来进行校准,通常情况下接收六次硬件VSync就可以完成校准动作。
全部0条评论
快来发表一下你的评论吧 !