VSync信號
vsync是有兩個信號的,
一個是vsync-app用于生成當前幀的數(shù)據(jù);(CPU計算和GPU渲染)
一個用于消費數(shù)據(jù)(合成圖像到Display上,vsync-surface) 。
三緩沖機制:
?CPU緩存為了防止GPU計算超時,提前生成數(shù)據(jù) GPU:將數(shù)據(jù)放到緩沖池防止屏幕渲染超時
?
一,vsync信號來源
vsync可以由底層HardWare提供經(jīng)由Display發(fā)送,當?shù)讓親ardware不能提供時也會發(fā)送vsync信號到Display。vsync屏蔽了底層Hal,使得沒有Vsync的硬件也可以使用。
二,發(fā)送流程
HardWare到達Display之后,Display會 「將vsync信號分成兩個」 一個用于 「生成」 一個用于 「消費」 的vsync信號。
「一個是vsync-app」 喚醒Chrographer做App的繪制操作(生成當前幀數(shù)據(jù))
「一個是vsync-sf」 是SurfaceFliger使用,當vsync信號來臨時進行合成操作(要滿足消費完上一幀數(shù)據(jù)的條件下)
三,偏移量
vsync每隔16ms發(fā)送一個。vsync會分成兩個信號發(fā)送。這就意味著只要這兩個信號在16ms之內(nèi)處理完數(shù)據(jù)就可以。也就是說我們可以打亂順序是 「先合成消費幀數(shù)據(jù)繪制到屏幕上」 還是先 「生成幀數(shù)據(jù)」 。
比如先發(fā)送vsync-app在0-13ms做完處理,接著13-16ms在發(fā)送vsync-surface合成數(shù)據(jù) 或者顛倒,但是事件一定保證只要在16ms之內(nèi)處理完這兩個信號即可
四,整個處理過程:
1.vsync-app:UI Thread準備好繪制指令,提交給Render Thread渲染線程去調(diào)用OpenGl的函數(shù)去生成buffer并放到BufferQuene中
2.vsync-surface:SurfaceFliger進程去BufferQuene中去取出buffer合成圖像顯示到屏幕Display中。
五,vsync-app 解釋
喚醒Chorgrapher去做處理生成當前這一幀的數(shù)據(jù)。注意:有兩個線程共同合作完成繪制動作:UIThread生成指令和RenderThread調(diào)用OpenGl庫生成Buffer放入到BufferQuene緩沖隊列中。 「UIThread」 :Choreographer.doFrame() 「RenderThread」 :DrawFrame
首先來講 「UIThread的Choreographer.doFrame」 方法:
1.按順序發(fā)送INPUT,ANIMATION,TRASVEL并處理他們各自的doFrame方法 先處理輸入事件在處理動畫,最后的TRASVEL會進行調(diào)用到ViewRootImpl中的doTrasvel回調(diào),這個回調(diào)里面會進行measure,layout和draw。
這里講下draw方法,進行performDraw方法調(diào)用時會調(diào)用全局Surface(也就是activity)的lockCanvas方法。這個方法會在native層的Surface對象中鎖定一塊內(nèi)存區(qū)域返回值為canvas也就是這片在native層的Surface內(nèi)存空間中。接下來調(diào)用draw方法把這個canvas傳入到參數(shù)中,也就是我們在draw方法中對canvas進行的修改實質上都是對這塊內(nèi)存區(qū)域的修改。最后draw方法調(diào)用完成后,會進行釋放這塊內(nèi)存區(qū)域并交給RenderThread去處理渲染數(shù)據(jù)。(釋放的操作在native層對應的處理是把這塊內(nèi)存區(qū)域變成一個Bitmap交由RenderThread去渲染)
?draw方法其實并沒有進行真正的繪制,而是把繪制的內(nèi)容放入到了DisplayList中接著同步到RenderThread中。
?
繪制最終會調(diào)用到View.invalidate方法
2.RenderThread執(zhí)行的時候UIThread就可以釋放掉去做其他處理,接著RenerThread去取出DisplayList中的數(shù)據(jù)進行處理生成frameBuffer給到Surface去做合成處理。具體流程:RenderThread會執(zhí)行一個DrawFrameTask的Task,里面核心方法是DrawFrame。通過OpenGl和一些庫將渲染數(shù)據(jù)通知給SurefaceFliger去做圖層合成。將渲染數(shù)據(jù)放入到阻塞隊列中
六,vsync-sf:
App端中RenderThread產(chǎn)生的FrameBuffer數(shù)據(jù)會在SurfaceFliger中進行消費。也就是取出阻塞隊列中的渲染數(shù)據(jù)。SurfaceFliger進行合成到Display上面處理
-
cpu
+關注
關注
68文章
10890瀏覽量
212413 -
編程
+關注
關注
88文章
3634瀏覽量
93858 -
渲染
+關注
關注
0文章
70瀏覽量
10933
發(fā)布評論請先 登錄
相關推薦
評論