? ? ? ? 上節我們談到流暢度作為用戶能夠直觀感受到Android系統性能高低的方面,主要可以包括launcher中待機界面的滑動流暢度、主菜單界面界面滑動的流暢度、待機界面和主菜單界面切換的流暢程度;還有就是在橫豎屏切換的流暢度,應用方面主要就是應用打開的響應時間,使用過程中的流暢度,中斷切換重新進入等方面的流暢度。
? ? ? ? 這段時間主要收集了一些現有資料,流暢度中指標主要是(FPS:系統合成幀率、Aggregate frame stats:應用跳幀次數、幅度、Jankiness count:(估算)應用跳幀次數、Max accumulated frames:(估算)應用跳幀幅度、Frame rate:應用繪制幀率、SM:應用繪制輪詢頻率、Skipped frames:應用跳幀次數、幅度),局限于本人的知識水平,探究分析將主要針對于FPS方面的數據,后續將繼續補充~
? ? ? ? 針對于launcher模塊,初步我們收集了界面滑動和切換界面的響應時間,工具主要用的是高速攝像機(120幀/s),這樣每個場景嘗試收集了5組數據,除去一組最大值和最小值,最終的三組求平均值即為該場景的響應時間,這種方式所測量的方法很大程度上依靠于個人的主管程度和測量時所理解的開始時間和結束時間,需要統一標準開始時間后這樣測出的響應時間和競品的數據才有可比性和可分析性;
? ? ? ? 對于FPS數據的采集,第一我們采用的是adb命令行的方式,主要使用的命令行包括adb shell dumpsys gfxinfo package_name >FPS.txt 這條命令主要采集的是近128幀數據的渲染時間,每一幀數據包括有draw prepared process execute這四部分,之前可能只有三部分數據一幀,目前新添加上數據prepared數據,分別代表的含義包括:
? ? ? ? Draw(藍)表示View.onDraw()方法的耗時,這部分主要是建立DisplayList對象用的,這些對象將會被轉化成OpenGL命令,GPU只能讀懂OpenGL命令。如果這個地方耗時比較大,說明視圖比較復雜。藍色區域代表的時間,是創建DisplayList對象的時間。
? ? ? ? Prepared(紫)5.1以后將UI Thread線程所做的事分成了2個線程來做:UI Thread和Render Thread。新加的Render Thread線程會將Draw過程生成的DisplayList對象轉化成為OpenGL的命令,然后發送給GPU,這個時候UI Thread可以空閑下來處理下一個frame的數據。如果傳送的資源過多的話這個地方耗時就比較大。紫色區域代表的時間就是UI Thread傳送數據給Render Thread所用的時間。
? ? ? Process(紅)紅色區域代表創建OpenGL命令的時間,表示渲染引擎執行顯示列表所花的時間,view越多,時間就越長。
? ? ? Execute(黃)黃色區域代表發送OpenGL命令給GPU所用的時間,表示把一幀數據發送到屏幕上排版顯示實際花費的時間。其實是實際顯示幀數據的后臺緩存區與前臺緩沖區交換后并將前臺緩沖區的內容顯示到屏幕上的時間。所以這個時間,一般都很短。
? ? ? 一般我們將這四部分時間相加時間小于16ms定義為流暢幀,因為這樣一秒時間內才能繪制出60幀以上,達到流暢的程度;若一幀渲染時間超過了16ms,這時就會出現丟幀的現象,也就是我們常看到的卡頓;具體進程的分析我們將用到traceview來分析個進程中方法的調用是否超時或調用次數(遞歸次數)過多影響渲染時間,此工具數據分析待以后詳解;
? ? ? ? 第二種數據獲取的命令方式為adb shell dumpsys Surface Flinger --latency Package_name >FPS.txt 這種方式我們獲取 的128幀數據(第一行為刷新周期),其余127幀數據分為三部分,每一列代表一部分:
? ?第一列:這一部分的數據表示應用程序繪制圖像的時間點。
? 第二列:這一部分代表的是在SF(軟件)將幀提交給H/W(硬件)繪制之前的垂直同步時間。
? 第三列:SF將幀提交給H/W的時間點,是H/W接受完SF發來數據的時間點,繪制完成的時間點。
? ? ? ?當渲染時間大于16.67,按照垂直同步機制,該幀就已經渲染超時 ;那么,如果它正好是16.67的整數倍,比如66.68,則它花費了4個垂直同步脈沖,減去本身需要一個,則超時3個;?如果它不是16.67的整數倍,比如67,那么它花費的垂直同步脈沖應向上取整,即5個,減去本身需要一個,即超時4個,可直接算向下取整 ;
? ? ? ?最后的計算方法思路: 執行一次命令,總共收集到了m幀(理想情況下m=128),但是這m幀里面有些幀渲染超過了16.67毫秒,算一次jank,一旦jank, 需要用掉額外的垂直同步脈沖。其他的就算沒有超過16.67,也按一個脈沖時間來算(理想情況下,一個脈沖就可以渲染完一幀)?
所以FPS的算法可以變為: m / (m + 額外的垂直同步脈沖) * 60;
? ? ? ?通過這條命令我們所獲取到的數據計算出幀率,這個應是硬件層面,也就是顯示層面的刷新幀率,這與幀率之間存在著一定區別:
? ? ? ?刷新幀率:顯卡渲染出多幀圖像,是需要顯示設備呈現在我們面前的。這個顯示設備就是我們熟知的顯示器。顯示器有一個概念叫做刷新率(Windows系統在控制面板,顯示里設置),是指在1秒內,重新刷新屏幕的次數。
? ? ? 幀率:幀率是用來衡量顯卡渲染能力的一個指標。顯卡在處理圖像數據時,性能越強的顯卡,在均等時間內(比如1秒),渲染出的靜態圖像的數量(這一幅靜態圖像就稱為一幀)。
? ? ? 顯示器的刷新一幀后就會產生一個垂直同步信號。當我們選擇“垂直同步”(即打開垂直同步)時,顯卡在渲染每一幀之前會等待垂直同步信號,只有顯示器完成了一次刷新時,發出垂直同步信號,顯卡才會渲染下一幀。這種情況下,顯卡的渲染能力會受到顯示器刷新率的制約。如果顯示器刷新率是60Hz,顯卡幀率最多只會達到60。
? ? ? ?最終,我們可以通過py腳本,可視化的窗口形式直觀的顯示出來,流暢度的評分可以考慮幾個層面包括FPS,MFS,OKT,Frame,這樣各指標所占一定比例得出的SS評分更為客觀評價;數據整理和分析見下回分解。