每一次面試準備都是造航母
複製代碼
fps:每秒傳輸的幀數,FPS」也能夠理解爲咱們常說的「刷新率(單位爲Hz)」。
hz:表明屏幕在一秒內刷新的次數,Android手機通常爲60HZ,也就是一秒刷新60幀,大約16.67ms刷新一次
丟幀:原本一秒中畫面須要更新 60 幀,可是若是這期間只更新了 55 幀 , 那麼在用戶看來就是丟幀了 , 主觀感受就是卡了
tearing: 一個屏幕內的數據來自2個不一樣的幀,畫面會出現撕裂感
jank: 繪圖速度過慢,一個幀在屏幕上連續出現2次
lag:從用戶體驗來講,就是點擊下去到呈現效果之間存在延遲
撕裂(screen tearing):當cpu/gpu將數據準備寫入buffer(緩衝區)中,但display還沒來的及顯示,這時cpu/gpu把下一幀數據往buffer寫,還沒寫完,Display開始讀去buffer顯示,(也就是繪圖數度大於顯示速度),這是就會出現顯示的上半部分爲下一幀數據,下半部分爲上一幀數據,如圖所示,這就是撕裂。 android
tearing發生的緣由是display讀buffer同時,buffer被修改,那麼多一個buffer是否是能解決問題,這個時候雙緩衝就誕生了。面試
從性能角度出發,若是隻對一塊緩衝區進行讀寫無疑效率比較低下:一方面屏幕要從該區域去讀,另外一方面顯卡要等待去寫.所以在實際中,其實幀緩衝區實則被劃分爲兩部分:緩存
前緩衝區: 用來緩存要顯示到屏幕的幀數據 後緩衝區: 用來緩存顯卡生成的幀數據. 屏幕只能前緩衝區讀取數據用於顯示,顯卡只能日後緩衝區寫入新生成的幀數據.須要注意的是兩塊緩衝區並不發生實際上的數據拷貝操做,即將後緩衝區的幀數據拷貝到前緩衝區,而是在前緩衝區的幀數據已經推到屏幕上,且新的幀數據被寫入到後臺緩衝區後,進行指針交換操做,將原來的後緩衝區變爲前緩衝區 佈局
但仍是有問題,假如是backbuffer準備完成一幀數據之後就進行,那麼若是此時屏幕尚未完整顯示上一幀內容的話,確定是會出問題的。看來只能是等到屏幕處理完一幀數據後,才能夠執行這一操做了. 當掃描完一個屏幕後,設備須要從新回到第一行以進入下一次的循環,此時有一段時間空隙,稱爲VerticalBlanking Interval(VBI)。你們應該能想到了,這個時間點就是咱們進行緩衝區交換的最佳時間。由於此時屏幕沒有在刷新,也就避免了交換過程當中出現 screentearing的情況。VSync(垂直同步)是VerticalSynchronization的簡寫,它利用VBI時期出現的vertical sync pulse來保證雙緩衝在最佳時間點才進行交換。 因此說V-sync這個概念並非Google獨創的,它在早些年前的PC機領域就已經出現了。不過Android 4.1給它賦予了新的功用,稍後就能夠看到。性能
在一個典型的顯示系統中分爲GPU,CPU,Display(有些言論稱爲顯示器)三部分,Android中LayoutInflater將佈局中的xml標籤轉換爲對象,cpu通過計算將它轉化爲多邊形(Polygons)或Texture(紋理)。gpu對多邊形或者紋理進行柵格化(Rasterization)操做,柵格化後的數據寫入幀緩衝區中等待顯示器顯示。如圖:優化
在Android 4.1以前,界面卡頓是Android中最受詬病的一點.爲了解決界面卡頓問題,Google爲Android引入了Project Butter計劃,即常說的黃油計劃.在該項目中,Google對Android顯示系統進行重構,並引入了三個相當重要的改進:
動畫
VSync加強:VSync不只僅用於避免畫面撕裂現象,如今它還會通知GPU在渲染下一幀以前要等待屏幕完成 逐行繪製.
Triple Buffer: 三緩衝機制
Choreographer: 用於協同nimations,input和drawing一塊兒工做
spa
雙緩衝意味着要使用兩個緩衝區(SharedBufferStack中),其中一個稱爲Front Buffer,另一個稱爲Back Buffer。UI老是先在Back Buffer中繪製,而後再和Front Buffer交換,渲染到顯示設備中,其中Display處理前Front Buffer,CPU、GPU處理Back Buffer.net
須要注意的是Android中一直存在VSync機制(有待考證),只不過早期VSync只是爲了不畫面撕裂(screen tearing)現象.爲了更好的瞭解加強過的VSync和Triple Buffer,咱們先來看一下早期圖像顯示的過程,即VSync只用來避免畫面撕裂的狀況:線程
這個圖中有三個元素,Display是顯示屏幕,GPU和CPU負責渲染幀數據,每一個幀以方框表示,並以數字進行編號,如0、一、2等等。VSync用於指導雙緩衝區的交換。以時間的順序來看下將會發生的異常:
其實總結上面的這個狀況之因此發生,首先的緣由就在於第二幀沒有及時的繪製。那麼如何使得第二幀及時被繪製呢?這就是咱們在Graphic系統中引入VSYNC的緣由,
在雙緩存的基礎上,android又引入了三緩存技術。 首先來看傳統的雙緩衝機制,理想狀況下,其工做狀態以下:
當CPU/GPU的處理時間超過16ms時,第一個VSync到來時,緩衝區B中的數據尚未準備好,因而只能繼續顯示以前A緩衝區中的內容。而B完成後,又由於缺少VSync pulse信號,它只能等待下一個signal的來臨。因而在這一過程當中,有一大段時間是被浪費的。當下一個VSync出現時,CPU/GPU立刻執行操做,此時它可操做的buffer是A,相應的顯示屏對應的就是B。這時看起來就是正常的。只不過因爲執行時間仍然超過16ms,致使下一次應該執行的緩衝區交換又被推遲了——如此循環反覆,便出現了愈來愈多的「Jank」。
很顯然,第一次的Jank看起來是沒有辦法的,除非升級硬件配置來加快FPS。咱們關注的重點是被CPU/GPU浪費的時間段,怎麼才能充分利用起來呢?Google爲了解決該問題,引入的三緩衝機制,即在原來雙緩衝的機制上加入了第三塊緩衝區.
咱們來逐步分析下這個是否有效。首先和預料中的一致,第一次「Jank」無可厚非。不過讓人欣慰的是,當第一次VSync發生後,CPU不用再等待了,它會使用第三個buffer C來進行下一幀數據的準備工做。雖然對緩衝區C的處理所需時間一樣超過了16ms,但這並不影響顯示屏——第2次VSync到來後,它選擇buffer B進行顯示;而第3次VSync時,它會接着採用C,而不是像double buffering中所看到的狀況同樣只能再顯示一遍B了。這樣子就有效地下降了jank。可是帶來了lag的問題,如上圖所示,A這一幀在第4個vsync來的時候才顯示,若是是雙緩衝,那在第三個vynsc就能夠顯示了。
三緩衝做用: 簡單的說在2個緩存區被GPU和display佔據的時候,開闢一個緩衝區給CPU用,通常來講都是用雙緩衝,須要的時候會開啓3緩衝,三緩衝的好處就是使得動畫更爲流程,可是會致使lag,從用戶體驗來講,就是點擊下去到呈現效果會有延遲。因此默認不開三緩衝,只有在須要的時候自動開啓 一句話總結三緩衝有效利用了等待vysnc的時間,減小了jank,可是帶來了lag
總結: VSync(解決畫面撕裂) 三緩衝(提高CPU/GPU利用率)
谷歌提供了這麼牛逼的機制,爲何你寫的APP還會卡? 1.界面太複雜。 2.主線程太忙。他可能還在處理用戶交互或者其餘事情。
參考:
lionoggo.com/2017/09/12/…
www.jianshu.com/p/0cb06877c…
blog.csdn.net/litefish/ar…