5. Vsync機制
5.1 黃油計划_三個方法改進顯示系統
vsync, triple buffering, vsync虛擬化
參考文檔:
林學森 <深入理解Android內核設計思想>第2版 9.6節
Getting To Know Android 4.1, Part 3: Project Butter - How It Works And What It Added
http://www.androidpolice.com/2012/07/12/getting-to-know-android-4-1-part-3-project-butter-how-it-works-and-what-it-added/
Android 4.4(KitKat)中VSync信號的虛擬化
http://blog.csdn.net/jinzhuojun/article/details/17293325
Vsync:
圖中的16ms表示顯示一副圖片的時間,display表示第幾幀,圖中display顯示第0幀的時候,GPU或者CPU准備第1幀顯示的圖片,在第0幀尾部,CPU或者GPU本應該開始准備第2幀顯示的圖片,結果他們偷懶了,沒有被強制在Vsync處開始工作,因此Display只能連續兩幀顯示一副圖片 ,稱這種現象為Jank

假如cpu或者gpu掉鏈子了怎么辦,如下圖,如果GPU忙不過來了,沒有能及時完成,又會導致Jank,引入了 triple buffering

上述優化是在Vsync時刻才開始工作,而APP准備好數據是發送給surface,surface使用CPU和GPU進行渲染生成圖片,然后發給display,如果都同時工作,那么一副圖片顯示需要經過兩個Vsync時刻32ms,先是APP生成,接着surface處理,然后才能顯示,問題的根源是都在Vsync時刻開始工作,錯過了就要等到下個Vsync,解決辦法是讓surface在APP就緒好后就開始工作,因此把App開始工作的時候是Vsync+offset1,surface工作的時刻在Vsync+offset1+offset2

5.2 Vsync框架
(1)誰產生Vsync:硬件或者軟件(VsyncThread)
(2)誰處理Vsync:某個線程(DispSyncThread)
(3)Vsync分為Vsync-APP和Vsync-Surface,誰負責Vsync虛擬化(DispSyncThread)
(4)Vsync-App和Vsync-Surface怎么起作用:按需產生:APP需要更新界面的時候,發送請求Vsync信號給EventThread(APP),EventThread(APP)在收到Vsync后喚醒APP,APP開始產生新界面
Surface需要合成界面的時候,發送請求Vsync信號給EventThread(Surface),EventThread(Surface)在收到Vsync后喚醒Surface,Surface開始合成新界面

由上圖可知Vsync框架引入了五個線程:軟件產生Vsync信號的線程、虛擬化Vsync信號產生Vsync-APP和Vsync-Surface的線程、分別對Vsync-APP和Vsync-Surface感興趣的EventThread(APP)和EventThread(Surface)、SurfaceFlinger線程
當應用程序需要更新它的界面的時候對EventThread(APP)發出請求,請求得到Vsync-APP信號,APP得到Vsync-APP信號后,APP開始構造畫面,完成后把這些畫面發送的SurfaceFlinger線程,SurfaceFlinger收到畫面后其向EventThread(Surface)發出請求,請求得到Vsync-Surface信號,SurfaceFlinger得到Vsync-Surface信號后,SurfaceFlinger開始合成畫面
APP按需進行:
(1)APP有更新界面的需要時,它需要得到Vsync-APP
(2)APP向EventThread(APP)提出請求
(3)EventThread(APP)再向DispSyncThread提出請求
(4)DispSyncThread收到Vsync后,休眠offset1,發出Vysnc-APP
Surface按需進行:
(1)APP把新數據發給Surface
(2)Surface有Vsync需求,向EventThread(surface)發出請求
(3)EventThread(Surface)再向DispSyncThread發出請求
(4)DispSyncThread收到Vsync后,休眠offset2,發出Vysnc-Surface
5.3 初始化代碼分析
上述所說的Vsync框架中的五個線程同屬於SurfaceFlinger進程,在Main_surfaceflinger.cpp函數中創建,SurfaceFlinger是主線程
5.4 surfaceflinger使用vsync過程代碼分析
(1)APP發數據給surfaceflinger
(2)surfaceflinger發請求給EventThread(surface)
(3)EventThread(surface)發vsync請求給DispSyncThread
(4)硬件或者軟件Vsync會喚醒DispSyncThread
(5)DispSyncThread發信號給EventThread(surface),其在發信號給surfaceflinger
