圖形渲染原理

我們都知道可視化程序都是由 CPU 和 GPU 協(xié)作進行的。那么我們下面先來介紹下這兩個的基本概念:

CPU

  • 主要是用于運算和控制盖淡。
  • 有一定成都的并行運算年柠,但是它是通過不停的切換時間片來達到我們想象中的并行運算。

GPU

  • 主要是用于進行繪圖相關(guān)的運算的微處理器褪迟。
  • 它有很多的運算單元冗恨,可以做到真正的并行運算。

計算機將存儲在內(nèi)存中的形狀轉(zhuǎn)換繪制到屏幕上的過程叫做渲染味赃。渲染過程中最常用的技術(shù)就是光柵化掀抹。

屏幕圖像顯示原理

介紹屏幕圖像顯示原理前,需要先了解下 CRT 顯示器原理心俗。

CRT 顯示器原理

CRT顯示器原理圖

CTR 電子槍是從上到下呈 Z 字形逐行掃描傲武,掃描完成后會就會呈現(xiàn)一幀的畫面,然后電子槍會回到初始位置從新進行掃描城榛。為了同步顯示器的顯示過程和視屏控制器揪利,顯示器會用硬件時鐘產(chǎn)生一系列的定時信號。當電子槍進行掃描時狠持,顯示器會發(fā)出一個水平同步信號(horizonal synchronization)土童,簡稱 HSync;當一幀畫面繪制完成后工坊,電子槍回復到原位献汗,準備繪制下一幀前敢订,顯示器會發(fā)出一個垂直同步信號(vertical synchronization),簡稱 VSync罢吃。顯示器通常以固定的頻率進行刷新楚午,這個刷新率就是 Vsync 信號產(chǎn)生的頻率。

上圖所示為 CPU尿招、GPU和顯示器常見的工作方式矾柜。CPU計算好顯示的內(nèi)容,提交至 GPU就谜,GPU渲染完成后將數(shù)據(jù)提交到幀緩沖區(qū)中怪蔑,顯示器會按照 Vsync 信號逐幀讀取幀緩沖區(qū)中的數(shù)據(jù),經(jīng)過數(shù)模轉(zhuǎn)換最終在顯示器上顯示丧荐。

但是這種情況下是最簡單的情況缆瓣,幀緩沖區(qū)只有一個。當沒有引入垂直同步信號的技術(shù)的時候虹统,這里會造成一個常見的問題弓坞,屏幕撕裂

屏幕撕裂

屏幕撕裂

屏幕撕裂原理

造成的原因是因為车荔,當顯示器讀取幀緩沖區(qū)的內(nèi)容時渡冻,當前幀緩沖區(qū)的數(shù)據(jù)還是上一幀的數(shù)據(jù),所以忧便,在逐行掃描顯示的是老數(shù)據(jù)族吻,當GPU在掃描的過程中,提交了新的數(shù)據(jù)到幀緩沖區(qū)后珠增,顯示器會讀取到新的內(nèi)容呼奢,所以導致下方繪制的是新的數(shù)據(jù),這種情況就是屏幕撕裂產(chǎn)生的原因切平。

解決屏幕撕裂的方法,是使用垂直同步信號 (Vsync) 辐董,相當于加鎖操作悴品,只有 GPU 渲染完一幀,放入幀緩沖區(qū)中简烘,顯示器才會去讀取幀緩沖區(qū)中的內(nèi)容苔严。

在這種情況下,幀緩沖區(qū)的讀取和刷新都會存在較大的效率問題孤澎,為了解決效率問題届氢,就引入了新的技術(shù),雙緩沖區(qū)覆旭。

雙緩沖區(qū)

雙緩沖區(qū)

雙緩沖區(qū)的機制就是退子,GPU會預先渲染一幀數(shù)據(jù)放入一個緩沖區(qū)中岖妄,用于視頻控制器的讀取。當下一幀渲染完畢后寂祥,GPU 會直接把視屏控制器的指針指向第二個緩沖區(qū)荐虐。

但是雙緩沖區(qū)仍然會產(chǎn)生掉幀的問題。具體掉幀的原因可以參考我寫的另一篇文章【UIView的繪制原理及優(yōu)化】丸凭。

