上一篇讲了Activity的绘制流程(二)Choreographer(//www.greatytc.com/p/57305733dc50),本篇主讲(三)VSync。
(一)窗口的添加
(二)Choreographer
(三)VSync
(四)Surface
(五)RenderThread
(六)StartingWIndow
(七)窗口切换
一、VSync的产生
在上一篇已经提到了Choreographer监听VSync,使帧率处于一个相对稳定的状态。VSync分为硬件VSync和软件VSync,硬件VSync由HWC硬件模块根据屏幕刷新率产生,软件VSync由SurfaceFlinger根据硬件VSync模拟出来的。抓取systrace,可以看到在SurfaceFlinger中有三个线程:DispSync、app、sf。DispSync线程承担着同步硬件VSync,产生软件VSync并唤醒app线程和sf线程。
SurfaceFlinger初始化时会创建一个Scheduler对象mScheduler,Scheduler初始化时会创建一个DispSync对象mPrimaryDispSync,DispSync初始化时会创建一个DispSyncThread对象mThread,DispSyncThread就是DispSync线程。
SurfaceFlinger初始化时还会调用Scheduler的createConnection函数创建两个ConnectionHandle对象mAppConnectionHandle和mSfConnectionHandle。Scheduler的createConnection函数实际会去创建了一个EventThread对象,一个EventThreadConnection对象和一个ConnectionHandle对象,将这三个对象封装为一个Connection对象,放入Scheduler的mConnections中,通过ConnectionHandle可找到对应的EventThread和EventThreadConnection。
EventThread就是app线程和sf线程。Choreographer初始化时会传入参数VSYNC_SOURCE_APP(值为0)并创建一个FrameDisplayEventReceiver对象mDisplayEventReceiver,它会在SurfaceFlinger端找到对应的app线程,创建一个EventThreadConnection对象放入到app线程的vector列表mDisplayEventConnections中。EventThreadConnection保存了一个BitTube,它内部是一个socket。
二、请求VSync
Choreographer请求VSync,其实就是在SurfaceFlinger端找到对应的EventThreadConnection,标记其vsyncRequest为VSyncRequest::Single,vsyncRequest是一个VSyncRequest对象,它有以下几种状态:
enum class VSyncRequest {
None = -1,
Single = 0,
Periodic = 1,
};
三、接收VSync
当app线程被DispSync唤醒后,会遍历vector列表mDisplayEventConnections。若Choreographer请求VSync,则遍历到对应的EventThreadConnection,会通过Socket将VSync发送到应用端。应用端将Socke中的数据读出,然后分派Vsync,最终实现在应用主线程中调用Choreographer的doFrame函数。