iOS底层探究

02总结--004--OpenGL 渲染流程汇总

2020-07-02  本文已影响0人  修_远

[TOC]

TOC

前言

整个渲染流程比较多,这篇文章中只记录流程中的步骤,对于每个步骤中的细节不做过多说明,如果想要了解,可以参考笔者的其他文章。

一、整体流程

1.1 计算机图形渲染简单流程

计算机图形渲染简单流程
  1. Application 应用处理阶段:得到图元
  2. Geometry 几何处理阶段:处理图元,得到新图元
  3. Rasterization 光栅化阶段:图元转换为片元(像素)
  4. Pixel 像素处理阶段:处理片元(像素),得到位图

1.2 计算机层次流程图

image
  1. APP:图层树,UIView/CALayer
  2. Core Graphics:Core Graphics 是一个强大的二维图像绘制引擎,是 iOS 的核心图形库,常用的比如 CGRect 就定义在这个框架下
  3. Core Animation:在 iOS 上,几乎所有的东西都是通过 Core Animation 绘制出来,它的自由度更高,使用范围也更广
  4. Core Image:Core Image 是一个高性能的图像处理分析的框架,它拥有一系列现成的图像滤镜,能对已存在的图像进行高效的处理
  5. Metal:Metal 类似于 OpenGL ES,也是一套第三方标准,具体实现由苹果实现。Core Animation、Core Image、SceneKit、SpriteKit 等等渲染框架都是构建于 Metal 之上的。

二、CPU 阶段:Core Animation

2.1 Core Animation 层级图

Core Animation 层级图

2.2 CALayer 的层级图

CALayer 的层级
  1. backgroundColor
  2. contents
  3. borderWidth / borderColor

【总结】

  1. 设置 layer.cornerRadius 只会设置 backgroundColor 和 border 的圆角,不会设置 contents
  2. 同时设置 layer.masksToBounds 才会设置 contents 的圆角。(对应view中的clipsToBounds属性)

2.3 UIView 和 CALayer 之间的关系

image

【核心关系】

  1. CALayer 是 UIView 的属性之一,负责渲染和动画,提供可视内容的呈现。
  2. UIView 提供了对 CALayer 部分功能的封装,同时也另外负责了交互事件的处理。

【区别】

2.4 Core Animation Pipeline 渲染流水线

image
  1. Handle Events:这个过程中会先处理点击事件,这个过程中有可能会需要改变页面的布局和界面层次。
  2. Commit Transaction:此时 app 会通过 CPU 处理显示内容的前置计算,比如布局计算、图片解码等任务,接下来会进行详细的讲解。之后将计算好的图层进行打包发给 Render Server
  3. Decode:打包好的图层被传输到 Render Server 之后,首先会进行解码。注意完成解码之后需要等待下一个 RunLoop 才会执行下一步 Draw Calls。
  4. Draw Calls:解码完成后,Core Animation 会调用下层渲染框架(比如 OpenGL 或者 Metal)的方法进行绘制,进而调用到 GPU。
  5. Render:这一阶段主要由 GPU 进行渲染。
  6. Display:显示阶段,需要等 render 结束的下一个 RunLoop 触发显示。

2.5 Core Animation 之 Commit Transaction 流程

image
  1. Layout:构建视图
  2. Display:绘制视图
  3. Prepare:Core Animation 额外工作,图片解码和转换
  4. Commit:图层打包发送到 Render Server

三、OpenGL 渲染阶段

3.1 OpenGL 渲染流程:蓝宝书

1. OpenGL 渲染流程图

OpenGL 渲染流程图

2. 单个流程解释

3. 流程总结

  1. 四个阶段

红宝书上给出的流程是三排,也就是将顶点数据准备阶段和顶点着色器阶段放在一起了,这里为了方便记忆,我将每一个职责单独分开,成了四个阶段。

  1. 可编程阶段
  1. OpenGL 自动处理阶段

3.1 OpenGL 渲染架构:蓝宝书【补】

OpenGL 渲染架构 OpenGL 渲染架构名词解释

3.2 OpenGL 渲染原理:Render Server