在使用了雙緩沖區(qū)和垂直同步信號后福扬,由于總要等待緩沖區(qū)交換之后再進行下一幀的渲染,使得幀率無法完全得到硬件的最高水平惜犀。所以引進了三緩沖區(qū)铛碑。

三緩沖區(qū)

即在等待垂直同步信號到來之前,來回交替兩個離屏緩沖區(qū)虽界,而在垂直同步信號到來時汽烦,屏幕緩沖區(qū)會和最近渲染完成的離屏緩沖區(qū)進行交換。

渲染過程

iOS下的圖形渲染框架

官方框架圖.png
iOS下的渲染框架.png

UIKit/AppKit

如果你開發(fā)過iOS/Mac浓恳,就會對此框架比較熟悉刹缝。iOS 下使用的是 UIKit,MacOS 下使用的是 AppKit颈将,我們通常使用 UIKit/AppKit 組件中的 Layout 以及 backgroundColor 等屬性來完成日常的界面繪畫工作梢夯。
其實 UIKit/AppKit 本身并不具備屏幕成像的能力,它主要負責用戶操作事件的響應晴圾。

那我們?nèi)粘i_發(fā)中的 UIKit 組件是如何呈現(xiàn)到屏幕上的呢颂砸?

Core Animation

Core Animation官方文檔

Core Animation Programming Guide

Core Animation,乍一看好像是做動畫的死姚,其實動畫只是 Core Animation 中的一部分人乓。它最初是有一個叫 Layer Kit 演變而來的。

Render, compose, and animate visual elements.

Core Animation 主要用于渲染都毒、混合和動畫視覺元素色罚,可以理解為是一個復合引擎。旨在為了可能快的組合屏幕上不同的顯示內(nèi)容账劲。這些內(nèi)容被分解成獨立的圖層戳护,即 CALayer。從本質(zhì)上來言瀑焦,CALayer 是用戶所能在屏幕上看到的一切的基礎腌且。

Metal

早期蘋果底層也是使用 OpenGL ES 來進行開發(fā)的。在 2014 年的時候推出了 Metal榛瓮,2018年的時候铺董, OpenGL 的 API 已經(jīng)被蘋果廢棄了。蘋果推出 Metal 說是將 3D 圖像的渲染性能提高了 10 倍禀晓。但是主要的原因還是想將核心技術(shù)掌握在自己手中精续。

Metal 類似于 OpenGL ES坝锰,也是一套第三方標準。Core Animation驻右、Core Image什黑、SceneKit、SpriteKit 等顯然框架都是構(gòu)建于 Metal 之上的堪夭。

雖然 OpenGL 已經(jīng)被蘋果所廢棄愕把,但是蘋果已經(jīng)實現(xiàn)了一套機制將 OpenGL 命令無縫橋接到 Metal 上,由 Metal 擔任真正與硬件交互的工作森爽。

Core Graphics

Core Graphics 是基于 Quartz 高級繪圖引擎恨豁,主要用于運行時繪制圖像。開發(fā)者可以用此框架處理基于路徑的繪圖爬迟、轉(zhuǎn)換橘蜜、顏色管理、離屏渲染付呕、漸變计福、陰影、圖像管理等徽职。

Graphics Hardware

圖形處理器象颖,支持 Metal 和 OpenGL ES的圖形硬件蚤认。也就是我們常提到的 GPU猖辫。

UIView 和 CALayer 的關(guān)系

UIKit 中的每一個 UI 視圖控件內(nèi)部都有一個關(guān)聯(lián)的 CALayer误阻,即 backing layer愚战。

由于這種一一對應的關(guān)系,視圖層級擁有 視圖樹 的樹形結(jié)構(gòu)痕檬,對應 CALayer 擁有 圖層樹 的樹形結(jié)構(gòu)儒溉。

其中視圖的職責是創(chuàng)建并管理 圖層桥嗤,以確保子視圖在層級關(guān)系中添加以及被移除時毯辅,其關(guān)聯(lián)的圖層在圖層樹中也有相應的操作埂伦,即保證視圖樹和圖層數(shù)在結(jié)構(gòu)上的一致。

UIView的職責:

  • 視圖的構(gòu)建
  • 簡單的動畫
  • 管理子視圖
  • 觸摸方法等的管理

Layer 的職責:

  • 視圖的繪制思恐,展示的內(nèi)容
  • 對應 UIView 中的子視圖的圖層數(shù)的管理

