Core Animation渲染過程

上一篇iOS圖片渲染過程初探介紹了屏幕顯示圖像的原理,這一篇簡書探討下iOS和OS X系統(tǒng)下Core Animation在可視元素顯示中的作用。下圖是可視元素的渲染框架

iOS-render-frame.png

圖層和視圖

要了解Core Animation在渲染上的作用,我們必須要先了解什么是圖層,什么又是視圖。
圖層(Layer)它是使用Core Animation執(zhí)行任何操作的核心構(gòu)件。和視圖一樣,圖層的可管理信息包含集合結(jié)構(gòu)、內(nèi)容、可是屬性;與視圖不同的是,圖層沒有定義自己的外觀,圖層僅管理周圍位圖的狀態(tài)信息。位圖可以是視圖繪圖結(jié)果或者一張圖片。CALayer繼承自NSObject類,負責顯示UIView或NSView提供的內(nèi)容contents。CALayer有三個視覺元素:背景色、內(nèi)容和邊框,其中,內(nèi)容的本質(zhì)在iOS上是一個CGImage,在OS X(10.6)上也可以是NSImage。
視圖(View)在iOS當中,所有的視圖都從一個叫做UIVIew的基類派生而來,UIView可以處理觸摸事件,可以支持基于Core Graphics繪圖,可以做仿射變換(例如旋轉(zhuǎn)或者縮放),或者簡單的類似于滑動或者漸變的動畫。在OS X中View主要是NSView,NSView處理的是鼠標事件等。
這里我們能夠知道視圖和圖層的分離完美的實現(xiàn)了視圖顯示和視圖事件的完美解耦,所以即使在OS X和iOS用戶交互方式的不同,還是一樣可以使用Core Animation完成圖層層面的操控。


Core Animation渲染

在iOS和OS X系統(tǒng)的軟件開發(fā)過程中,每一個View都會包含一個CALayer的實例屬性。每一個View視圖能夠被顯示到屏幕的原理和圖像顯示到屏幕的原理相同。在可視元素顯示的過程中,Core Animation是作為負責在硬件合成和操縱應用內(nèi)容的基礎(chǔ)構(gòu)件。圖層對象用于管理和操控你的應用內(nèi)容。圖層將捕獲的內(nèi)容放入一副位圖中,圖形硬件(GPU)能非常容易的操控你的位圖。
Core Animation為動畫視圖和其他可視元素提供了一個通用的系統(tǒng)。Core Animation不是視圖的替代品,而是一種和視圖相集成的技術(shù)。由于位圖可以直接由圖形硬件直接操控,所以通過將視圖的內(nèi)容緩存到位圖中,可以獲取更好的性能。除了緩存視圖內(nèi)容,Core Animation還可以定義任意可視視圖,然后將該對象添加到視圖上,最后動畫該對象。
如下圖所示:Core Animation位于AppKit和UIKit的底層。它被緊密的集成到了Cocoa和Cocoa Touch視圖工作流中


Core-Animation-structure.png
Core Animation 的渲染管線

類似于GPU的圖形渲染管線,Core Animation的動畫和視圖的渲染也有自己的進程流水線。
Core Animation的繪制是通過Core Animation Pipeline實現(xiàn),它以流水線的形式進行渲染,具體分為四個步驟:

  1. Commit Transaction: CoreAnimation提交會話,包括自己和子樹(view hierarchy)的layout狀態(tài),細分為:
    • Layout: 構(gòu)建視圖布局,如addSubview等。layout過程會建立(set up)views,會調(diào)用重載的layoutSubviews方法,這里會發(fā)生view的創(chuàng)建,以及通過addSubview將layers添加進view層級中,將內(nèi)容聚集起來,并做一些輕量的數(shù)據(jù)庫查找(因為不能在這里停留太久,輕量級的操作可以是本地化字符串的查找以供應label的layout),這個過程通常是CPU密集型或者I/O密集型。
    • Display: 重載drawRect: 進行視圖繪制,該步驟使用CPU與內(nèi)存。display過程繪制views,這個階段是如果drawRect有重載的話會通過drawRect繪制內(nèi)容或者做字符串繪制,需要注意的是這個階段實際上是CPU或者內(nèi)存密集型的,由于這里是用core graphics渲染,所以通常用CGContext來渲染,也要避免在這里有過多的耗時。
    • Prepare: 主要處理圖像的解碼與格式轉(zhuǎn)換等操作。prepare commit會做一些額外的Core Animation工作,比如圖像解碼和圖像轉(zhuǎn)換,圖像解碼很容易理解,如果view層級中有圖片,則會在這個階段進行JPEG/PNG的解碼,圖像轉(zhuǎn)換只是在存在有GPU不支持的圖像時才會發(fā)生,典型的場景是對位圖進行索引以避免特定的圖像類型
    • Commit: 將Layer遞歸打包并發(fā)送到Render Server。commit過程是遞歸的,所以需要確保view樹的平整以確保高效
  2. Render Server: 負責渲染工作,會解析上一步Commit Transaction中提交的信息并反序列化成渲染樹(render tree),隨后根據(jù)layer的各種屬性生成繪制指令,并在下一次VSync信號到來時調(diào)用OpenGL進行渲染。
  3. GPU: GPU會等待顯示器的VSync信號發(fā)出后才進行OpenGL渲染管線,將3D幾何數(shù)據(jù)轉(zhuǎn)化成2D的像素圖像和光柵處理,隨后進行新的一幀的渲染,并將其輸出到緩沖區(qū)。
  4. Dispaly: 從緩沖區(qū)中取出畫面,并輸出到屏幕上。


    CoreAnimation-Pipeline.jpg

Core Animation 動畫

雖然Core Animation 被緊密的集成到Cocoa和Cocoa Touch視圖的渲染工作中,但是仍然保留了部分用于擴展功能的接口,這些接口暴露給了視圖,以至于我們可以細粒度地制作和控制應用中的視圖的動畫。

animation-process.png

如圖所示,視圖動畫本身分為三個處理過程,兩個在應用內(nèi),最后一個在render server 中。
第一個階段是建立動畫,更新View層級,通常為animateWithDuration:animaitons:
第二階段是準備提交動畫的階段,即如上所述的4階段的commit transaction,唯一不同的地方在于提交階段,不僅需要提交view層級,也需要提交animation,因為我們需要將animation提交出去給render server以期以后的animation的更新不需要通過進程間通信(IPC)與應用進行再次的溝通,這樣更高效。

參考:
為什么必須在主線程操作UI

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容