美文网首页
CoreAnimation深入了解

CoreAnimation深入了解

作者: lkm_0bdc | 来源:发表于2020-07-05 21:50 被阅读0次

如图,Core Animation位于AppKit和UIKit的底层。它被紧密的集成到了Cocoa和Cocoa Touch视图工作流中。虽然被紧密的集成,Core Animation也存在扩展功能的接口,这些接口暴露给了应用的视图。使用这些接口能让你更好地控制应用中的动画。

Core Animation是一个复合引擎,自身并不是一个绘图系统。它只是一个负责在硬件上合成和操纵应用内容的基础构件。Core Animation的核心是图层对象,图层对象用于管理和操控你的应用内容。图层将捕获的内容放到一副位图中,图形硬件能够非常容易的操控你的位图。在大部分应用中,图层被作为一种管理视图内容的方式。

UIKit 

UIKit是一组Objective-C API,为线条图形、Quartz图像和颜色操作提供Objective-C 封装,并提供2D绘制、图像处理及用户接口级别的动画。UIKit包括UIBezierPath(绘制线、角度、椭圆及其它图形)、UIImage(显示图像)、UIColor(颜色操作)、UIFont和UIScreen(提供字体和屏幕信息)等类以及在位图图形环境、PDF图形环境上进行绘制和 操作的功能等, 也提供对标准视图的支持,也提供对打印功能的支持。UIKit中UIView类本身在绘制时自动创建一个图形环境(对应Core Graphics层的CGContext类型)作为当前的图形绘制环境。在绘制时可以调用UIGraphicsGetCurrentContext 函数获得当前的图形环境。

Core Graphics

Core Graphics基于Quartz高级绘图引擎,驱动GPU时,需要依赖于OpenGL/Metal.主要用于运行时绘制图像。开发者可以使用此框架来处理基于路径的绘图,转换,颜色管理,离屏渲染,图案,渐变和阴影,图像数据管理,图像创建和图像遮罩以及PDF文档创建,显示和分析。

当开发者需要在运行时创建图像时,可以使用Core Graphics去绘制。与之相对的是运行前创建图像,例如用Photoshop提前做好图片素材直接导入应用。相比之下,我们更需要Core Graphics去在运行时实时计算、绘制一系列图像帧来实现动画。

Core Image

Core Image与Core Graphics恰恰相反,Core Graphics用于在运行时创建图像,而Core Image用于处理运行前创建的图像。Core Image框架拥有一系列现成的图像过滤器,能对一寸照的图像进行高效的处理。

大部分情况下,Core Image会在GPU中完成工作,如果GPU忙,会使用CPU进行处理。

OpenGL ES

OpenGL ES是OpenGL的子集。在图形渲染原理一文中提到过OpenGL是一套第三方标准,函数的内部实现由对应的GPU厂商开发实现。

UIView

在iOS中,所有的视图都是从UIView这个基类派生而来的,UIView可以处理用户触摸事件,可以支持基于Core Graphics绘图,可以支持仿射变换(旋转、缩放等),可以支持类似于滑动、渐变等动画。

CALayer

CALayer在概念上同UIView有些类似,同样也是被层级关系树管理的矩形块,也可以包含一些内容(图片、文字、背景色),也可以管理子图层,有一些方法和属性用来做动画和变换。

那么为什么CALayer可以呈现可视化内容呢?因为CALayer基本等同于一个纹理。纹理是GPU进行图像渲染的重要依据。在图形渲染原理中提到纹理本质上就是一张图片,因此CALayer也包含一个contents属性指向一块缓存区,称为backing store,可以存放位图(Bitmap)。iOS中将该缓存区保存的图片称为寄宿图

平行的层级关系

1、每一个视图都有一个CALayer实例的图层属性,视图的职责就是:创建并管理这个图层,以确保子视图在视图的层级关系中被添加或者移除时,对应的图层在“层级关系树中” 有相同的操作。

那为什么要基于UIView和CALayer提供两个平行的层级关系?

