上一篇講了Activity的繪制流程(二)Choreographer(http://www.reibang.com/p/57305733dc50)涵叮,本篇主講(三)VSync绑莺。
(一)窗口的添加
(二)Choreographer
(三)VSync
(四)Surface
(五)RenderThread
(六)StartingWIndow
(七)窗口切換
一震肮、VSync的產(chǎn)生
在上一篇已經(jīng)提到了Choreographer監(jiān)聽VSync隐轩,使幀率處于一個(gè)相對穩(wěn)定的狀態(tài)。VSync分為硬件VSync和軟件VSync,硬件VSync由HWC硬件模塊根據(jù)屏幕刷新率產(chǎn)生,軟件VSync由SurfaceFlinger根據(jù)硬件VSync模擬出來的繁莹。抓取systrace,可以看到在SurfaceFlinger中有三個(gè)線程:DispSync特幔、app咨演、sf。DispSync線程承擔(dān)著同步硬件VSync蚯斯,產(chǎn)生軟件VSync并喚醒a(bǔ)pp線程和sf線程薄风。
SurfaceFlinger初始化時(shí)會(huì)創(chuàng)建一個(gè)Scheduler對象mScheduler,Scheduler初始化時(shí)會(huì)創(chuàng)建一個(gè)DispSync對象mPrimaryDispSync拍嵌,DispSync初始化時(shí)會(huì)創(chuàng)建一個(gè)DispSyncThread對象mThread遭赂,DispSyncThread就是DispSync線程。
SurfaceFlinger初始化時(shí)還會(huì)調(diào)用Scheduler的createConnection函數(shù)創(chuàng)建兩個(gè)ConnectionHandle對象mAppConnectionHandle和mSfConnectionHandle撰茎。Scheduler的createConnection函數(shù)實(shí)際會(huì)去創(chuàng)建了一個(gè)EventThread對象嵌牺,一個(gè)EventThreadConnection對象和一個(gè)ConnectionHandle對象打洼,將這三個(gè)對象封裝為一個(gè)Connection對象龄糊,放入Scheduler的mConnections中,通過ConnectionHandle可找到對應(yīng)的EventThread和EventThreadConnection募疮。
EventThread就是app線程和sf線程炫惩。Choreographer初始化時(shí)會(huì)傳入?yún)?shù)VSYNC_SOURCE_APP(值為0)并創(chuàng)建一個(gè)FrameDisplayEventReceiver對象mDisplayEventReceiver,它會(huì)在SurfaceFlinger端找到對應(yīng)的app線程阿浓,創(chuàng)建一個(gè)EventThreadConnection對象放入到app線程的vector列表mDisplayEventConnections中他嚷。EventThreadConnection保存了一個(gè)BitTube,它內(nèi)部是一個(gè)socket芭毙。
二筋蓖、請求VSync
Choreographer請求VSync,其實(shí)就是在SurfaceFlinger端找到對應(yīng)的EventThreadConnection退敦,標(biāo)記其vsyncRequest為VSyncRequest::Single粘咖,vsyncRequest是一個(gè)VSyncRequest對象,它有以下幾種狀態(tài):
enum class VSyncRequest {
None = -1,
Single = 0,
Periodic = 1,
};
三侈百、接收VSync
當(dāng)app線程被DispSync喚醒后瓮下,會(huì)遍歷vector列表mDisplayEventConnections。若Choreographer請求VSync钝域,則遍歷到對應(yīng)的EventThreadConnection讽坏,會(huì)通過Socket將VSync發(fā)送到應(yīng)用端。應(yīng)用端將Socke中的數(shù)據(jù)讀出例证,然后分派Vsync路呜,最終實(shí)現(xiàn)在應(yīng)用主線程中調(diào)用Choreographer的doFrame函數(shù)。