Render Server
  1. GPU 收到 Command Buffer,包含图元 primitives 信息
  2. Tiler 开始工作:先通过顶点着色器 Vertex Shader 对顶点进行处理,更新图元信息
  3. 平铺过程:平铺生成 tile bucket 的几何图形,这一步会将图元信息转化为像素,之后将结果写入 Parameter Buffer 中
  4. Tiler 更新完所有的图元信息,或者 Parameter Buffer 已满,则会开始下一步
  5. Renderer 工作:将像素信息进行处理得到 bitmap,之后存入 Render Buffer
  6. Render Buffer 中存储有渲染好的 bitmap,供之后的 Display 操作使用

3.3 OpenGL 渲染原理:画家算法

画家算法

3.4 OpenGL 渲染过程:正常和离屏的简易流程

简易渲染流程

3.5 OpenGL 渲染过程:Layer的绘制【正常和离屏】

正常流程
  1. 绘制 sublayer1,绘制完了丢弃
  2. 绘制 sublayer2,绘制完了丢弃
  3. 绘制 sublayer3,绘制完了丢弃
离屏流程
  1. 绘制 sublayer1,存入离屏缓存区
  2. 绘制 sublayer2,存入离屏缓存区
  3. 绘制 sublayer3,存入离屏缓存区
  4. 从离屏缓存区取出 sublayer1
  5. 从离屏缓存区取出 sublayer2
  6. 从离屏缓存区取出 sublayer3
  7. 混合 -> 呈现

3.6 OpenGL 渲染案例:Mask渲染流程【离屏】

Mask渲染流程
  1. 渲染mask,存入离屏缓存区;
  2. 渲染layer,存入离屏缓存区;
  3. 读取离屏缓存区的数据,然后进行混合操作,将结果存入帧缓存区;
  4. 等待下一次 runloop到来,显示到屏幕上;

3.7 OpenGL 渲染案例:UIBlurEffectView渲染流程【离屏】

UIBlurEffectView渲染流程
  1. Content:渲染内容
  2. capture content:捕获内容
  3. Horizontal Blur:水平模糊
  4. Vertical Blur:垂直模糊
  5. Compositing Pass:合并过程
  6. 合并完成之后将结果存入帧缓存区,等待下一次 runloop到来,显示到屏幕上

四、显示阶段:帧缓存区到显示、帧缓存区的切换

4.1 位图显示到屏幕流程

位图显示到屏幕流程
  1. 视频控制器(Video Controller)会读取帧缓冲器中的信息
  2. 经过数模转换传递给显示器(Monitor)
光束扫描
  1. 电子束会从屏幕的左上角开始逐行扫描,屏幕上的每个点的图像信息都从帧缓冲器中读取的位图

4.2 撕裂流程(需要画图)

撕裂流程
  1. 新的位图还没有渲染好;
  2. 电子束从头开始新的一帧的扫描;
  3. 电子束扫描到一半的时候,新的位图渲染好了;
  4. 电子束扫描另一半内容,这一半内容显示的是新的位图,所以造成撕裂现象

4.3 垂直同步 Vsync + 双缓冲机制 Double Buffering

垂直同步信号(vertical synchronisation,Vsync)相当于给帧缓存区加锁:当电子束完成一帧的扫描,将要从头开始扫描时,就会发出一个垂直同步信号,只有当视频控制器接收到 Vsync 之后,才会将帧缓存区中的位图更新为下一帧。

双缓冲机制
  1. 视频控制器读取 primary surface 缓存区里的内容进行显示;
  2. 渲染服务(render server)将内容渲染存入 back Buffer 后台缓存区里;
  3. 等下一次呈现指令到来时,交换缓存区
    1. 视频控制器读取 back Buffer 的内容
    2. 渲染服务将内容存入 primary surface

4.4 掉帧流程

掉帧流程

【说明】

【过程】

  1. 第一帧显示 A
  2. 第二帧显示 A(第一个 Vsync 到来,但是 B 还没有渲染完成,因为同步问题,所以这一次不会更新帧缓存区里的位图,也即当前帧缓存区里面的位图还是 A);
  3. 第三帧显示 B(CPU+GPU过程 A 没有处理完成)
  4. 第四帧显示 A(A已经处理完成了)

4.5 三缓冲 Triple Buffering

三缓冲

参考:iOS Rendering 渲染全解析(长文干货)

上一篇 下一篇

猜你喜欢

热点阅读