Core Animation 渲染流水線

Core Animation流水線

實際上沾谜,app本身并不負責渲染,渲染有一個獨立的進程負責壁袄,即 Render Server 進程。

Core Animation 流水線的詳細過程如下:

  • 1媚媒、由 app 處理事件(Handle Event)嗜逻;如:用戶的點擊、觸摸等缭召,在此過程中需要更是視圖樹栈顷,對應的圖層數(shù)也會更新
  • 2逆日、app 中通過 CPU 完成對代碼的邏輯處理,計算出需要顯示的內(nèi)容萄凤;如:視圖的創(chuàng)建室抽、布局計算、圖片解碼靡努、文本繪制等坪圾。在完成對顯示內(nèi)容的計算后,app 對圖層進行打包惑朦,并在下一次 RunLoop 時將其發(fā)送至 Render Server 兽泄,即完成了一次 Commit Transaction 操作。
  • 3漾月、Render Server 主要執(zhí)行 GPU病梢、Core Graphics 相關(guān)程序,并調(diào)用 GPU
  • 4梁肿、GPU 則在物理層上完成對圖像的渲染蜓陌。
  • 5、最終吩蔑,GPU 通過 Frame Buffer 钮热、視屏控制器等相關(guān)部件,將圖像顯示在屏幕上

Commit Transaction

在 Core Animation 流水線中哥纫,app 調(diào)用 Render Server 的 Commit Transaction 其實可以細分為以下4個步驟:

  • layout
    主要是進行視圖的構(gòu)建霉旗;包括:LayoutSubviews 方法的重載,addSubview: 方法填充子視圖等蛀骇。
  • display
    主要進行視圖的繪制厌秒,這里僅僅是設置成要成像的圖元數(shù)據(jù)。重載視圖的 drawReact:方法可以自定義 UIView 的顯示擅憔,其原理是在 drawReact: 方法內(nèi)部繪制寄宿圖鸵闪,該過程使用 CPU 和內(nèi)存
  • prepare
    一般處理圖像的解碼和轉(zhuǎn)換等操作。
  • commit
    將圖層進行打包暑诸,并將它們發(fā)送至 Redner Server蚌讼,該過程會遞歸執(zhí)行,因為圖層和視圖都是以樹形結(jié)構(gòu)存在的个榕。

以上整個流程所執(zhí)行的時間遠遠超過了 16.67 ms篡石,因此為了滿足對屏幕的 60FPS 刷新率的支持,需要將這些步驟進行分解西采,通過流水線的方式進行并行執(zhí)行凰萨,如下圖所示:

參考鏈接

計算機那些事(8)——圖形圖像渲染原理

iOS 圖像渲染原理

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子胖眷,更是在濱河造成了極大的恐慌武通,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件珊搀,死亡現(xiàn)場離奇詭異冶忱,居然都是意外死亡,警方通過查閱死者的電腦和手機境析,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門囚枪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人簿晓,你說我怎么就攤上這事眶拉。” “怎么了憔儿?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵忆植,是天一觀的道長。 經(jīng)常有香客問我谒臼,道長朝刊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任蜈缤,我火速辦了婚禮拾氓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘底哥。我一直安慰自己咙鞍,他們只是感情好,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布趾徽。 她就那樣靜靜地躺著续滋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪孵奶。 梳的紋絲不亂的頭發(fā)上疲酌,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機與錄音了袁,去河邊找鬼朗恳。 笑死,一個胖子當著我的面吹牛载绿,可吹牛的內(nèi)容都是我干的粥诫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼崭庸,長吁一口氣:“原來是場噩夢啊……” “哼怀浆!你這毒婦竟也來了劝堪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤揉稚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后熬粗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搀玖,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年驻呐,在試婚紗的時候發(fā)現(xiàn)自己被綠了灌诅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡含末,死狀恐怖猜拾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情佣盒,我是刑警寧澤挎袜,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站肥惭,受9級特大地震影響盯仪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜜葱,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一全景、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧牵囤,春花似錦爸黄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至汹桦,卻和暖如春鲁驶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背舞骆。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工钥弯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人督禽。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓脆霎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親狈惫。 傳聞我的和親對象是個殘疾皇子睛蛛,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355