3缓冲策略:在android4.1后提供了3缓冲策略。
CPU GPU 和display各使用一个buffer。三缓冲有效利用了的等待Vysnc信号的时间,减少jank,但是带来了延迟。buffer并不是越多越好,buffer正在是两个,出现jank后才会有第三个。
系统在收到Csync通知时,CPU、GPU就立即开始计算然后把数据写入buffer。其中比较重要的一个类是:
Choreographer(编舞者).应用层一般可以实现它的内部接口FrameCallBack来监控应用帧率。
{08EB6B39-C1C2-8866-BF75-A157D5C6B538}.jpg
Choreographer是单例模式,还有一个内部类是FlameDisplayEventReceiver。他有一个onVsync的方法用于接收垂直同步信号。这个垂直同步信号并不是每16.7毫秒就会执行一次,而是需要申请获取。如何申请呢,就是UI需要绘制的时候,比如调用requestLayout或者View.invalidate或者ValueAnimator.start方法时,就会申请获取垂直同步信号。这些方法最终都会调用ViewRootImpl.scheduleTraversals()方法。ViewRootImpl.scheduleTraversals()里就会发送同步屏障。然后调用了Choreographer.postCallBack方法去申请垂直同步信号,同时把需要执行的绘制流程扔到一个runnable里,垂直同步信号来到时就会执行doFrame,然后发送一个异步消息,去执行刚才runnable里的绘制流程。执行绘制流程之前会先移除同步屏障。
1、丢帧(掉帧) ,是说 这一帧延迟显示 还是丢弃不再显示 ?
答:延迟显示,因为缓存交换的时机只能等下一个VSync了。
布局层级较多/主线程耗时 是如何造成 丢帧的呢?
答:布局层级较多/主线程耗时 会影响CPU/GPU的执行时间,大于16.6ms时只能等下一个VSync了。
2、16.6ms刷新一次 是啥意思?是每16.6ms都走一次 measure/layout/draw ?
答:屏幕的固定刷新频率是60Hz,即16.6ms。不是每16.6ms都走一次 measure/layout/draw,而是有绘制任务才会走,并且绘制时间间隔是取决于布局复杂度及主线程耗时。
3、measure/layout/draw 走完,界面就立刻刷新了吗?
答:不是。measure/layout/draw 走完后 会在VSync到来时进行缓存交换和刷新。
4、如果界面没动静止了,还会刷新吗?
答:屏幕会固定没16.6ms刷新,但CPU/GPU不走绘制流程。见下面的SysTrace图。
5、可能你知道VSYNC,这个具体指啥?在屏幕刷新中如何工作的?
答:当扫描完一个屏幕后,设备需要重新回到第一行以进入下一次的循环,此时会出现的vertical sync pulse(垂直同步脉冲)来保证双缓冲在最佳时间点才进行交换。并且Android4.1后 CPU/GPU的绘制是在VSYNC到来时开始。
6、可能你还听过屏幕刷新使用 双缓存、三缓存,这又是啥意思呢?
答:双缓存是Back buffer、Frame buffer,用于解决画面撕裂。三缓存增加一个Back buffer,用于减少Jank。
7、可能你还听过神秘的Choreographer,这又是干啥的?
答:用于实现——“CPU/GPU的绘制是在VSYNC到来时开始”
网友评论