VSync 虚拟化
为了提高UI的响应速度, Android重新设计了VSync的相应逻辑。
- 先来看下
VSync
的响应:
VSync
到来,SF
和App
同时接收到VSync
, 这个时候SF
肯定需要等待App
端把UI绘制完毕, 然后才能进行混合输出. 这个时候SF
先休眠然后再唤醒,这里肯定涉及到CPU的上下文调度, 需要消耗一定的时间。 - 做一个假设:
VSync
到来,App
先接收到VSync
, 然后SF
等待一段时间再接收到这个VSync
, 如果App
绘制UI比较快, 则等到SF
唤醒的时候, 无需等待就可以继续工作了, 这里就避免了一次CPU的调度。 -
总结
Android 就是考虑到上面的这个假设, 设计了虚拟化的VSync
.
DispSync
接收到VSync
之后, 先发给App
然后过段时间再发给SF
.
SF中传递线程关联方式
通过上面介绍了解到, SF
收到 HWC
传递过来的VSync
, 先传递到 DispSyncThread
(VSync
分发线程), 然后分发给 EventThread
(VSync
处理线程)。
看图中粉红色线部分:
1: EventThread
(VSync
处理线程)启动之后, 进入 threadLoop
循环, 调用 waitForEvent
方法, 激活整个传递流程。
2: waitForEvent
调用 enableVSyncLocked
。
2-1:enableVSyncLocked
第一步把 EventThread
自己设置为 DispSyncSource
的回调。
2-2:DispSyncSource
通过setVSyncEnabled
把自己添加到 DispSync
的回调 mEventListeners
中。
PS
:DispSync
和 DispSyncSource
的初始化都在SF
的init
中。 这里都比较简单, 画出来图就太多线了。
SF中VSync的传递
图中绿线部分, 接着上节传递的位置 onVSyncReceived
。
整个流程跟着箭头走比较清晰, 其中涉及到三次跨线程交互。
前两次都是通过 Condition
进行唤醒的, 最后一次通过的是本地套接字
唤醒的。