天天看點

Android卡頓原理分析和SurfaceFlinger,Surface概念簡述Android 卡頓原理SurfaceFlinger 簡述Surface 概述

本篇僅是簡述,還在學習中,後續會慢慢完善。

Android 卡頓原理

Android早期相較于IOS卡頓較為嚴重,從4.4開始,特别是5.0版本以後,由于各方面的優化(系統的和CPU,GPU,記憶體的),系統的流暢程度已經有了很大提升。

其中Vsync的持續改進起到了一定的作用,Vsync稱為垂直同步主要是為了解決顯示卡生成幀的速度和螢幕(顯示系統的一種)重新整理的頻率不一緻,也就是CPU,GPU處理準備畫面的頻率和Display裝置重新整理頻率(一般是16ms)不一緻的問題,有了Vsync可以讓顯示器輸出穩定正确的畫面。

如果 CPU、GPU 處理,生成幀的速度和 Display 重新整理的速度不一緻,在不使用vsync的情況下會出現螢幕正在重新整理第二幀圖像,但是顯示卡已經更新了第三幀圖像,這時反映到螢幕上就會産生一部分是第二幀的圖像,一部分是第三幀的圖像(畫面撕裂(screentearing))。有了vsync機制,每次螢幕重新整理時通過Vsync通知更新幀,這樣顯示的畫面就不會出現上面的問題。Vsync可以由硬體或者軟體生成。

Display 是Android 對輸出顯示裝置的一個抽象,一般指手機顯示器,在Andrid 4.1 後優化SurfaceFlinger,支援更多外部輸入裝置,比如HDMI, Wifi Display 等等。Display的輸入是過濾後的所有Window的Surface, 輸出是和顯示裝置尺寸相同的Buffer, 這個Buffer 最終送到了硬體的FB裝置,或者HDMI裝置,或者遠處的Wifi Display Sink裝置進行顯示。輸入到輸出這條路徑上有SurfaceFlinger, OpenGL 和 HWComposer。

不使用Vsync:

Android卡頓原理分析和SurfaceFlinger,Surface概念簡述Android 卡頓原理SurfaceFlinger 簡述Surface 概述

display展示第0幀的時候,GPU或者CPU準備第1幀顯示的圖檔,第0幀結束時VSync信号到來,CPU或者GPU應該開始準備第2幀,但由于某些原因沒有在Vsync處開始準備第二幀圖像,Display再次展示時隻能顯示前一幀圖像,反映到界面上會給使用者卡頓的印象。

使用vsync:

Android卡頓原理分析和SurfaceFlinger,Surface概念簡述Android 卡頓原理SurfaceFlinger 簡述Surface 概述

上面的圖展示了使用Vsync時的正常情況,但是還有一種情況是cpu,gpu在vsync到來時開始工作,但是可能由于CPU或者gpu工作太繁重,導緻cpu,gpu忙不過來,處理合成surface的時間會變長,也會導緻不能按時處理完下一幀圖檔。

CPU,gpu忙不過來的情況:

Android卡頓原理分析和SurfaceFlinger,Surface概念簡述Android 卡頓原理SurfaceFlinger 簡述Surface 概述

Display顯示第0幀資料,CPU和GPU開始渲染第1幀畫面,下一次Vsync到來之前完成了渲染,Display在第1個VSync後,正常顯示第1幀;接着由于某些原因,cpu,gpu由于過忙沒有及時地開始處理第2幀,VSync再次來時,由于第2幀資料還沒有準備就緒,顯示的還是第1幀,被Android開發組命名為“Jank”,當第2幀資料準備完成後,它并不會馬上被顯示,而是要等待下一個VSync。螢幕多顯示了一次第1幀,如果頻繁發生會導緻卡頓。

為提高android的處理幀的效率,Android還提供了雙緩沖,三緩沖方案:

Android卡頓原理分析和SurfaceFlinger,Surface概念簡述Android 卡頓原理SurfaceFlinger 簡述Surface 概述

緩沖區是建構和存儲幀的容器,Android的雙緩沖模型中,一個緩存區顯示1幀,而在另一個緩存區進行下一幀的處理。如上圖緩沖器标記為“A”和“B”。當顯示緩沖區A時,系統開始在緩沖區B中建立一個新幀,當準備好時,它們交換緩沖區,B被顯示,并且A中的幀被清除并且處理新的幀。除此之外還有三緩沖結構等等,具體的我也沒太研究是以還需要大家自己去看。

