1. 程式人生 > >iOS離屏渲染

iOS離屏渲染

離屏渲染概念

  • layer不做觸發離屏渲染的操作時,是可以直接放入緩衝區中讓GPU直接渲染在螢幕內的。但是當你設定圓角、陰影、遮罩、邊界反鋸齒、設定組不透明、光柵化等觸發離屏渲染的操作後,layer繪製以後的幀不能直接放入到GPU讀取幀所在的緩衝區了。因此需要再建立一個新的緩衝區,在繪製圖層時,會在這兩個緩衝區之間進行上下文切換。這種切換上下文的操作代價是,如果切換時間過長或者渲染操作過長就會導致卡頓和效能問題。綜上所述,GPU直接讀取幀渲染到螢幕上的緩衝區就是螢幕內渲染,而在螢幕之外所建立的緩衝區就是離屏渲染。
  • drawRect也會引起離屏渲染,在drawRect
    中,一般使用Core Graphic來繪製圖形和文字,這些圖形的計算和渲染是CPU來負責的,渲染結束以後再交付給GPU顯示。

光柵化

  • 光柵化可以理解為是CPU對繪製內容的圖層生成點陣圖來快取一段時間,如果該時間內需要再次渲染該圖層,可以直接通過該點陣圖來進行渲染,不需要再次計算和切換上下文,但是這僅僅限於相同的圖層。

優化建議

下面兩種方法都可以在一定程度上優化離屏渲染產生的效能問題,但是不能避免離屏渲染:
  1. 使用 dractRect方法用CPU來分擔GPU壓力。
  2. 通過上面對光柵化的描述,可以使用光柵化對圖層進行短暫快取。
下面來說一下如何避免設定圓角產生的離屏渲染問題。
  1. 對圖片進行重新繪製,利用CoreGraphics重新繪製一張帶圓角的圖片,這樣就可以不用設定圖層屬性而達到圓角的效果。不過這個方法也有缺點:繪製是無法避免的,對於UITableView來說,每次複用都要重新繪製一次,對CPU會產生一定的壓力。如果繪製的圓角內容比較多的話,用這種方法有可能會產生更大的效能問題。解決辦法可以針對此種方案專門設定一套快取策略,但是如果快取的圖片過多,也會帶來記憶體壓力。所以建議如果圖片較少的情況下,可以採用此種方案,如果圖片過多的話建議採用其他方案。
  2. UIImageView上面再覆蓋一個UIImageView,覆蓋的UIImageView是帶有透明圓角中心的圖片。這樣也可以避免離屏渲染。

注意事項

 Tips: 
  1.親測,iOS9以後,UIImageView在沒有設定背景顏色的情況下,直接設定圓角是不會觸發離屏渲染的。
  2.iOS9以後,設定圓角時只有在同時設定了layer.backgroundColor以及layer.contents後才會觸發離屏渲染。