android fps 垂直同步,浅谈Android流畅度
原標(biāo)題:淺談Android流暢度
哈哈
講個(gè)故事
白
1
流暢度
關(guān)于流暢度谷歌官方給出的解釋為:running at a consistent 60 frames per second, without any dropped or delayed frames, or as we like to call it, jank.即以每秒60幀(每幀16.6ms)的速度運(yùn)行,也就是60fps,并且沒有任何延遲或者掉幀。
因此,關(guān)于流暢度的問題,我們先確定了以下三個(gè)考量指標(biāo)。
1、FPS:每秒的幀數(shù)。
2、丟幀(SF: Skipped Frame):在16.6ms完成工作卻因各種原因沒做完,占了后n個(gè)16.6ms的時(shí)間,相當(dāng)于丟了n幀。
3、流暢度(SM: SMoothness):和丟幀相對(duì),在VSync機(jī)制中1s內(nèi)Loop運(yùn)行的次數(shù)。
VSYNC機(jī)制
大家應(yīng)該看到上面提到了16.6ms和VSync,現(xiàn)在來解釋一下VSync機(jī)制。
VSync機(jī)制: Android系統(tǒng)每隔16ms發(fā)出VSYNC信號(hào),觸發(fā)對(duì)UI進(jìn)行渲染,VSync是Vertical Synchronization(垂直同步)的縮寫,是一種在PC上很早就廣泛使用的技術(shù),可以簡(jiǎn)單的把它認(rèn)為是一種定時(shí)中斷。而在Android 4.1(JB)中已經(jīng)開始引入VSync機(jī)制
上圖所示是VSync機(jī)制下的繪制過程。從上圖可以看出,CPU和GPU的處理時(shí)間都少于一個(gè)VSync的間隔,即16.6ms。如果每個(gè)間隔都有繪制的情況下,當(dāng)前的FPS即為60幀。
當(dāng)CPU和GPU處理時(shí)間都很慢,或因?yàn)槠渌脑?#xff0c;如在主線程中干活太多,那么就會(huì)出現(xiàn)如下圖這樣的狀況。
從上圖可以看到,CPU和GPU的處理時(shí)間因?yàn)楦鞣N原因都大于一個(gè)VSync的間隔(16.6ms),所以在第二個(gè)VSync還在處理1區(qū)域的繪制時(shí),不可能實(shí)現(xiàn)理論上的FPS60,同時(shí)也出現(xiàn)了丟幀(SF: Skipped Frame)情況。試想用戶盯著同一張圖看了32ms而不是16ms,當(dāng)然很容易察覺出卡頓感,哪怕僅僅出現(xiàn)一次掉幀,用戶都會(huì)發(fā)現(xiàn)動(dòng)畫不是很順暢。
測(cè)試方法
通過以上信息相信大家對(duì)VSync機(jī)制有一個(gè)簡(jiǎn)單的了解,也知道了為什么我們測(cè)試流暢度要定最開始提到的幾個(gè)指標(biāo)。下面我們來介紹一下測(cè)試方法。
gfxinfo
dumpsys是一個(gè)在設(shè)備上運(yùn)行的Android工具,可以轉(zhuǎn)儲(chǔ)有關(guān)系統(tǒng)服務(wù)狀態(tài)的信息。將gfxinfo命令傳遞給dumpsys在logcat中提供了一個(gè)輸出,其中包含與記錄階段期間發(fā)生的動(dòng)畫幀相關(guān)的性能信息。
> adb shell dumpsys gfxinfo
上面的命令可產(chǎn)出關(guān)于幀的多項(xiàng)信息,部分信息如下:
Stats since: 752958278148ns
Total frames rendered: 82189
Janky frames: 35335 (42.99%)
90th percentile: 34ms
95th percentile: 42ms
99th percentile: 69ms
Number Missed Vsync: 4706
Number High input latency: 142
Number Slow UI thread: 17270
Number Slow bitmap uploads: 1542
Number Slow draw: 23342
Total frames rendered: 本次dump搜集的總幀數(shù)
Janky frames: 卡幀數(shù)量和卡幀比
Number Missed Vsync: 垂直同步失敗的幀
Number High input latency: 處理input時(shí)間超時(shí)的幀數(shù)
Number Slow UI thread: 因UI線程上的工作導(dǎo)致超時(shí)的幀數(shù)
Number Slow bitmap uploads: 因bitmap的加載耗時(shí)的幀數(shù)
Number Slow issue draw commands: 因繪制導(dǎo)致耗時(shí)的幀數(shù)
可以看到其實(shí)這個(gè)命令給出的結(jié)果就很詳細(xì)了,我們可以運(yùn)用此命令來測(cè)試我們的app,并計(jì)算我們需要的數(shù)據(jù)。
SurfaceFlinger
SurfaceFlinger 是Android系統(tǒng)的一個(gè)服務(wù),用來生成Surface,管理幀緩沖區(qū)(按序排放窗口,將其合成一張圖片,即一幀)
測(cè)試命令如下:adb shell dumpsys SurfaceFlinger --latency
運(yùn)行結(jié)果部分如下:
這條命令的含義是獲取當(dāng)前l(fā)ayer(窗口、圖層)的最近128幀的信息(僅保存128幀)共128行。
第一行是設(shè)備的刷新周期refresh-period,單位是納秒
剩余的127行,分為3列
第一列: when the app started to draw (開始繪制圖像的瞬時(shí)時(shí)間)
第二列: the vsync immediately preceding SF submitting the frame to the h/w (VSYNC信令將軟件SF幀傳遞給硬件HW之前的垂直同步時(shí)間)
第三列:timestamp immediately after SF submitted that frame to the h/w (SF將幀傳遞給HW的瞬時(shí)時(shí)間,及完成繪制的瞬時(shí)時(shí)間)
fps計(jì)算:總幀數(shù)/刷新總耗時(shí)
一些問題
為什么有時(shí)候FPS很低,但是我們卻不覺得App卡頓?
有時(shí)候FPS很低,我們卻感覺不到卡頓,因?yàn)楸緛砭陀貌坏侥敲锤叩腇PS,比如畫一個(gè)動(dòng)畫只畫了0.5秒就畫完了,那么FPS最高也只有30幀/秒(標(biāo)準(zhǔn)是60幀/每秒),但這并不代表它是卡頓的,用0.5秒動(dòng)畫就畫完了,不能為了湊夠60幀/秒,在做個(gè)1s的動(dòng)畫吧。而如果屏幕根本沒有繪制需求,即屏幕顯示的畫面是靜止的,那FPS就為0。因此,是不是用fps來作為指標(biāo),我們需要認(rèn)真想一想,這個(gè)跟你測(cè)試場(chǎng)景有很大關(guān)系。我們可以針對(duì)此問題設(shè)計(jì)合適的測(cè)試場(chǎng)景,這樣才能更真實(shí)的反應(yīng)出應(yīng)用程序的性能。
參考:
https://developer.android.com/training/testing/performance?hl=zh-cn#aggregate返回搜狐,查看更多
責(zé)任編輯:
總結(jié)
以上是生活随笔為你收集整理的android fps 垂直同步,浅谈Android流畅度的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 动态修改 selecto
- 下一篇: linux script $,linux