iOS界面渲染流程

·  阅读 1636

来源

UIView渲染

iOS渲染视图的核心是Core Animation 其渲染层次依次为:图层树->呈现树->渲染树

CPU阶段

  1. 布局(Frame)
  2. 显示(Core Graphics)
  3. 准备(QuartzCore/Core Animation)
  4. 通过IPC提交(打包好的图层树以及动画属性)

OpenGL ES阶段

  1. 生成(Generate)
  2. 绑定(Bind)
  3. 缓存数据(Buffer Data)
  4. 启用(Enable)
  5. 设置指针(Set Pointers)
  6. 绘图(Draw)
  7. 清除(Delete)

GPU阶段

  1. 接收提交的纹理(Texture)和顶点描述(三角形)
  2. 应用变换(transform)
  3. 合并渲染(离屏渲染等)

总结

  1. 首先一个视图由CPU进行Frame布局,准备视图和图层的层级关系,查询是否有重写drawRect:或drawLayer:inContext:方法,注意:如果有重写的话,这里的渲染是会占用CPU进行处理的。
  2. CPU会将处理好的视图和图层的层级关系打包,通过IPC(内部处理通信)通道提交给渲染服务,渲染服务由OpenGL ES和GPU组成。
  3. 渲染服务首先将图层数据交给OpenGL ES进行纹理生成和着色。生成前后帧缓存,再根据显示硬件的刷新频率,一般以设备的VSync信号和CADisplayLink为标准,进行前后帧缓存的切换。
  4. 最后,将最终要显示在画面上的后帧缓存交给GPU,进行采集图片和形状,运行变换,应用纹理和混合。最终显示在屏幕上。 iOS平台渲染核心原理的重点主要围绕前后帧缓存、Vsync信号、CADisplayLink

Core Animation

core Animation不仅仅是字面意思的核心动画,而是整个显示核心QuartzCore框架中的Core Animation

image01.png Core Animation是依赖于OpenGL ES做GPU渲染,CoreGraphics做CPU渲染 image02.png

Core Animation 在 RunLoop 中注册了一个 Observer,监听了 BeforeWaiting 和 Exit 事件。这个Observer的 优先级是2000000,低于常见的其他 Observer。当一个触摸事件到来时,RunLoop 被唤醒,App 中的代码会执行一些操 作,比如创建和调整视图层级、设置UIView的frame、修改CALayer的透明度、为视图添加一个动画;这些操作最终都会被 CALayer 捕获,并通过CATransaction提交到一个中间状态去(CATransaction 的文档略有提到这些内容,但并不完 整)。当上面所有操作结束后,RunLoop 即将进入休眠(或者退出)时,关注该事件的 Observer 都会得到通知。这时 CA 注册的那个 Observer 就会在回调中,把所有的中间状态合并提交到GPU去显示;如果此处有动画,CA会通过DisplayLink 等机制多次触发相关流程。

CPU渲染职能

CPU渲染职能主要体现在以下5个方面:

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

OpenGL ES渲染职能

image03.png 简单来说,OpenGL ES是对图层进行取色,采样,生成纹理,绑定数据,生成前后帧缓存。

GPU渲染职能

GPU会根据生成的前后帧缓存数据,根据实际情况进行合成,其中造成GPU渲染负担的一般是:离屏渲染,图层混合,延迟加载。

image04.png

前后帧缓存 & Vsync信号

iOS 的显示系统是由 VSync 信号驱动的,VSync 信号由硬件时钟生成,每秒钟发出 60 次(这个值取决设备硬件,比如 iPhone 真机上通常是 59.97)。iOS 图形服务接收到 VSync 信号后,会通过 IPC 通知到 App 内。App 的 Runloop 在启动后会注册对应的 CFRunLoopSource 通过 mach_port 接收传过来的时钟信号通知,随后 Source 的回调会驱动整个 App 的动画与显示。

image05.png

帧缓存:接收渲染结果的缓冲区,为GPU指定存储渲染结果的区域

帧缓存可以同时存在多个,但是屏幕显示像素受到保存在前帧缓存(front frame buffer)的特定帧缓存中的像素颜色元素的控制。程序的渲染结果通常保存在后帧缓存(back frame buffer)在内的其他帧缓存,当渲染后的后帧缓存完成后,前后帧缓存会互换。(OS完成)

前帧缓存决定了屏幕上显示的像素颜色,会在适当的时候与后帧缓存切换。

Core Animation的合成器会联合OpenGL ES层和UIView层、StatusBar层等,在后帧缓存混合产生最终的颜色,并切换前后帧缓存; OpenGL ES坐标是以浮点数来存储,即使是其他数据类型的顶点数据也会被转化成浮点型。

分类:
iOS
标签:
收藏成功!
已添加到「」, 点击更改