Advanced Graphics and Animations for iOS Apps

主題:

  1. Core Animation pipeline
  2. 動畫
  3. 渲染相關(guān)概念
  4. UIBlurEffect and UIVibrancyEffect
  5. Profiling Tools and demon

一、Core Animation pipeline

app 直接使用 core Animation 或者通過 UIKit 間接使用 core Animation 來創(chuàng)建圖層;

app 進(jìn)程不為 Core Animation 提供渲染工作,Core Animation 會將所有的圖層提交到 render server 來完成渲染工作。

render server

  1. 獨(dú)立的進(jìn)程;
  2. 具有一個 Core Animatio 對應(yīng)的服務(wù)端版本,專門接收 Core Animation 提交的圖層;
  3. 使用 GPU進(jìn)行渲染,硬件加速;
  4. 對應(yīng)框架為 OpenGL 或者 metal 框架進(jìn)行渲染,

硬件加速即指 GPU 渲染。因?yàn)橐话愣?,CPU 雖然也是硬件,但是工作內(nèi)容大部分是面向軟件層面,需要處理很多中斷指令。相對而言,GPU 工作內(nèi)容是純計算,其設(shè)計上也是為了高并發(fā)和高效率的計算,所以 GPU 渲染一般稱為硬件加速,使用 CPU 渲染則效率相對低下;

大概流程

app:

  1. 用戶通過操作 app 觸發(fā)事件;
  2. 事務(wù)提交到 render server(具體分為4步,見后文);

render server/GPU

  1. 解碼圖層;
  2. 等待下一幀開始的信號。iOS 上是雙緩沖機(jī)制,所以這個信號表示上一個 buffer 已經(jīng)掃描展示,顯示器已經(jīng)切換到了另一個 buffer。當(dāng)下,需要繪制新的位圖并更新到上一幀所在的 buffer 上;
  3. 調(diào)用 openGL 或者 metal 函數(shù),利用 GPU 進(jìn)行繪制渲染;
  4. 將繪制完成的位圖存儲到 buffer 中,等待顯示器掃描展示,這個步驟和上個步驟如果未在 16.67ms 內(nèi)完成,則會造成卡頓;


    coreAnimation pipline

commit transaction

1. layout

兩個關(guān)鍵方法:layoutSubviewsaddSubview;這一步中,view 被創(chuàng)建,layer 被創(chuàng)建并被添加到視圖樹中;這一步中,可以做一些輕量的數(shù)據(jù)庫操作,比如 label 的布局需要字符串;

這一步發(fā)生在 CPU,一般都是 CPU 操作或者 I/O 操作(外存);

2. display

關(guān)鍵方法:drawRect;如果這個方法被重寫了,那么就會調(diào)用 Core Graphic 來利用 CPU 進(jìn)行繪制。

因?yàn)榇藭r的繪制時不可見的,所以這里使用的 CPU 在內(nèi)存中進(jìn)行位圖的繪制;這里嚴(yán)格來說,可以說成是離屏渲染,因?yàn)椴皇侵苯永L制在 buffer 上的。

GPU 的繪制一般都是直接繪制在 buffer 上,GPU 的離屏渲染大概是開辟一塊內(nèi)存進(jìn)行渲染操作,最后將兩塊內(nèi)存混合,在兩塊內(nèi)存之間進(jìn)行切換會消耗性能。 Apple 對于離屏渲染的界定其實(shí)就是 GPU 離屏渲染,所以 CG 相關(guān)的繪制函數(shù)不被認(rèn)定為時離屏渲染;

這一步一般是 CPU 操作或者 memory(內(nèi)存) 操作,因?yàn)槭鞘褂?CPU 繪制位圖,需要使用到內(nèi)存,而不是本地化存??;

這一步是適用 CPU 渲染,所以應(yīng)當(dāng)盡量避免過多或者范圍過大的繪制,最好直接使用 layer,因?yàn)?Layer 實(shí)際就是一個指向 bitmap 的指針,而且 layer 是通過 core Animation 實(shí)現(xiàn),而不是 core Graphic,其會盡可能將渲染操作提交到 GPU 上執(zhí)行,這也就是 Apple 所說的硬件加速;

上面已經(jīng)解釋,但是再啰嗦幾句。硬件軟件只是一種說法,CPU 處理的事物更多的是來自軟件,所以常說 CPU 面向的是軟件層面,而 GPU 的操作基本都是全量利用 GPU 的計算能力來進(jìn)行渲染,不會處理各種中斷、if 判斷等,所以常說 GPU 面向硬件。

3. prepare

這一步主要是對圖層中所包含的圖片進(jìn)行解碼和轉(zhuǎn)換。

解碼就是我們常說的將圖片解碼成 bitmap 格式存儲在內(nèi)存中。bitmap 的大小是否和原圖相同,取決于圖片的格式,也就是壓縮方式,PNG 是保真類型的圖片,壓縮之后的圖片存儲大小會變現(xiàn),但是在這一步,會被加載到內(nèi)存,解碼之后的 bitmap 和原圖大小一致;JPEG 則是對 bitmap 中相鄰的點(diǎn)進(jìn)行了裁剪等操作,壓縮之后不僅存儲大小變小,被加載到內(nèi)存中,還原成 bitmap 之后,因?yàn)樵瓐D的信息部分丟失,所以解碼之后的 bitmap 大小會比原 bitmap 要?。?/p>

iOS 的 GPU 支持 JPEG 和 PNG,其他格式需要進(jìn)行轉(zhuǎn)換;

4. package up

關(guān)鍵詞:recursive

遞歸圖層樹,打包所有 layer 信息,傳遞給 render server;

正因?yàn)橐f歸 layer tree,所以布局時盡量減少視圖層級(as flat as possible)能夠保證這一步盡量的高效快速;

animation

animation

步驟和圖層繪制一樣,唯一不同的是在 commit 階段,不僅提交圖層,還提交了動畫。這樣在動畫執(zhí)行過程中,render server 按照既定的流程執(zhí)行動畫,不需要在進(jìn)程之間進(jìn)行通信了。這也是 core Animation 動畫高效的原因;


以下暫時沒看到,暫略

渲染的幾個概念

  1. tile based rendering is how all GPUs work
  2. introduce the concept of render passes
  3. doing a first example by showing you how masking works with render passes

UIBlurEffect 和 UIVibrancyEffect 原理

項(xiàng)目中的 toast 有用到,需要好好總結(jié)下;

instrument

這種使用的東西,比較不好說,要自己體會,略;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容