iOS介面卡頓之離屏渲染

weixin_34006468發表於2016-03-07

   導讀:

離屏渲染在開發中帶來介面卡頓問題一直讓開發者們頭疼.今天在這裡寫一遍關於離屏渲染的博文.希望大家有所收穫

現在的iOS開發越來越注重App效能和使用者體驗了.

效能優化和記憶體管理是iOS面試中必問的兩道面試題.也是程式設計中最難的部分之一

要想知道如何解決介面卡頓問題,那你必須對離屏渲染有所瞭解

要想成為一個高階iOS程式設計師,你必須學會如何效能優化,記憶體優化

讀懂了這篇文章,掌握離屏渲染的原理,讓你的App從此遠離卡頓.


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

一.On-Screen Rendering

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

當前螢幕渲染是不需要額外建立新的快取.也不需要開啟新的上下文.相較與離屏渲染,效能更好.

      但是受當前螢幕渲染的侷限因素限制(只有自身上下文,螢幕快取有限等),很對圖形渲染,當前螢幕渲染是解決不了的.這時必須使用到離屏渲染.如何正確的使用離屏渲染,下面會為你詳細描述

二.Off-Screen Rendering

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

特殊的“離屏渲染”:CPU渲染

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

普通的離屏渲染

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

1.建立新緩衝區

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

2.上下文切換

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

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

1.shouldRasterize(光柵化)

2.masks(遮罩)

3.shadows(陰影)

4.edge antialiasing(抗鋸齒)

5.group opacity(不透明)

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

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

在開發時需要根據實際情況來選擇最優的實現方式,儘量使用On-Screen Rendering。簡單的Off-Screen Rendering可以考慮使用Core Graphics讓CPU來渲染。

如何抉擇

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

儘量使用當前螢幕渲染

鑑於離屏渲染、CPU渲染可能帶來的效能問題,一般情況下,我們要儘量使用當前螢幕渲染。

離屏渲染 VS CPU渲染

由於GPU的浮點運算能力比CPU強,CPU渲染的效率可能不如離屏渲染;但如果僅僅是實現一個簡單的效果,直接使用CPU渲染的效率又可能比離屏渲染好,畢竟普通的離屏渲染要涉及到緩衝區建立和上下文切換等耗時操作。普通的離屏繪製是發生在繪製服務(是獨立的處理過程)並且同時通過GPU執行。當OpengGL的繪製程式在繪製每個layer的時候,有可能因為包含多子層級關係而必須停下來把他們合成到一個單獨的快取裡。你可能認為GPU應該總是比CPU牛逼一點,但是在這裡我們還是需要慎重的考慮一下。因為對GPU來說,從當前螢幕(on-screen)到離屏(off-screen)上下文環境的來回切換,代價是非常大的。因此對一些簡單的繪製過程來說,這個過程有可能用CoreGraphics,全部用CPU來完成反而會比GPU做得更好。所以如果你正在嘗試處理一些複雜的層級,並且在猶豫到底用-[CALayer setShouldRasterize:] 還是通過CoreGraphics來繪製層級上的所有內容,唯一的方法就是測試並且進行權衡。

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

簡而言之:

如果覺得前面的過於抽象,沒看懂,不要緊,把下面的看懂就能正確的解決離屏渲染帶來的介面卡頓的問題了

1.儘量使用當前螢幕渲染,能不使用離屏渲染則儘量不用,你應當儘量避免使用 layer 的 border、corner、shadow、mask 等技術.

2.必須離屏渲染時,相對簡單的檢視應該使用cpu渲染,相對複雜的檢視則使用一般的離屏渲染.

相關文章