圖形渲染流程

一、CPU 和 GPU

CPU 是計算機整個系統(tǒng)的運算核?咕缎、控制核?珠十。CPU 內部采用的是流水線結構, 使其擁有一定程度的并行計算能力。CPU 擅長分支預測等復雜操作凭豪。
GPU 是可進行繪圖運算工作的專用微處理器焙蹭,是一個被高度優(yōu)化設計的用來并發(fā)計算的硬件單元。GPU擅長對大量數據進行大量并行的工作嫂伞,GPU 各個單元依懶性非常低孔厉。

CPU和GPU工作原理
CPU內部組成
GPU內部組成

1.1 CPU 和 GPU異構系統(tǒng)

在實際應用中 CPU 和 GPU 有兩種異構系統(tǒng)來協(xié)同工作

兩種架構方式
  • 左邊是分離式架構系統(tǒng),CPU 和 GPU 擁有各自存儲系統(tǒng)帖努。CPU 的內存也是我們所說的手機或是電腦內存撰豺,GPU 的內存是顯存(幀緩沖)也就是圖形頂點數據存儲的位置。這種結構的缺點在于 PCI-e 相對于兩者具有低帶寬和高延遲然磷,數據的傳輸成了其中的性能瓶頸郑趁。目前使用非常廣泛,如PC姿搜、智能手機等寡润。
  • 右邊是耦合式架構系統(tǒng),CPU 和 GPU 共享內存和緩存舅柜。主要應用在游戲主機中梭纹,如 PS4。

1.2 CPU 和 GPU工作流程

當 CPU 遇到圖像處理的需求時致份,會調用 GPU 進行處理变抽,主要流程是這樣:

  1. 將主存的處理數據復制到顯存中
  2. CPU 指令驅動 GPU
  3. GPU 中的每個運算單元并行處理
  4. GPU 將顯存結果傳回主存

1.3 GPU 圖形渲染流程

GPU 圖形渲染流程具體可以分為六個步驟:

  • 頂點著色器
  • 圖元裝配
  • 幾何著色器
  • 光柵化
  • 片元著色器
  • 測試與混合

開發(fā)人員可以使用 GLSL 語言進行對頂點著色器和片元著色器修改,這也是唯一能對圖形修改的地方氮块,片元著色器主要是對圖形的飽和度進行修改绍载。

二、圖像顯示方式和原理

隨機掃描顯示

在隨機掃描方式中滔蝉,電子束能在屏幕上進行隨機移動击儡,軌跡隨顯示內容變化而變化,只在需要顯示字符和圖形的地方掃描蝠引,而不是全屏掃描阳谍。一般用于高清晰度的專用圖形顯示器中蛀柴。特點:

  • 顯示速度快、畫面清晰矫夯、線條輪廓十分光滑
  • 控制方式復雜鸽疾,只能用于字符和圖形顯示,不適用于顯示隨機圖像
隨機掃描方式

光柵掃描顯示

在光柵掃描方式中训貌,電子束在水平和垂直同步信號的控制下有規(guī)律的掃描整個屏幕制肮。特點:

  • 控制方式簡單
  • 畫面質量較好和穩(wěn)定
  • 對掃描頻率要求高
光柵掃描方式

那為什么人眼感覺不到屏幕在刷新呢?這里有個專有名詞"視覺暫留"旺订,人眼在觀察景物的時候弄企,光信號傳入大腦神經,需經過一段短暫的時間区拳,光的作用結束后拘领,視覺形象并不會立即消失。在人眼中1秒16幀的畫面就是連續(xù)的了樱调。

圖像顯示流程

CPU 計算好顯示內容提交至 GPU约素,GPU 渲染完成后將渲染結果存入幀緩沖區(qū),視頻控制器會按照 VSync 信號逐幀讀取幀緩沖區(qū)的數據(位圖)笆凌,經過數模轉換(數字信號->模擬信號)后最終由顯示器(逐行掃描)進行顯示.

圖像顯示流程

幀緩沖和垂直同步

