離屏渲染?

Core Animation工具用來監測Core Animation性能。它給我們提供了周期性的FPS,并且考慮到了發生在程序之外的動畫(見圖12.4)

Core Animation工具提供了一系列復選框選項來幫助調試渲染瓶頸:

Color Blended Layers(混合和過度繪制)

- 這個選項基于渲染程度對屏幕中的混合區域進行綠到紅的高亮(也就是多個半透明圖層的疊加)。由于重繪的原因,混合對GPU性能會有影響,同時也是滑動或者動畫幀率下降的罪魁禍首之一。

GPU每一幀可以繪制的像素有一個最大限制(就是所謂的fill rate),這個情況下可以輕易地繪制整個屏幕的所有像素。但是如果由于重疊圖層的關系需要不停地重繪同一區域的話,掉幀就可能發生了。

GPU會放棄繪制那些完全被其他圖層遮擋的像素,但是要計算出一個圖層是否被遮擋也是相當復雜并且會消耗處理器資源。同樣,合并不同圖層的透明重疊像素(即混合)消耗的資源也是相當客觀的。所以為了加速處理進程,不到必須時刻不要使用透明圖層。任何情況下,你應該這樣做:

給視圖的backgroundColor屬性設置一個固定的,不透明的顏色

設置opaque屬性為YES

如果用到了圖像,盡量避免透明除非非常必要。如果圖像要顯示在一個固定的背景顏色或是固定的背景圖之前,你沒必要相對前景移動,你只需要預填充背景圖片就可以避免運行時混色了。

如果是文本的話,一個白色背景的UILabel(或者其他顏色)會比透明背景要更高效。

Color Offscreen-Rendered Yellow(離屏渲染)

- 這里會把那些需要離屏渲染的圖層高亮成黃色。這些圖層很可能需要用shadowPath或者shouldRasterize來優化。

當圖層屬性的混合體被指定為在未預合成之前不能直接在屏幕中繪制時,屏幕外渲染就被喚起了。屏幕外渲染并不意味著軟件繪制,但是它意味著圖層必須在被顯示之前在一個屏幕外上下文中被渲染(不論CPU還是GPU)。圖層的以下屬性將會觸發屏幕外繪制:

1、圓角(當和maskToBounds一起使用時)

2、圖層蒙板

3、陰影

屏幕外渲染和我們啟用光柵化時相似,除了它并沒有像光柵化圖層那么消耗大,子圖層并沒有被影響到,而且結果也沒有被緩存,所以不會有長期的內存占用。但是,如果太多圖層在屏幕外渲染依然會影響到性能。

有時候我們可以把那些需要屏幕外繪制的圖層開啟光柵化以作為一個優化方式,前提是這些圖層并不會被頻繁地重繪。

對于那些需要動畫而且要在屏幕外渲染的圖層來說,你可以用CAShapeLayer,contentsCenter或者shadowPath來獲得同樣的表現而且較少地影響到性能。

ColorHitsGreenandMissesRed(光柵化緩存圖層命中情況)

- 當使用shouldRasterizep屬性的時候,耗時的圖層繪制會被緩存,然后當做一個簡單的扁平圖片呈現。當緩存再生的時候這個選項就用紅色對柵格化圖層進行了高亮。如果緩存頻繁再生的話,就意味著柵格化可能會有負面的性能影響了。

光柵化

啟用shouldRasterize屬性會將圖層繪制到一個屏幕之外的圖像。然后這個圖像將會被緩存起來并繪制到實際圖層的contents和子圖層。如果有很多的子圖層或者有復雜的效果應用,這樣做就會比重繪所有事務的所有幀劃得來得多。但是光柵化原始圖像需要時間,而且還會消耗額外的內存。

當我們使用得當時,光柵化可以提供很大的性能優勢,但是一定要避免作用在內容不斷變動的圖層上,否則它緩存方面的好處就會消失,而且會讓性能變的更糟。

Color Copied Images(拷貝的圖片)

- 有時候寄宿圖片的生成意味著Core Animation被強制生成一些圖片,然后發送到渲染服務器,而不是簡單的指向原始指針。這個選項把這些圖片渲染成藍色。復制圖片對內存和CPU使用來說都是一項非常昂貴的操作,所以應該盡可能的避免。

Color Immediately

- 通常Core Animation Instruments以每毫秒10次的頻率更新圖層調試顏色。對某些效果來說,這顯然太慢了。這個選項就可以用來設置每幀都更新(可能會影響到渲染性能,而且會導致幀率測量不準,所以不要一直都設置它)。

Color Misaligned Images(圖片的不正常縮放)

- 這里會高亮那些被縮放或者拉伸以及沒有正確對齊到像素邊界的圖片(也就是非整型坐標)。這些中的大多數通常都會導致圖片的不正常縮放,如果把一張大圖當縮略圖顯示,或者不正確地模糊圖像,那么這個選項將會幫你識別出問題所在。

Color OpenGL Fast Path Blue

- 這個選項會對任何直接使用OpenGL繪制的圖層進行高亮。如果僅僅使用UIKit或者Core Animation的API,那么不會有任何效果。如果使用GLKView或者CAEAGLLayer,那如果不顯示藍色塊的話就意味著你正在強制CPU渲染額外的紋理,而不是繪制到屏幕。