Android 系統每 16ms(更準确的是大概16.6ms) 就會發出一次 VSYNC信号觸發ui更新。螢幕一秒大約重新整理60次,所裡處理合稱一幀花費的時間在 16ms 内,畫面會比較流暢。

如果在16ms内由于view的繪制邏輯過于複雜,就會導緻本次繪制新内容不會成功,依然會顯示上次繪制的内容,如果頻繁發生16ms無法完成界面更新的問題,反映到軟體影響是看着應用的界面會感覺卡頓。

SurfaceFlinger 簡述

來自:http://www.cnblogs.com/samchen2009/p/3364327.html

SurfaceFlinger的作用主要是merge Surface,用于接受多個來源的圖形顯示資料,然後将他們合稱發送到顯示裝置。

SurfaceFlinger 是一個獨立的Service, 它接收所有Window的Surface作為輸入,根據ZOrder, 透明度,大小,位置等參數,計算出每個Surface在最終合成圖像中的位置,然後交由HWComposer或OpenGL生成最終的顯示Buffer, 然後顯示到特定的顯示裝置上。

在Android底層繪制系統中,SurfaceFlinger 為App程序建立具體的Surface, 在SurfaceFlinger裡對應成Layer, 然後負責管理、合成顯示。Layer是SurfaceFlinger 進行合成的基本操作單元。Layer是在應用請求建立Surface的時候在SurfaceFlinger内部建立,是以一個Surface對應一個 Layer, 但注意,Surface不一定對應于Window,Android中有些Surface并不跟某個Window相關,而是有程式直接建立,比如說 StrictMode, 一塊紅色的背景,用于提示示Java代碼中的一些異常, 還有SurfaceView, 用于顯示有硬體輸出的視訊内容等。

Surface 概述

Window在android不同地方有不同含義,這裡主要讨論WindowManagerService中管理的Window。Window 是 Android 中視窗的宏觀定義,主要是管理 View 的建立,以及與 ViewRootImpl 的互動,将 Activity 與 View 解耦。

看下圖:

Android卡頓原理分析和SurfaceFlinger,Surface概念簡述Android 卡頓原理SurfaceFlinger 簡述Surface 概述
Surface的建立由誰發起呢,App要顯示自己的内容,會發起Surface建立請求,WindowManagerService, 負責接收APP請求,向SurfaceFlinger發起具體的請求建立Surface。Window與Surface一一對應。 Surface負責記錄每個時刻Window的内容。在Android的SurfaceFlinger實作裡,通常一個Surface有兩塊 Buffer, 一塊用于繪畫,一塊用于顯示,兩個Buffer按照固定的頻率進行交換,進而實作Window的動态重新整理。

一個視窗界面包含多個View組成View hierachy的樹形結構,隻有最頂層的DecorView才對WMS可見,這個DecorView在WMS中有一個對應的WindowState,在SurfaceFlinger有對應的Layer。

Layer是SurfaceFlinger 進行合成的基本操作單元。Layer在應用請求建立Surface的時候在SurfaceFlinger内部建立,是以一個Surface對應一個 Layer, 但注意,Surface不一定對應于Window,Android中有些Surface并不跟某個Window相關,而是有程式直接建立,例如SurfaceView, 用于顯示有硬體輸出的視訊内容等。

一個應用程式有多個視窗界面(Activity),可以包含多個Surface,每個window又對應一個Surface,Display每次顯示的是多個Window融合後的效果。Surface内部對應一塊螢幕緩沖區,視窗中所有的View共享一塊緩沖區,是以視窗中的任何view最終都是繪制在Surface對應的buffer(螢幕緩沖區)上的。Android的View必須在主線程更新,是由于視窗中所有的View共享一塊緩沖區,如果異步可更新,會造成資料的不同步。

Handle onto a raw buffer that is being managed by the screen compositor.

Surface持有一個被螢幕合成器管理的原始緩沖區,是以所有繪制的内容最終都會儲存到這個緩沖區中。

Surface定義在ViewRootImpl中的成員,定義時已經執行個體化了:

final Surface mSurface = new Surface();

ViewRootImpl的個數與addView的調用次數相關,一個Activity可以多次調用addView, 也就是說一個Activity可以有多個Surface.

Surface 内部持有一個Canvas,可以利用這個Canvas繪制。

繼續閱讀