前言:
《iOS Core Animation Advanced Techinques》学习笔记之:
iOS核心动画1——认识图层CALayer
iOS核心动画2——隐式动画和图层行为
视图绘制的原理:
要想提高图层显示或动画的性能,就得先明白iOS绘图和动画的原理。我们设置了图层用于显示或动画的属性后,iOS都做了哪些处理,最终才将结果绘制渲染在屏幕上的?
视图绘制大概有一下几个阶段:
在
APP
内部的4个阶段:
1.程序设置
layer
的各修饰属性,如frame
,backgroundColor
等;
2.设置layer
的内容。包括设置contents
属性,重写drawRect:
方法,或在CALayer
代理方法drawLayer:inContext:
中绘制;
3.Core Animation
框架准备要渲染图层的各属性的数据,以及要做的动画的参数,准备将其发送给render server
。同时在这个阶段也会解压要渲染的image
。(除了用imageNamed:
方法从bundle
加载的image
会立刻解压之外,其他的比如直接从硬盘读入,或者从网络上下载的image
不会立刻解压,只有在真正要渲染的时候才会解压);
4.最后,Core Animation
将打包图层的属性数据及动画参数,通过IPC(内部处理通信)
发送给sender server
。
在
APP
外的2个阶段:
当
render server
收到打包的数据后,会被序列化为render tree
。然后render server
会做下面两件事:
1.根据layer
的各种属性(如果是动画的,会计算动画layer
的属性的中间值),用OpenGL
准备渲染。
2.渲染到屏幕上。
总共有以上6个阶段。其中前5个阶段都在软件层面处理(通过CPU
),只有最后一个阶段是被GPU(图形处理器)
执行。如果是做动画的话,最后两个步骤会一直重复执行直到动画结束。
我们都知道iOS设备的屏幕刷新频率是60HZ。如果上面的这些步骤在一个刷新周期内无法做完(1/60s),就会造成掉帧,即界面卡顿。
图层性能优化:
了解了图层绘制渲染的原理后,我们可以找出在这些阶段中可以会存在性能问题的步骤,并进行优化。
下面是总结的一些可优化的点:
1| layer
的层级结构太复杂或有复杂的几何形状:
若某视图的层级结构太过复杂的话,各层视图的frame
将会花费大量计算,尤其是Autolayout
的话,更消耗CPU
。做动画时图层往往要做frame
的更改,这就得让CPU
计算出图层的frame
在每帧的数据值。
另外复杂的几何形状会大大增多需要渲染的“三角板”和栅格化的操作。
2|半透明合成:
因为图层是有层级结构的,各个图层叠加累积在一起。 假如最上层的图层是不透明的(opaque
为YES
)。那屏幕上的这块区域里最终显示的内容即为这块最上层图层的内容,它把下面图层的内容都遮住了。当opaque
为YES
时,用于屏幕显示的目标像素值只需简单地拷贝而来。
但是,假如某图层是半透明的,那它在当前层的像素值是当前图层的像素值和底部一层的图层的像素值叠加计算而来。这就是一个运算量很大的数学计算,另外,合成时还可能因为上下图层“像素未对齐”而导致额外的计算量。
因此,我们设置图层的backgroundColor
等属性时最好设置为一个不透明的颜色;若一个图层是不透明的,则主动告诉程序opaque
为YES
,而不是让程序费资源去计算。
3|离屏绘制:
什么是离屏渲染(绘制)?
有些情况下,不能直接在屏幕上绘制渲染。需要先绘制在离屏的上下文中,等绘制好了后,再转移至
render server
进行渲染。如此一来,就造成了额外的开销:其一,是创建了新的缓冲区,开辟了新的内存;其二,是将离屏offScreen
切换至当前屏幕onScreen
时上下文切换的代价很大。
常见的离屏绘制有这几种:
1.圆角、遮罩、阴影或光删化都会先绘制在离屏offScreen
的上下文context
上;
2.重写的drawRect
方法,或CALayerDelegate
的drawLayer:inContext:
方法为了支持对图层内容的任意绘制,Core Graphics
会先绘制一个等大小的图片,然后再将其通过IPC
传送到渲染服务器。
关于离屏渲染更多参考:离屏渲染学习笔记
更多资料参考:
性能调优
图层性能
iOS 视图,动画渲染机制探究
绘制像素到屏幕上
Advanced Graphics and Animations for iOS Apps(session 419)学习与延伸
网友评论