WWDC14_419_高級圖形和動畫

原標題為:《Advanced Graphics and Animation For iOS Apps》。下載的文件名有點不同寸癌。本筆記內(nèi)容為視頻學(xué)習(xí)和實踐探索。另外 objc 的這篇文章《繪制像素到屏幕上》和本視頻的內(nèi)容有很大程度的交集,推薦一下汰扭。

視頻內(nèi)容

  • Core Animation pipeline
  • Rendering concepts
  • UIBlurEffect
  • UIVibrancyEffect
  • Profiling tools
  • Case studies
Core Animation Pipeline

這個章節(jié)的時長為06:35囤躁,但信息量非常大冀痕。每個小節(jié)拉出來都能另寫一章。


屏幕內(nèi)容的顯示流程

讓屏幕頁面流暢應(yīng)該保證頁面刷新率為 60 幀/秒狸演,1 幀的時間大概就是 16.67 ms了言蛇。Core Animation 這個框架的名字很具有誤導(dǎo)性,讓大家以為這個框架只是用來實現(xiàn)動畫的宵距,實際上 Core Animation 框架做了很多基礎(chǔ)工作:組合屏幕上的內(nèi)容腊尚,追蹤視圖結(jié)構(gòu)和內(nèi)容的變化。流程圖中 Commit Transaction 前面的紅框代表觸發(fā)視圖內(nèi)容變化的事件满哪,比如點擊按鈕婿斥,之后Core Animation 框架會捕獲到屏幕內(nèi)容的變化并提交給 Render Server(渲染服務(wù)器),Render Server 里另外一個版本的 Core Animation 框架負責(zé)解碼并繪制內(nèi)容哨鸭。

動畫處理的流程
Commit Transaction的具體過程

值得注意的是:在 Prepare 這個階段做的事是圖像解碼以及圖像轉(zhuǎn)換民宿。無論是網(wǎng)上下載的圖像還是從磁盤讀取圖像文件,得到的圖像一般是不能直接用于顯示的像鸡,需要解碼為位圖(bitmap)勘高。如果你的視圖中使用了 JPEGs 或是 PNGs的圖像,將在這個階段進行解碼;如果你使用了 GPU 不支持的圖像格式(就是 JPEG 和 PNG 之外的格式)华望,那么圖像就需要轉(zhuǎn)換格式蕊蝗。Path 團隊的圖像緩存開源庫FastImageCache就利用這個特性來加速圖像的顯示。

Rendering concepts

這一節(jié)介紹了一些基本的渲染知識:屏幕被分割成 NxN 像素的小塊來渲染赖舟,每個小塊的大小與 SoC(System on Chip) 的cache相關(guān)蓬戚。具體的操作過程如下:對于一個 app icon,被當做一個 CALayer 來渲染宾抓,而 CALayer 在 Core Animation 中被劃分為兩個三角形子漩,每個三角形可以被繼續(xù)分割成多個三角形,對每一個三角形單獨渲染石洗。

Layer in CoreAnimation is two triangles

split into multiple triangles

后面的幢泼,我看完之后基本就忘了,所以想了解到底怎么渲染的可以看看這一段讲衫。大致過程是渲染然后合成缕棵,在開頭的文章中有對這塊的敘述。

UIVisualEffectView

在 iOS 8 中蘋果放出了新的 UIView 子類 UIVisualEffectView涉兽。蘋果在 iOS 7 中廣泛使用了虛化效果招驴,卻沒有給出接口,民間大多使用 GPUImage 這個庫來實現(xiàn)虛化效果枷畏,終于在 iOS 8 里給出了官方支持别厘。UIVisualEffectView 支持 UIBlurEffect 和 UIVibrancyEffect 兩種效果,前者是虛化內(nèi)容拥诡,后者在前者的基礎(chǔ)上再合成一個透明視圖触趴。

UIBlurEffect(虛化效果)的實現(xiàn)正是基于上一節(jié)提到的渲染+合成。其手法是這樣:抓取用作背景的內(nèi)容然后進行縮放以降低計算量渴肉,然后分別進行水平虛化和垂直虛化(翻譯得可能不對冗懦,就是橫著來一下,然后豎著來一下宾娜,而不是直接對整個內(nèi)容進行虛化批狐,降低計算量)扇售,最后將縮小的內(nèi)容再放大到原來的尺寸進行著色前塔。

虛化過程

效果有三種樣式:Extra light, Light, Dark。這三種樣式對性能的要求依次降低承冰。另外 iPad 2以及 iPad 3不支持虛化(who care?)华弓。而 UIVibrancyEffect 效果是在 UIBlurEffect 的基礎(chǔ)上再合成一個視圖。UIVibrancyEffect 效果對性能要求極高困乒,蘋果工程師建議避免對全屏使用該效果寂屏,并給出了優(yōu)化性能的建議:Rasterization 和 Group Opacity。