為了效率問題圣猎,GPU 通常會引入兩個緩沖區(qū),即雙緩沖機制乞而。在這種情況下送悔,GPU 會預先渲染一幀放入一個緩沖區(qū)中,用于視頻控制器的讀取爪模。當下一幀渲染完畢后欠啤,GPU 會直接把視頻控制器的指針指向第二個緩沖區(qū)。
雙緩沖雖然能解決效率問題屋灌,但會引入一個新的問題洁段。造成畫面撕裂現象,原因是視頻控制器還未讀取完 A 幀緩沖區(qū)數據時共郭,顯示到屏幕一半的畫面祠丝,當GPU 將新的一幀數據提交到 B 幀緩沖區(qū)并且交換緩沖區(qū)后,視頻控制器就會把新的一幀數據的下半段顯示到屏幕上除嘹,就會出現畫面撕裂的現象写半。

畫面撕裂原因
雙緩存區(qū)示意圖

為了解決這個問題,GPU 通常有一個機制叫做垂直同步尉咕,垂直同步技術相當于在幀緩沖區(qū)加鎖操作污朽,當電子束都掃描完成以后才去讀取數據。當開啟垂直同步后龙考,GPU 會等待顯示器的 VSync 信號發(fā)出后蟆肆,才進行新的一幀渲染和緩沖區(qū)更新。這樣能解決畫面撕裂現象晦款,也增加了畫面流暢度炎功,但需要消費更多的計算資源,也會帶來部分延遲缓溅。

iOS 設備會始終使用垂直同步+雙緩存區(qū)的策略蛇损。

掉幀

垂直同步+雙緩存區(qū)解決了畫面撕裂問題,但是有出現了一個新的問題——掉幀坛怪。掉幀是重復渲染同一幀數據淤齐。屏幕顯示 A 緩沖區(qū)的數據,當垂直同步信號到來時袜匿,B 緩沖區(qū)的數據還沒有準備好更啄,屏幕繼續(xù)顯示 A 緩存區(qū)的數據,等到 B 緩沖區(qū)數據準備完成后居灯,交換緩沖區(qū)祭务,按照這個方式一直執(zhí)行下去,就會造成卡頓怪嫌。

掉幀示意圖

大致的流程是這樣:
接收垂直同步信號 -> CPU 和 GPU 還沒有準備好數據 -> 視頻控制器就拿不到 FrameBuffer 里面的數據 -> 重復渲染同一幀數據

為了解決這個問題义锥,提出了三緩存區(qū)機制,合理使用 CPU 和 GPU 的閑置時間岩灭,三緩存區(qū)也會存在掉幀問題拌倍,但是它能減少掉幀次數。這樣的話卡頓的原因也就找到了:

  • CPU 和 GPU 渲染流水線耗時過長——掉幀
  • 垂直同步+雙緩沖區(qū)是以掉幀為代價解決屏幕撕裂問題

三噪径、iOS系統(tǒng)圖像渲染流程

圖形圖形渲染框架介紹

  • UIKit 主要提供界面呈現能力柱恤、事件響應能力、驅動 RunLoop 運行與系統(tǒng)內核通信熄云。簡單來說就是主要負責界面展示膨更、事件響應以及是 RunLoop 的需求方。
  • CoreAnimation 來自于 QuartzCore 框架缴允,提供了圖形處理和視頻圖像處理的能力荚守。不要認為 CoreAnimation 只是負責核心動畫,還負責通過調用 OpenGL ES 把我們用代碼構建的界面顯示到屏幕上练般。
  • CoreGraphics 提供了非常強大的輕量級2D渲染能力矗漾。CoreGraphics 負責創(chuàng)建顯示到屏幕上的數據模型。

三者的關系是通過界面展示以及動畫的創(chuàng)建薄料、執(zhí)行關聯(lián)起來的敞贡,所以它們之間是協(xié)作而不是從屬的關系。

協(xié)作圖

UIView 與 CALayer(CoreAnimation Layer) 關系

1. UIView 可以響應事件摄职,CALayer 不可以

查看 UIKit 框架可以得知 UIView 是繼承 UIResponder誊役,這也就說明 UIView 有接收事件和響應事件處理的能力获列。CALayer 是繼承 NSObject 所以說 CALayer 沒有接收和響應事件處理的能力。

2. UIView 的屬性與 CALayer 的屬性是映射關系

一個 CALayer 的 frame 是由 anchorPoint蛔垢、position击孩、bounds、transform 共同決定的鹏漆,對于一個 UIView 的 frame 只是簡單返回 CALayer 的 frame 而已巩梢。同樣的 UIView 的 center、bounds 也是返回 CALayer 的一些屬性艺玲。