职责分离

UIView 与UILayer区别

UIView 主要负责视图与用户的交互,uiview继承于UIResponder,真正的内容显示是通过UIView里面的图层CALayer来完成的(没有交互能力),并且CALayer直接继承 NSObject。

不同的图层树反映了不同的动画状态

使用Core Animation的app拥有三个图层对象集合。每一个图层对象集合在呈现app内容上都扮演着不同的角色。

Ø模型图层树中的对象(或简称“图层树”)用的最多。在这个树中的对象是模型对象,模型对象负责存储所有动画的目标值。无论何时改变图层的属性值,你使用的始终是某一个模型对象。

Ø呈现树中的对象包含所有运行中的动画的瞬时值。图层树对象包含的是动画的目标值,而呈现树中的对象代表显示在屏幕上动画的当前值。你不应该更改这个树中的对象。相反,你使用这些对象来读取当前动画的值,可能用于创建开始于这些值的新的动画。

Ø在渲染树中的对象执行实际的动画,并且对Core Animation是不公开的。

Core Animation 流水线

介绍一下Core Animation流水线的工作原理:

在 iOS上,动画和视图的渲染其实是在另外一个进程做的(下面我们叫这个进程 render server),在 iOS 5 以前这个进程叫 SpringBoard,在 iOS 6 之后叫 BackBoard。

App通过IPC将渲染任务及相关数据提交给Render Server。Render Server处理完数据后,再传递至GPU。最后由GPU调用iOS的图像设备进行显示。

Core Animation流水线的详细过程如下:

· 首先,由app处理事件(Handle Events),如:用户点击操作,在此过程中app可能需要更新视图树,相应地,图层树也会被更新。

· 其次,app通过CPU完成对显示内容的计算,如:视图的创建、布局计算、图片解码、文本绘制等。在完成对现实内容的计算之后,app对图层进行打包,并在下一次RunLoop时将其发送至Render Server,即完成了一次commit Transaction操作。

· Render Server主要执行OpenGL、Core Graphics相关程序,并调用GPU。

· GPU则在物理层上完成了对图像的渲染。

· 最终,GPU通过Frame Buffer、视频控制器等相关部件,将图像显示在屏幕上。

 对上述步骤进行串联,他们执行所消耗的时间圆圆超过16.67ms,因此为了满足对屏幕的60FPS刷新率的支持,需要将这些步骤进行分解,通过流水线的方式并行执行

Commit Transaction

在Core Animation流水线中,app调用Render Server前的最后一步Commit Transaction其实可以细分为4个步骤:

· Layout: 构建视图布局如addSubview等操作

· Display: 重载drawRect:进行时图绘制,该步骤使用CPU与内存

· Prepare: 主要处理图像的解码与格式转换等操作

· Commit: 将Layer递归打包并发送到Render Server

Render Server

负责渲染工作,会解析上一步Commit Transaction中提交的信息并反序列化成渲染树(render tree),随后根据layer的各种属性生成绘制指令,并在下一次VSync信号到来时调用OpenGL进行渲染。

GPU

GPU会等待显示器的VSync信号发出后才进行OpenGL渲染管线,将3D几何数据转化成2D的像素图像和光栅处理,随后进行新的一帧的渲染,并将其输出到缓冲区。

Dispaly

从缓冲区中取出画面,并输出到屏幕上。

动画渲染原理

iOS动画的渲染也是基于上述Core Animation流水线完成的。这里我们重点关注app与Render Server的执行流程。

日常开发中,如果不是特别的复杂动画,一般使用UIViewAnimation实现,iOS将其处理过程分为如下三部阶段:

· Step1:调用animationWithDuration:animations:方法

· Step2:在Animation Block中进行Layout,Display,Prepare,Commit等步骤。

· Step3:Render Server根据Animation逐帧进行渲染。

相关文章

网友评论

      本文标题:CoreAnimation深入了解

      本文链接:https://www.haomeiwen.com/subject/tlybqktx.html