1.Rasterization
設(shè)置 CALayer 的 shouldRasterize 屬性為 YES 能夠為程序觸發(fā)離屏渲染(Offscreen Rendering),更新內(nèi)容時能夠額外渲染不在屏幕范圍上的內(nèi)容用作緩存迁霎;不要濫用吱抚,因為離屏渲染的緩存大小只有屏幕尺寸的 2.5 倍大;當離線渲染的內(nèi)容超過 100 ms 沒有使用將會被清除考廉。應(yīng)該在以下場景中才開啟該屬性:

  • 繪制代價很大的靜態(tài)內(nèi)容
  • 結(jié)構(gòu)非常復(fù)雜的視圖

要注意秘豹,離屏渲染的計算代價是很大的,與之相比昌粤,通過普通手段顯示內(nèi)容要廉價很多(有很多術(shù)語由于沒有鋪墊寫出來只會更讓人困惑既绕,還是推薦看開頭的文章)。只有當屏幕中的圖層不變時才可以利用這個選項來優(yōu)化涮坐。因此凄贩,在一般情況下,還是不要開啟離屏渲染的好袱讹。
2.Group Opacity
如果一個 layer 的 opacity 值小于 1.0 并且該 layer 含有子 layer 或者有背景圖像疲扎,開啟groupopacity 將會觸發(fā)離屏渲染。建議一直關(guān)閉該功能廓译,將 layer 的 allowsGroupOpacity 設(shè)置為 NO评肆。

Profiling Tool:

Xcode 套件中的 Instruments 工具估計是最沒有被有效利用的工具之一,我以前就只用來查看內(nèi)存占用以及泄露問題了非区。實際上利用 Instruments來對視圖和動畫性能調(diào)優(yōu)是非常高效的瓜挽。視圖和動畫的性能一旦有問題自然是非常不爽快的,相對于手工一遍遍主觀調(diào)試征绸,Instruments 能夠直接指出性能不佳的部分久橙,一目了然。
(Instruments 的文檔令人發(fā)指管怠,基本上找不到主講工程師在視頻中提到的 debug options)
主講的工程師在介紹工具之前給出了性能調(diào)優(yōu)的檢查選項:


Performance Investigation Mindset
Core Animation Instrument

在 Xcode 的菜單欄中依次選擇 Product->Profile 后淆衷,會啟動 Instruments 工具,有多種分析和調(diào)試工具渤弛,選擇 Core Animation祝拯。
根據(jù)視頻內(nèi)容探索了以下調(diào)試選項:

  • Color blended layers
    屏幕上綠色的部分表示該處的 layer 是 opaque (不透明的),這樣 GPU 在合成時就不需要考慮該 layer 下面的內(nèi)容直接輸出該 layer 的內(nèi)容就夠了她肯;紅色的部分表示該處的內(nèi)容需要 blend(混合)佳头,GPU 需要將該 layer 以及該 layer 下方的內(nèi)容進行混合后才能輸出,工作量大晴氨。


    IMG_0384.PNG
  • Color Hits Green and Misses Red
    該選項與前面提到的Rasterization有關(guān)康嘉。綠色表明離屏渲染的 cache 中還有該部分的緩存,紅色表示該部分的緩存已被移除籽前。
  • Color Copied Images
    前面提到過亭珍,圖像要被解碼后才能用于顯示敷钾,GPU只支持對 JPEG 和 PNG 格式,其他格式的圖像需要由 CPU 來轉(zhuǎn)化解碼肄梨,最好放在后臺中解碼阻荒。
    我在使用這個選項的時候未發(fā)現(xiàn)畫面有任何變化,嘗試了瀏覽 gif 也沒有發(fā)現(xiàn)異樣众羡〔扑桑看來需要使用這個選項的場景太少。
  • Color MisalignedImages
    找出對字節(jié)沒有對齊的圖像并進行著色纱控。當圖像尺寸與其容器 View 的尺寸不一樣的時候辆毡,需要把該圖像進行縮放。
  • Color Offscreen-Renderd Yellow
    將離屏渲染的部分標記為黃色甜害,查找出觸發(fā)離屏渲染的部分舶掖。
  • Color Compositing Fast-Path Blue
    將由顯示硬件(原話為 display hardware)進行混合的 layers 標記為藍色,這是個好事尔店,因為這意味著 GPU 的工作更少眨攘。
  • Flash Updated Regions
    標記屏幕上正在刷新的內(nèi)容為黃色。

看完這部分以后進行性能調(diào)優(yōu)不用到處猜瓶頸所在了嚣州,直接使用工具查看鲫售。

OpenGL ES Driver Instruments

在 Xcode 6.3 里,這個組件是找不到的该肴,應(yīng)該是改名成 GPU Driver 了情竹。這個組件可以用來統(tǒng)計大部分的運行參數(shù):CPU 占用,視圖幀率匀哄,渲染使用秦效,設(shè)備使用以及更多參數(shù)。我開發(fā)中的 App 的幀率還沒有超過 50 的涎嚼,真是慘不忍睹阱州。該組件可以回答性能優(yōu)化列表「Performance Investigation Mindset」中前面三個問題。

