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