3. UIView 主要負責管理 CALayer 时鸵,CALayer 負責繪制

重寫 [view drawRect:rect] 和 [layer display] 可以看出 UIView 是 CALayer 的代理绷落,從而繪制出視圖內容左敌。

關系圖

4. 執(zhí)行動畫的時候止潘,是 CALayer 在為 UIView 做隱式動畫

CALayer 修改屬性是默認支持隱式動畫的,在給 UIView 的 Layer 做動畫的時候若治,UIView 作為 CALayer 的代理慨蓝,CALayer 通過 actionForLayer:forKey: 向 UIView 請求相應的 action(動畫行為)。

CALayer 內部維護著三種圖層樹端幼,分別是 presentLayer Tree(動畫樹)礼烈,modeLayer Tree(模型樹), Render Tree(渲染樹)婆跑,在做動畫的時候此熬,我們其實修改的是 presentLayer Tree ,展示在界面上是 modelLayer Tree滑进。

渲染流程

渲染流程圖

App 本身并不負責渲染任務犀忱,負責渲染任務是一個獨立的進程—— Render Server。App 通過 IPC (進程間通信) 將渲染任務和相關數據提交給 Render Server扶关。Render Server 處理完數據提交給 GPU阴汇。最后 GPU 渲染完成后把這一幀畫面放到 FrameBuffer,等到 Vsync 信號到來节槐,視頻控制器就會把這一幀畫面顯示到屏幕上搀庶。

CoreAnimation 渲染流水線
Render Server 操作步驟

CoreAnimation 在 RunLoop 中注冊了一個 Observer,監(jiān)聽 RunLoop 即將休眠(BeforeWaiting)和退出(Exit)事件铜异。如果調整 UIView / CALayer 視圖層級哥倔、屬性設置,或是手動調用 UIView / CALayer 的 setNeedsLayout / setNeedsDisplay 方法后揍庄,這些操作都會被 CALayer 標記咆蒿,并通過 CATransaction 提交到一個全局容器(Backing Store)去。當 RunLoop 即將休眠或是退出時,關注該事件的 Observer 就會在回調中把所有待處理的 UIView / CALayer 執(zhí)行實際的繪制和調整沃测,最終交給 GPU 進行渲染缭黔。如果圖層有動畫,通過 CADisplayLink 穩(wěn)定的刷新機制會不斷喚醒 RunLoop蒂破,使得不斷觸發(fā) Observer 回調试浙,從而根據動畫時間來更新屬性值并繪制出來。

RunLoop-UIView-CALayer
方法調用棧

在方法調用棧中可以很清晰的看出來每一個方法是做什么的寞蚌,其中還包括了 UIView 與 CALayer 的關系。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末钠糊,一起剝皮案震驚了整個濱河市挟秤,隨后出現的幾起案子,更是在濱河造成了極大的恐慌抄伍,老刑警劉巖艘刚,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異截珍,居然都是意外死亡攀甚,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門岗喉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秋度,“玉大人,你說我怎么就攤上這事钱床〖运梗” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵查牌,是天一觀的道長事期。 經常有香客問我,道長纸颜,這世上最難降的妖魔是什么兽泣? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮胁孙,結果婚禮上唠倦,老公的妹妹穿的比我還像新娘。我一直安慰自己浊洞,他們只是感情好牵敷,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著法希,像睡著了一般枷餐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上苫亦,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天毛肋,我揣著相機與錄音怨咪,去河邊找鬼。 笑死润匙,一個胖子當著我的面吹牛诗眨,可吹牛的內容都是我干的。 我是一名探鬼主播孕讳,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼匠楚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了厂财?” 一聲冷哼從身側響起芋簿,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎璃饱,沒想到半個月后与斤,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡荚恶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年撩穿,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谒撼。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡食寡,死狀恐怖,靈堂內的尸體忽然破棺而出嗤栓,到底是詐尸還是另有隱情冻河,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布茉帅,位于F島的核電站叨叙,受9級特大地震影響,放射性物質發(fā)生泄漏堪澎。R本人自食惡果不足惜擂错,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望樱蛤。 院中可真熱鬧钮呀,春花似錦、人聲如沸昨凡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽便脊。三九已至蚂四,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背遂赠。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工久妆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人跷睦。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓筷弦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親抑诸。 傳聞我的和親對象是個殘疾皇子烂琴,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345