以前很少使用 Instruments,也因為我目前做的東西很少需要使用這些工具,當然還有可能是因為不知道能做什么所以沒法用埠忘,惡性循環(huán)。

View Debugging

Xcode 6 的新特性之一夜惭,可以在 Xcode 里實時查看 UI 結(jié)構(gòu)了,但只支持通過 Xcode 運行的 app刁憋。相比大名鼎鼎的 Reveal 還是有不少差距的滥嘴。
當然木蹬,兩者的定位不一樣至耻。目前來說對于調(diào)試夠用了若皱。

選擇調(diào)試工具
Case Study

案例學(xué)習(xí)這一塊給出了兩個常見的性能隱患:
1.陰影繪制
以前的常見代碼:

CALayer *imageViewLayer = cell.imageView.layer;
imageViewLayer.shadowColor = [UIColor blackColor].CGColor;
imageViewLayer.shadowOpacity = 1.0;
imageViewLayer.shadowRadius = 2.0;
imageViewLayer.shadowOffset = CGSizeMake(1.0, 1.0)
//設(shè)置了上面這些屬性后就能繪制陰影了,這樣一來Core Animation 必須知道陰影的形狀才能進行繪制尘颓,但這樣就必須使用離屏渲染來渲染內(nèi)容走触。(為啥,不明白)下面的方法可以避免離屏渲染疤苹。
imageViewLayer.shadowPath = CGPathCreateWithRect(imageRect, NULL)

2.圓角繪制
以往的常見代碼:

CALayer *imageViewLayer = cell.imageView.layer; 
imageViewLayer.cornerRadius = imageHeight / 2.0;
imageViewLayer.masksToBounds = YES;

在給出的例子里互广,工程師使用一個 TableView 顯示一些圓形頭像。(由于說到關(guān)鍵時刻字幕消失了我聽不懂了卧土,所以不明白為什么這里產(chǎn)生了離屏渲染)我的理解是惫皱,由于重用機制,被重用的 Cell 每一次出現(xiàn)尤莺,Core Animation 都要為 Cell 繪制圓角旅敷,這種機制導(dǎo)致了離屏繪制。
工程師的建議是:

  • 不要對重用的 Cell 使用 mask颤霎。
  • 如果做不到上一點媳谁,嘗試這個方法來:
    1.將 TableView 的背景設(shè)置為 solid white;
    2.在縮略圖上方繪制一個圓形,圓形外圍為白色友酱;
    這樣做減少了離屏渲染卻也增加了混合兩個圖層的工作晴音,但從性能上來說依然比原來好。

總結(jié):

離屏渲染代價昂貴缔杉,盡量避免
1·利用工具 CA Instrument 來找出它們
2·知道怎么做來避免它們(上面的 shadowPath 就是一個例子)(這個比較上锤躁,還沒搞清楚離屏渲染到底怎么觸發(fā)的)
在不同的設(shè)備上測試性能
1·使用 OpenGL ES Driver Instrument 來觀察 GPU
2·使用 Time Profiler Instrument 來觀察 CPU
知道視圖的結(jié)構(gòu)和任何隱含的繪制成本
1·這個對于 table cells 和滾動比較重要

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市或详,隨后出現(xiàn)的幾起案子进苍,更是在濱河造成了極大的恐慌,老刑警劉巖鸭叙,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件觉啊,死亡現(xiàn)場離奇詭異,居然都是意外死亡沈贝,警方通過查閱死者的電腦和手機杠人,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宋下,“玉大人嗡善,你說我怎么就攤上這事⊙纾” “怎么了罩引?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長枝笨。 經(jīng)常有香客問我袁铐,道長揭蜒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任剔桨,我火速辦了婚禮屉更,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘洒缀。我一直安慰自己瑰谜,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布树绩。 她就那樣靜靜地躺著萨脑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪饺饭。 梳的紋絲不亂的頭發(fā)上砚哗,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音砰奕,去河邊找鬼蛛芥。 笑死,一個胖子當著我的面吹牛军援,可吹牛的內(nèi)容都是我干的仅淑。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼胸哥,長吁一口氣:“原來是場噩夢啊……” “哼涯竟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起空厌,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤庐船,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嘲更,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體筐钟,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年赋朦,在試婚紗的時候發(fā)現(xiàn)自己被綠了篓冲。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡宠哄,死狀恐怖壹将,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情毛嫉,我是刑警寧澤诽俯,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站承粤,受9級特大地震影響暴区,放射性物質(zhì)發(fā)生泄漏闯团。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一颜启、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浪讳,春花似錦缰盏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至透揣,卻和暖如春济炎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辐真。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工须尚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侍咱。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓耐床,卻偏偏與公主長得像,于是被迫代替她去往敵國和親楔脯。 傳聞我的和親對象是個殘疾皇子撩轰,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容