iOS介面的繪製和渲染

來源:互聯網
上載者:User

標籤:

介面的繪製和渲染

UIView是如何到顯示的螢幕上的。

這件事要從RunLoop開始,RunLoop是一個60fps的回調,也就是說每16.7ms繪製一次螢幕,也就是我們需要在這個時間內完成view的緩衝區建立,view內容的繪製這些是CPU的工作;然後把緩衝區交給GPU渲染,這裡包括了多個View的拼接(Compositing),紋理的渲染(Texture)等等,最後Display到螢幕上。但是如果你在16.7ms內做的事情太多,導致CPU,GPU無法在指定時間內完成指定的工作,那麼就會出現卡頓現象,也就是丟幀。

60fps是Apple給出的最佳幀率,但是實際中我們如果能保證幀率可以穩定到30fps就能保證不會有卡頓的現象,60fps更多用在遊戲上。所以如果你的應用能夠保證33.4ms繪製一次螢幕,基本上就不會卡了。

總的來說,UIView從Draw到Render的過程有如下幾步:

  • 每一個UIView都有一個layer,每一個layer都有個content,這個content指向的是一塊緩衝,叫做backing store。

  • UIView的繪製和渲染是兩個過程,當UIView被繪製時,CPU執行drawRect,通過context將資料寫入backing store。

  • 當backing store寫完後,通過render server交給GPU去渲染,將backing store中的bitmap資料顯示在螢幕上。

就是從CPU到GPU的過程

pic_5.jpeg

其實說到底CPU就是做繪製的操作把內容放到緩衝裡,GPU負責從緩衝裡讀取資料然後渲染到螢幕上。

就如同的所示

pic_4.jpeg

整個過程也就是一件事:CPU將準備好的bitmap放到RAM裡,GPU去搬這快記憶體到VRAM中處理。
而這個過程GPU所能承受的極限大概在16.7ms完成一幀的處理,所以最開始提到的60fps其實就是GPU能處理的最高頻率。

因此,GPU的挑戰有兩個:

  • 將資料從RAM搬到VRAM中

  • 將Texture渲染到螢幕上

這兩個中瓶頸基本在第二點上。渲染Texture基本要處理這麼幾個問題:

合成(Compositing):

Compositing是指將多個紋理拼到一起的過程,對應UIKit,是指處理多個view合到一起的情況(drawRect只有當addsubview情況下才會觸發)

[self.view addsubview:subview]

如果view之間沒有疊加,那麼GPU只需要做普通渲染即可。 如果多個view之間有疊加部分,GPU需要做blending。

尺寸(Size):

這個問題,主要是處理image帶來的,假如記憶體裡有一張400x400的圖片,要放到100x100的imageview裡,如果不做任何處理,直接丟進去,問題就大了,這意味著,GPU需要對大圖進行縮放到小的地區顯示,需要做像素點的sampling,這種smapling的代價很高,又需要兼顧pixel alignment。計算量會飆升。

離屏渲染(Offscreen Rendering And Mask):

我們來看一下關於iOS中圖形繪製架構的大致結構

pic_3.jpeg

UIKit是iOS中用來系統管理使用者圖形互動的架構,但是UIKit本身構建在CoreAnimation架構之上,CoreAnimation分成了兩部分OpenGL ES和Core Graphics,OpenGL ES是直接調用底層的GPU進行渲染;Core Graphics是一個基於CPU的繪製引擎;

我們平時所說的硬體加速其實都是指OpenGL,Core Animation/UIKit基於GPU之上對電腦圖形合成以及繪製的實現,由於CPU是渲染能力要低於GPU,所以當採用CPU繪製時動畫時會有明顯的卡頓。

但是其中的有些繪製會產生離屏渲染,額外增加GPU以及CPU的繪製渲染。

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

  • On-Screen Rendering即當前螢幕渲染,指的是GPU的渲染操作是在當前用於顯示的螢幕緩衝區中進行。

  • Off-Screen Rendering即離屏渲染,指的是GPU在當前螢幕緩衝區以外新開闢一個緩衝區進行渲染操作。

離屏渲染的代價主要包括兩方面內容:

  • 建立新的緩衝區

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

為什麼需要離屏渲染?

目的在於當使用圓角,陰影,遮罩的時候,圖層屬性的混合體被指定為在未預合成之前不能直接在螢幕中繪製,即當主屏的還沒有繪製好的時候,所以就需要螢幕外渲染,最後當主屏已經繪製完成的時候,再將離屏的內容轉移至主屏上。

離屏渲染的觸發方式:

  • shouldRasterize(光柵化)

  • masks(遮罩)

  • shadows(陰影)

  • edge antialiasing(消除鋸齒)

  • group opacity(不透明)

上述的一些屬性設定都會產生離屏渲染的問題,大大降低GPU的渲染效能。

CPU渲染:

以上所說的都是離屏渲染髮生在OpenGL SE也就是GPU中,但是CPU也會發生特殊的渲染,我們的CPU渲染,也就是我們使用Core Graphics的時候,但是要注意的一點的是只有在我們重寫了drawRect方法,並且使用任何Core Graphics的技術進行了繪製操作,就涉及到了CPU渲染。整個渲染過程由CPU在App內 同步地 完成,渲染得到的bitmap最後再交由GPU用於顯示。

理論上CPU渲染應該不算是標準意義上的離屏渲染,但是由於CPU自身做渲染的效能也不好,所以這種方式也是需要盡量避免的。

分析

所以對於當屏渲染,離屏渲染和CPU渲染的來說,當屏渲染永遠是最好的選擇,但是考慮到GPU的浮點運算能力要比CPU強,但是由於離屏渲染需要重新開闢緩衝區以及螢幕的環境切換,所以在離屏渲染和CPU渲染的效能比較上需要根據實際情況作出選擇。

總結

其實第一部分的實現當時並沒有太多考慮效能上的一些問題,所以具體繪圖效能方面的最佳化,我會在下次的文章中闡述,也是我們App中實際遇到的一些情況以及對應的解決方案。

iOS介面的繪製和渲染

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.