1. 程式人生 > >什麽是離屏渲染?什麽情況下會觸發?該如何應對?

什麽是離屏渲染?什麽情況下會觸發?該如何應對?

循環 進行 off scree err 如果 概念 ram rendering


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

離屏渲染出發的場景有以下:
  • 圓角 (maskToBounds並用才會觸發)
  • 圖層蒙版
  • 陰影
  • 光柵化
為什麽要有離屏渲染?

大家高中物理應該學過顯示器是如何顯示圖像的:需要顯示的圖像經過CRT電子槍以極快的速度一行一行的掃描,掃描出來就呈現了一幀畫面,隨後電子槍又會回到初始位置循環掃描,形成了我們看到的圖片或視頻。

為了讓顯示器的顯示跟視頻控制器同步,當電子槍新掃描一行的時候,準備掃描的時發送一個水平同步信號(HSync信號),顯示器的刷新頻率就是HSync信號產生的頻率。然後CPU計算好frame等屬性,將計算好的內容交給GPU去渲染,GPU渲染好之後就會放入幀緩沖區。然後視頻控制器會按照HSync信號逐行讀取幀緩沖區的數據,經過可能的數模轉換傳遞給顯示器,就顯示出來了。具體的大家自行查找資料或詢問相關專業人士,這裏只參考網上資料做一個簡單的描述。

離屏渲染的代價很高,想要進行離屏渲染,首選要創建一個新的緩沖區,屏幕渲染會有一個上下文環境的一個概念,離屏渲染的整個過程需要切換上下文環境,先從當前屏幕切換到離屏,等結束後,又要將上下文環境切換回來。這也是為什麽會消耗性能的原因了。

由於垂直同步的機制,如果在一個 HSync 時間內,CPU 或者 GPU 沒有完成內容提交,則那一幀就會被丟棄,等待下一次機會再顯示,而這時顯示屏會保留之前的內容不變。這就是界面卡頓的原因。

為什麽要避免離屏渲染?

CPU GPU 在繪制渲染視圖時做了大量的工作。離屏渲染發生在 GPU 層面上,會創建新的渲染緩沖區,會觸發 OpenGL 的多通道渲染管線,圖形上下文的切換會造成額外的開銷,增加 GPU

工作量。如果 CPU GPU 累計耗時 16.67 毫秒還沒有完成,就會造成卡頓掉幀。

圓角屬性蒙層遮罩 都會觸發離屏渲染。指定了以上屬性,標記了它在新的圖形上下文中,在未愈合之前,不可以用於顯示的時候就出發了離屏渲染。

    • 在OpenGL中,GPU有2種渲染方式

      • On-Screen Rendering:當前屏幕渲染,在當前用於顯示的屏幕緩沖區進行渲染操作
      • Off-Screen Rendering:離屏渲染,在當前屏幕緩沖區以外新開辟一個緩沖區進行渲染操作
    • 離屏渲染消耗性能的原因

      • 需要創建新的緩沖區
      • 離屏渲染的整個過程,需要多次切換上下文環境,先是從當前屏幕(On-Screen)切換到離屏(Off-Screen);等到離屏渲染結束以後,將離屏緩沖區的渲染結果顯示到屏幕上,又需要將上下文環境從離屏切換到當前屏幕
    • 哪些操作會觸發離屏渲染?

      • 光柵化,layer.shouldRasterize = YES
      • 遮罩,layer.mask
      • 圓角,同時設置 layer.masksToBounds = YES、layer.cornerRadius大於0
      • 考慮通過 CoreGraphics 繪制裁剪圓角,或者叫美工提供圓角圖片
      • 陰影,layer.shadowXXX,如果設置了 layer.shadowPath 就不會產生離屏渲染

什麽是離屏渲染?什麽情況下會觸發?該如何應對?