Core Animation渲染过程

上一篇iOS图片渲染过程初探介绍了屏幕显示图像的原理,这一篇探讨下iOS和OS X系统下Core Animation在可视元素显示中的作用。下图是可视元素的渲染框架

iOS-render-frame.png

图层和视图

要了解Core Animation在渲染上的作用,我们必须要先了解什么是图层,什么又是视图。
图层(Layer)它是使用Core Animation执行任何操作的核心构件。和视图一样,图层的可管理信息包含集合结构、内容、可是属性;与视图不同的是,图层没有定义自己的外观,图层仅管理周围位图的状态信息。位图可以是视图绘图结果或者一张图片。CALayer继承自NSObject类,负责显示UIView或NSView提供的内容contents。CALayer有三个视觉元素:背景色、内容和边框,其中,内容的本质在iOS上是一个CGImage,在OS X(10.6)上也可以是NSImage。
视图(View)在iOS当中,所有的视图都从一个叫做UIVIew的基类派生而来,UIView可以处理触摸事件,可以支持基于Core Graphics绘图,可以做仿射变换(例如旋转或者缩放),或者简单的类似于滑动或者渐变的动画。在OS X中View主要是NSView,NSView处理的是鼠标事件等。
这里我们能够知道视图和图层的分离完美的实现了视图显示和视图事件的完美解耦,所以即使在OS X和iOS用户交互方式的不同,还是一样可以使用Core Animation完成图层层面的操控。


Core Animation渲染

在iOS和OS X系统的软件开发过程中,每一个View都会包含一个CALayer的实例属性。每一个View视图能够被显示到屏幕的原理和图像显示到屏幕的原理相同。在可视元素显示的过程中,Core Animation是作为负责在硬件合成和操纵应用内容的基础构件。图层对象用于管理和操控你的应用内容。图层将捕获的内容放入一副位图中,图形硬件(GPU)能非常容易的操控你的位图。
Core Animation为动画视图和其他可视元素提供了一个通用的系统。Core Animation不是视图的替代品,而是一种和视图相集成的技术。由于位图可以直接由图形硬件直接操控,所以通过将视图的内容缓存到位图中,可以获取更好的性能。除了缓存视图内容,Core Animation还可以定义任意可视视图,然后将该对象添加到视图上,最后动画该对象。
如下图所示:Core Animation位于AppKit和UIKit的底层。它被紧密的集成到了Cocoa和Cocoa Touch视图工作流中


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

类似于GPU的图形渲染管线,Core Animation的动画和视图的渲染也有自己的进程流水线。
Core Animation的绘制是通过Core Animation Pipeline实现,它以流水线的形式进行渲染,具体分为四个步骤:

  1. Commit Transaction: CoreAnimation提交会话,包括自己和子树(view hierarchy)的layout状态,细分为:
    • Layout: 构建视图布局,如addSubview等。layout过程会建立(set up)views,会调用重载的layoutSubviews方法,这里会发生view的创建,以及通过addSubview将layers添加进view层级中,将内容聚集起来,并做一些轻量的数据库查找(因为不能在这里停留太久,轻量级的操作可以是本地化字符串的查找以供应label的layout),这个过程通常是CPU密集型或者I/O密集型。
    • Display: 重载drawRect: 进行视图绘制,该步骤使用CPU与内存。display过程绘制views,这个阶段是如果drawRect有重载的话会通过drawRect绘制内容或者做字符串绘制,需要注意的是这个阶段实际上是CPU或者内存密集型的,由于这里是用core graphics渲染,所以通常用CGContext来渲染,也要避免在这里有过多的耗时。
    • Prepare: 主要处理图像的解码与格式转换等操作。prepare commit会做一些额外的Core Animation工作,比如图像解码和图像转换,图像解码很容易理解,如果view层级中有图片,则会在这个阶段进行JPEG/PNG的解码,图像转换只是在存在有GPU不支持的图像时才会发生,典型的场景是对位图进行索引以避免特定的图像类型
    • Commit: 将Layer递归打包并发送到Render Server。commit过程是递归的,所以需要确保view树的平整以确保高效
  2. Render Server: 负责渲染工作,会解析上一步Commit Transaction中提交的信息并反序列化成渲染树(render tree),随后根据layer的各种属性生成绘制指令,并在下一次VSync信号到来时调用OpenGL进行渲染。
  3. GPU: GPU会等待显示器的VSync信号发出后才进行OpenGL渲染管线,将3D几何数据转化成2D的像素图像和光栅处理,随后进行新的一帧的渲染,并将其输出到缓冲区。
  4. Dispaly: 从缓冲区中取出画面,并输出到屏幕上。


    CoreAnimation-Pipeline.jpg

Core Animation 动画

虽然Core Animation 被紧密的集成到Cocoa和Cocoa Touch视图的渲染工作中,但是仍然保留了部分用于扩展功能的接口,这些接口暴露给了视图,以至于我们可以细粒度地制作和控制应用中的视图的动画。

animation-process.png

如图所示,视图动画本身分为三个处理过程,两个在应用内,最后一个在render server 中。
第一个阶段是建立动画,更新View层级,通常为animateWithDuration:animaitons:
第二阶段是准备提交动画的阶段,即如上所述的4阶段的commit transaction,唯一不同的地方在于提交阶段,不仅需要提交view层级,也需要提交animation,因为我们需要将animation提交出去给render server以期以后的animation的更新不需要通过进程间通信(IPC)与应用进行再次的沟通,这样更高效。

参考:
为什么必须在主线程操作UI

你可能感兴趣的:(Core Animation渲染过程)