Flash Updated Regions(Core Graphics繪制的圖層)

- 這個選項會對重繪的內容高亮成黃色(也就是任何在軟件層面使用Core Graphics繪制的圖層)。這種繪圖的速度很慢。如果頻繁發生這種情況的話,這意味著有一個隱藏的bug或者說通過增加緩存或者使用替代方案會有提升性能的空間。

一、概念理解

OpenGL中,GPU屏幕渲染有以下兩種方式:

On-Screen Rendering

意為當前屏幕渲染,指的是GPU的渲染操作是在當前用于顯示的屏幕緩沖區中進行。

Off-Screen Rendering

意為離屏渲染,指的是GPU在當前屏幕緩沖區以外新開辟一個緩沖區進行渲染操作。

二、離屏渲染的是是非非

相比于當前屏幕渲染,離屏渲染的代價是很高的,主要體現在兩個方面:

創建新緩沖區

要想進行離屏渲染,首先要創建一個新的緩沖區。

上下文切換

離屏渲染的整個過程,需要多次切換上下文環境:先是從當前屏幕(On-Screen)切換到離屏(Off-Screen);等到離屏渲染結束以后,將離屏緩沖區的渲染結果顯示到屏幕上有需要將上下文環境從離屏切換到當前屏幕。而上下文環境的切換是要付出很大代價的。

三、離屏渲染觸發方式

設置了以下屬性時,都會觸發離屏繪制:

shouldRasterize(光柵化)

masks(遮罩)

shadows(陰影)

edge antialiasing(抗鋸齒)

group opacity(不透明)

需要注意的是,如果shouldRasterize被設置成YES,在觸發離屏繪制的同時,會將光柵化后的內容緩存起來,如果對應的layer及其sublayers沒有發生改變,在下一幀的時候可以直接復用。這將在很大程度上提升渲染性能。

而其它屬性如果是開啟的,就不會有緩存,離屏繪制會在每一幀都發生。

四、另一種特殊的“離屏渲染”

按照之前的說法,如果將不在GPU的當前屏幕緩沖區中進行的渲染都稱為離屏渲染,那么就還有另一種特殊的“離屏渲染”方式:CPU渲染。

如果我們重寫了drawRect方法,并且使用任何Core Graphics的技術進行了繪制操作,就涉及到了CPU渲染。整個渲染過程由CPU在App內同步地完成,渲染得到的bitmap最后再交由GPU用于顯示。

五、Instruments

Instruments的Core Animation工具中有幾個和離屏渲染相關的檢查選項:

Color Offscreen-Rendered Yellow

開啟后會把那些需要離屏渲染的圖層高亮成黃色,這就意味著黃色圖層可能存在性能問題。

Color Hits Green and Misses Red

如果shouldRasterize被設置成YES,對應的渲染結果會被緩存,如果圖層是綠色,就表示這些緩存被復用;如果是紅色就表示緩存會被重復創建,這就表示該處存在性能問題了。

六、如何抉擇

現在擺在我們面前得有三個選擇:當前屏幕渲染、離屏渲染、CPU渲染,該用哪個呢?這需要根據具體的使用場景來決定。

盡量使用當前屏幕渲染

鑒于離屏渲染、CPU渲染可能帶來的性能問題,一般情況下,我們要盡量使用當前屏幕渲染。

離屏渲染 VS CPU渲染

由于GPU的浮點運算能力比CPU強,CPU渲染的效率可能不如離屏渲染;但如果僅僅是實現一個簡單的效果,直接使用CPU渲染的效率又可能比離屏渲染好,畢竟離屏渲染要涉及到緩沖區創建和上下文切換等耗時操作。

總之,具體的選擇應該由性能測試結果來決定。

七、寫在最后

在趙巖同學的點撥下才理解了離屏渲染的概念,在此表示感謝!

如理解有誤還請大家指出。

參考文檔

Getting Pixels onto the Screen(中文翻譯版:繪制像素到屏幕上)

Designing for iOS: Graphics & Performance(中文翻譯版:iOS圖形處理和性能)

a performance minded take on ios design(中文翻譯版:iOS離屏繪制的性能和機制分析)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內容

  • 相比于當前屏幕渲染,離屏渲染的代價是很高的,這也是iOS移動端優化的必要部分。 OpenGL中,GPU屏幕渲染有以...
    一個人在路上走下去閱讀 8,903評論 0 74
  • 前言 在本系列文章的前兩篇中,我們已經了解了iOS Graphic相關的基本概念和影響Graphic性能的諸多因素...
    ac3閱讀 1,172評論 3 3
  • GPU渲染機制 CPU 計算好顯示內容提交到 GPU,GPU 渲染完成后將渲染結果放入幀緩沖區,隨后視頻控制器會按...
    Cdream閱讀 606評論 0 0
  • GPU渲染機制:CPU 計算好顯示內容提交到 GPU,GPU 渲染完成后將渲染結果放入幀緩沖區,隨后視頻控制器會按...
    zgsddzwj閱讀 191評論 0 0
  • 1.說明 在git中如果想忽略掉某個文件,不讓這個文件提交到版本庫中,可以使用修改 .gitignore 文件的方...
    _冷憶閱讀 2,355評論 0 1