Android 4.4(KitKat)中VSync信号的虚拟化

原文地址:http://blog.csdn.net/jinzhuojun/article/details/17293325

Android 4.1(Jelly Bean)引入了Vsync(Vertical Syncronization)用于渲染同步,使得App UI和SurfaceFlinger可以按硬件产生的VSync节奏来进行工作。关于VSync的介绍详见博文http://www.androidpolice.com/2012/07/12/getting-to-know-android-4-1-part-3-project-butter-how-it-works-and-what-it-added/。引用该博文的一张图来作为本文的开头:
这里写图片描述
虽然大家都同步了,但新的问题产生了:
1. App UI和SurfaceFlinger的工作显然是一个流水线的模型。即对于一帧内容,先等App UI画完了,SurfaceFlinger再出场对其进行合并渲染后放入framebuffer,最后整到屏幕上。而现有的VSync模型是让大家一起开始干活。这样对于同一帧内容,第一个VSync信号时App UI的数据开始准备,第二个VSync信号时SurfaceFlinger工作,第三个VSync信号时用户看到内容,这样就两个VSync period(每个16ms)过去了。这会影响用户体验。
2.计算机资源是有限的,大家一起做事,都抢资源,必然导致工作加倍的慢。

Android 4.4(KitKat)引入了VSync的虚拟化,即把硬件的VSync信号先同步到一个本地VSync模型中,再从中一分为二,引出两条VSync时间与之有固定偏移的线程。示意图如下:
这里写图片描述
这样,大家工作既保持一定的节拍,又可以相互错开,一前一后保持着咚次哒次,咚次哒次的流水节奏了:) 注意其中两个Phase offset参数(即VSYNC_EVENT_PHASE_OFFSET_NS和SF_VSYNC_EVENT_PHASE_OFFSET_NS)是可调的。

相关的主要创建流程在DispSync::DispSync():

以及SurfaceFlinger::init()中:

292DispSync::DispSync() {
293 mThread = new DispSyncThread();
294 mThread->run(“DispSync”, PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);

604    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,  
605            vsyncPhaseOffsetNs, true);  
606    mEventThread = new EventThread(vsyncSrc);  
607    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,  
608            sfVsyncPhaseOffsetNs, false);  
609    mSFEventThread = new EventThread(sfVsyncSrc);  
610    mEventQueue.setEventThread(mSFEventThread);  
611  
612    mEventControlThread = new EventControlThread(this);  
613    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); 

相关的类图如下:
这里写图片描述
如果上图不怎么直观的话,下面这张用序列图表示的线程模型图应该更好理解一点:
这里写图片描述
类型DispSync表示了一个基于硬件VSync信号的同步模型,它会根据从HWComposer来的硬件VSync信号的采样来进行同步。其它两个EventThread分别用了两个不同的虚拟VSync信号源(用DispSyncSource表示,其中包含了与真实VSync信号的偏移值),这两个VSync信号源就是被虚拟出来分别用于控制App UI和SurfaceFlinger渲染的。在EventThread的线程循环中,如果有需要就会向DispSync注册相应的listener。DispSyncThread就像乐队鼓手一样控制着大家的节奏。它在主循环中会先通过已经向DispSync注册的listener计算下一个要产生的虚拟VSync信号还要多久,等待相应时间后就会调用相应listener的callback函数。这样,对于那些注册了listener的监听者来说,就好像被真实的VSync信号控制着一样。至于EventControlThread是用来向真实的VSync硬件发命令的,可以先不管。

看来谷歌对于大家对Android UI流畅性的吐槽也已经很郁闷了,才会把VSync整这么麻烦。不过这样做缺点是引入了需要tune的参数,如果设不好结果可能也好不到哪去,将来会不会通过一些统计手段来让这两个参数自适应呢?

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值