美文网首页
core-Animation动画性能优化

core-Animation动画性能优化

作者: 我的月亮你的心 | 来源:发表于2017-04-10 15:32 被阅读67次

    iOS 中core-Animation动画性能优化

    关于绘图和动画有两种处理的方式:CPU(中央处理器)和GPU(图形处理器)。但是对于图像的处理,通常用硬件会更快,因为GPU使用图像对高度并行浮点运算做了优化,我们想尽可能把屏幕渲染的工作交给硬件去处理。问题在于GPU并没有无限制处理性能,而且一旦资源用完的话,性能就会开始下降了(即使CPU并没有完全占用)。大多数动画性能优化都是关于智能利用GPU和CPU,使得它们都不会超出负荷。

    iOS的动画和屏幕上组合的图层实际上被一个单独的进程管理,而不是你的应用程序。这个进程就是所谓的渲染服务。在iOS5和之前的版本是springboard进程(同事管理着iOS的主屏)。在iOS6之后的版本中叫做backboard。

    当运行一段动画时候,这个过程会被四个分离的阶段被打破:

    1.布局 ---这是准备你的视图/图层的层级关系,以及设置图层属性(位置,背景色,边框等等)的阶段

    2.显示---这是图层的寄宿图片被绘制的阶段。绘制有可能涉及你的`-drawRect:`和`-drawLayer:inContext:`方法的调用路径。

    3.准备---这是Core Animation准备发送动画数据到渲染服务的阶段。这同时也是Core Animation将要执行一些别的事务例如解码动画过程中将要显示的图片的时间点。

    4.提交---Core Animation打包所有图层和动画属性,然后通过IPC(内部处理通信)发送到渲染服务进行显示。

    5.渲染前准备 --- 图层和动画到达渲染服务进程,他们会被反序列化来形成另一个叫做*渲染树*的图层树。使用这个树状结构,渲染服务对动画的每一帧做出如下工作:对所有的图层属性进行插值运算,设置OpenGL几何形状(纹理化的三角形)来执行渲染前准备。

    6.渲染---在屏幕上渲染可见的三角形。

    所以一共有六个阶段;最后两个阶段在动画过程中不停地重复。前五个阶段都在软件层面处理(通过CPU),只有最后一个被GPU执行。而且,你真正只能控制前两个阶段:布局和显示。Core Animation框架在内部处理剩下的事务,你也控制不了它。

    GPU为一个具体的任务做了优化:它用来采集图片和形状(三角形),运行变换,应用纹理和混合然后把它们输送到屏幕上。现代iOS设备上可编程的GPU在这些操作的执行上又很大的灵活性,但是Core Animation并没有暴露出直接的接口。除非你想绕开Core Animation并编写你自己的OpenGL着色器,从根本上解决硬件加速的问题,那么剩下的所有都还是需要在CPU的软件层面上完成。

    降低GPU性能的几个重要因数:

    1.太多的几何结构(深度)-这发生在需要太多的三角板来做变换,以应对处理器的光栅化的时候。现代iOS设备的图形处理几百万个三角板,所以在coreannimation中几何结构并不是GPU的瓶颈所在。但由于图层在显示之前通过IPC渲染服务器的时候,太多的图层就会引起cpu的瓶颈。

    2.重绘(混合)---主要由重叠的半透明图层引起。GPU的*填充比率*(用颜色填充像素的比率)是有限的,所以需要避免*重绘*(每一帧用相同的像素填充多次)的发生。

    3.离屏绘制---这发生在当不能直接在屏幕上绘制,并且必须绘制到离屏图片的上下文中的时候。离屏绘制发生在基于CPU或者是GPU的渲染,或者是为离屏图片分配额外内存,以及切换绘制上下文,这些都会降低GPU性能。对于特定图层效果的使用,比如圆角,图层遮罩,阴影或者是图层光栅化都会强制Core Animation提前渲染图层的离屏绘制。但这不意味着你需要避免使用这些效果,只是要明白这会带来性能的负面影响。

    4.过大的图片 - 如果视图绘制超出GPU支持的2048x2048或者4096x4096尺寸的纹理,就必须要用CPU在图层每次显示之前对图片预处理,同样也会降低性能。

    降低CPU性能的几个重要因数:

    1.布局计算--如果你的视图层级过于复杂,当视图呈现或者修改的dan时候,计算图层帧率就会消耗一部分时间。autolayout自动布局。

    2.视图懒加载 -- iOS只会当视图控制器的视图显示到屏幕上时才会加载它。这对内存使用和程序启动时间很有好处,但是当呈现到屏幕上之前,按下按钮导致的许多工作都会不能被及时响应。比如控制器从数据库中获取数据,或者视图从一个nib文件中加载,或者涉及IO的图片显示(见后续“IO相关操作”),都会比CPU正常操作慢得多。

    3.Core Graphics绘制 -- 如果对视图实现了`-drawRect:`方法,或者`CALayerDelegate`的`-drawLayer:inContext:`方法,那么在绘制任何东西之前都会产生一个巨大的性能开销。为了支持对图层内容的任意绘制,Core Animation必须创建一个内存中等大小的寄宿图片。然后一旦绘制结束之后,必须把图片数据通过IPC传到渲染服务器。在此基础上,Core Graphics绘制就会变得十分缓慢,所以在一个对性能十分挑剔的场景下这样做十分不好。

    4.解压图片--PNG或者JPEG压缩之后的图片文件会比同质量的位图小得多。但是在图片绘制到屏幕上之前,必须把它解码成一个原始的尺寸。为了节省内存,iOS通常直到真正绘制的时候才去解码图片。根据你加载图片的方式,第一次对图层内容赋值的时候(直接或者间接使用`UIImageView`)或者把它绘制到Core Graphics中,都需要对它解压,这样的话,对于一个较大的图片,都会占用一定的时间。(异步加载,缓存nscache,提前解压 coregraphics)

    对动画的直观判断:

    为了做到动画的平滑,你需要以60FPS(帧每秒)的速度运行,以同步屏幕刷新速率,如果掉帧明显出出现卡顿现象。

    相关文章

      网友评论

          本文标题:core-Animation动画性能优化

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