Android----屏幕UI顯示系統基礎

屏幕顯示系統基礎概念

幀--->視頻由連續的靜態圖像連續快速切換播放形成,每一張靜態圖像稱為視頻的一幀。

利用人眼的“視覺暫留現象”只要連續圖像播放大于24幀/秒,即感受到的就是連續的動態圖像。

幀率(fps) ---> 每秒屏幕播放的幀數,幀率低于24人眼會感覺卡頓不流暢,越高越流暢
顯示器垂直分辨率:顯示器垂直方向上可顯示的像素數目
顯示器水平分辨率:顯示器水平方向上可顯示的像素數目
屏幕刷新率(HZ)-->又稱為場頻(垂直掃描頻率)

最初的CRT(陰極射線管)技術時代的屏幕,屏幕刷新像素都是從左上角開始從左到右,從上到下逐行掃描;所以完成一次垂直掃描即可完成整屏幕的刷新故而場頻也稱屏幕刷新率.

行頻--->水平掃描率,每秒在屏幕上掃描的行數
行頻 = 場頻 * 垂直分辨率 * K(一個常數)

為什么會有一個常數?答案也很簡單,由于每次掃描到最后一個像素后,下次又要重定位到左上角,存在一個性能損耗,所以“行頻”會比“場頻*垂直分辨率”大,即K一般大于1。

典型現代屏幕顯示系統角色分工:

構建視圖內容: 遍歷所有視圖,將需要繪制的操作緩存下來,交給單獨的Render線程使用GPU進行硬件加速渲染。(通常在主線程中使用CPU構建)

繪制階段 : 調用OpenGL(即使用GPU)對構建好的視圖進行繪制渲染,繪制的內容保存在Graphic Buffer 并交由 SurfaceFlinger 顯示。(Android 5.0+ 使用Render Thread線程,專門負責 UI 渲染和動畫顯示。)

顯示“卡頓”類型

Tearing --> "圖像撕裂",屏幕呈現的圖像由兩幀以上構成,畫面出現撕裂感(當前幀還未完全由屏幕更新到屏幕,即被下一幀的數據替換)
Jank --> 同一個幀在屏幕上連續出現2次即通常說的卡頓
Lag --> 屏幕延時,從用戶輸入到屏幕呈現效果之間存在延遲

Screen Tearing原因

屏幕顯示圖像本質是一個粗略的生產-消費者模型:CPU&GPU生產圖像數據到幀Buffer,顯卡從buffer獲取數據顯示到屏幕。


image.png

CPU & GPU生產幀數據時間是不定的,而屏幕刷新率基本由硬件(顯卡)決定通常60Hz。顯示控制器從Buffer獲取幀數據更新到屏幕有一個時間間隔(CRT技術的屏幕都是從屏幕左上從左到右,從上到下依次刷新屏幕像素)。

在屏幕的一個刷新周期內,buffer數據被cpu/gpu更改,就出現了圖像前部分是A幀,后半部分是B幀的“撕裂Tearing”.

由于幀buffer是一個競爭性資源,CPU/GPU 與 屏幕display會爭搶buffer,不同步就會導致Tearing.

顯示出現tearing的本質原因是,屏幕刷新率與CPU/GPU生成圖像的幀率不同步, 加入同步lock即可解決;每次屏幕或者GPU只能有一方在操作buffer.

雙緩沖+VSync同步機制

單buffer+同步雖然能解決tearing,但是效率太低,GPU和屏幕競爭同一塊buffer大部分時間都在互相等待中浪費了資源。

于是雙buffer機制適時出現(事實上單bufer機制只存在于30年前了):
backBuffer用于CPU/GPU后臺繪制,frameBuffer則用于顯示,當backBuffer準備就緒后,它們才進行交換。

雙緩沖解決了效率問題,但是如何解決同步問題---> 何時交換backBuffer和frameBuffer?

當掃描完一個屏幕后,設備需要重新回到第一行以進入下一次的循環,此時有一段時間空隙,稱為VerticalBlanking Interval(VBI)。這個時間點就是我們進行緩沖區交換的最佳時間,因為此時屏幕沒有在刷新,也就避免了交換過程中出現 screentearing的狀況。VSync(垂直同步)是VerticalSynchronization的簡寫,它利用VBI時期出現的vertical sync pulse來保證雙緩沖在最佳時間點才進行交換。

雙緩沖+Vsync工作模型:

without_vsync
draw_with_vsync.png

在這種模型下,只有當 VSync 信號產生時,交換back & frame buffer,CPU/GPU 才會開始繪制。當幀率大于刷新頻率時,幀率就會被迫跟刷新頻率保持同步,從而避免“tearing”現象。開啟VSync的本質就是強制拉平我們的GPU每秒繪制的幀數和屏幕的刷新頻率。

Google在Android的實踐

為改善Android上的UI體驗, Google在2012年的I/O大會上宣布了Project Butter,并在Android 4.1中正式搭載了實現機制。

從Android4.1版本開始,Android對顯示系統進行了重構,引入了三個核心元素:VSYNC, Tripple Buffer和Choreographer。VSYNC是Vertical Synchronized的縮寫,是一種定時中斷;Tripple Buffer是顯示數據的緩沖區;Choreographer起調度作用,將繪制工作統一到VSYNC的某個時間點上,使應用的繪制工作有序進行。

那么Triple buffer是干啥的?
看下上面的方案,在CPU/GUP幀率大于屏幕刷新的情況下皆大歡喜,萬一幀率低于屏幕刷新率呢?使用A、B代表兩塊buffer看下圖不同情況下的工作情況:


double_buffer_with_vsync.png
double_buffer_jank.png

若以60fps為屏幕刷新率,當CPU/GPU的處理時間超過16ms時,第一個VSync到來時,緩沖區B中的數據還沒有準備好,于是只能繼續顯示之前A緩沖區中的內容。而B完成后,又因為缺乏VSync pulse信號,它只能等待下一個signal的來臨。于是在這一過程中,有一大段時間是被浪費的。當下一個VSync出現時,CPU/GPU馬上執行操作,此時它可操作的buffer是A,相應的顯示屏對應的就是B。這時看起來就是正常的。只不過由于執行時間仍然超過16ms,導致下一次應該執行的緩沖區交換又被推遲了——如此循環反復,便出現了越來越多的“Jank”。


triple_buffer_vsync.png

Triple Buffering是MultipleBuffering的一種,指的是系統使用3個緩沖區用于顯示工作。當第一次VSync發生后,CPU不用再等待了,它會使用第三個buffer C來進行下一幀數據的準備工作,有效地降低了系統顯示錯誤的機率。

那是Buffer的數量越多越好?那肯定是不科學的,triple buffer是為了充分發揮CPU/GPU的工作效率,降低等待是充分利用流水線思路;各項任務的處理能力上限觸頂使用多的buffer也只是增加額外的buffer管理調度任務。

Choreographer的作用

上面提到了硬件會產生Vsync信號作為觸發標志,如果幀率是60ms那如何統一16.6ms內的任務等待Vsync到來才執行呢?

Choreographer就是用來統一協調任務的,動畫、繪制和輸入事件的任務會先進入Choreographer的隊列;由Choreographer申請硬件的Vsync信號,收到Vsync信號后統一回調任務隊列內的任務。

參考文章

屏幕成像原理以及FPS優化Tips
Android屏幕刷新顯示機制
Android繪制優化----系統顯示原理
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,283評論 6 530
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,947評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,094評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,485評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,268評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,817評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,906評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,039評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,551評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,502評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,662評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,188評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,907評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,304評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,563評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,255評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,637評論 2 370