-
CPU与GPU
-
CPU
中央处理器(CPU),是电子计算机的主要设备之一,电脑中的核心配件。其功能主要是解释计算机指令以及处理计算机软件中的数据。CPU是计算机中负责读取指令,对指令译码并执行指令的核心部件。中央处理器主要包括两个部分,即控制器、运算器,其中还包括高速缓冲存储器及实现它们之间联系的数据、控制的总线。电子计算机三大核心部件就是CPU、内部存储器、输入/输出设备。中央处理器的功效主要为处理指令、执行操作、控制时间、处理数据
-
GPU
图形处理器(英语:Graphics Processing Unit,缩写:GPU),又称显示核心、视觉处理器、显示芯片,是一种专门在个人电脑、工作站、游戏机和一些移动设备(如平板电脑、智能手机等)上做图像和图形相关运算工作的微处理器
-
图片渲染过程中分别作了什么工作
CPU:- 确认场景中哪些对象需要被渲染,一个object只要在符合特定的规则才会被渲染。例如,当处于相机的视锥体内的对象可以被渲染,而超出(不在视锥体内)的部分则被剔除(Culled),不进行渲染
- CPU会收集这些将要被渲染的每一个对象的数据,并且整合成指令,即我们常说的Draw Calls。一个Draw Call包含一个单独的网格(mesh)数据和它将如何进行渲染的信息。比如,需要对材质使用哪些贴图等。在某些情况下,使用相同的设置的object数据会被合并进一个Draw Call。将不同的object数据合并到一个Draw Call的行为我们称之为 合批(Batching)。
- CPU会为每一个Draw Call创建一个数据包叫做 batch,然而,batch中包含的数据不仅仅是draw call,还有一些数据由于与我们探讨的渲染性能问题无关,因此就不在这里展开。一旦完成了batch工作,CPU接着会进行如下工作:
- 发送一条指令给到GPU变更渲染状态(Render State)。这个指令我们称为 SetPass Call。SetPass Call的作用是告诉GPU在渲染下一个材质的时候该使用哪一种设置。SetPass Call仅当从前一个材质到下一个材质确实需要变更渲染状态的情况下CPU才会发出
- CPU发送一条Draw Call指令给到GPU。Draw Call指示GPU按照SetPass Call定义的设置来对具体的材质进行渲染。
- 某种情况下,你的batch可能包含不止一个渲染通道(pass),这取决于你的 shader 代码中pass的代码块,一个pass代码块就需要GPU变更一次渲染状态。所以,一个batch中每多包含一个pass,CPU就要新发送一次SetPass Call到GPU,然后再把Draw Call发送一次到GPU。
与此同时, GPU 会进行如下工作:
- GPU按照CPU的要求完成渲染任务。
- 如果当前任务是一个SetPass Call,那么GPU会变更当前的渲染状态(Render State)。
- 如果当前任务是一个Draw Call, GPU就渲染指定的材质。通过顶点着色器、片元着色器进行渲染
总结一下
CPU就是计算出需要渲染的模型数据,然后发送指令调用GPU去渲染。 首先读取绘制模型,CPU将读取到的多边形转交给GPU,GPU根据模型数据绘制出对应的模型骨架,注意这一步没有纹理只有线框。GPU将模型数据放进显存,GPU同时也为模型贴材质,给模型上颜色。CPU相应从显存中获取多边形的信息。然后CPU计算光照后产生的影子的轮廓。等CPU计算出后,显卡的工作又有了,那就是为影子中填充深的颜色。无论多牛的显卡,光影都是CPU计算的,GPU只有2个工作,1多边形生成。2为多边形上颜色。
-
-
计算机渲染原理
- 扫描方式
- 随机扫描
比较老的扫描方式了,采用随机定位的方式控制电子束的运行(缺点不能显示太复杂的图像)
- 光栅扫描
冲上到下依次扫描
- 随机扫描
- 光栅扫描显示系统结构
- 最简单的光栅图形系统结构

- 常用的光栅图形系统结构

- 高级光栅图形系统结构

- 最简单的光栅图形系统结构
- 扫描方式
-
屏幕撕裂与卡顿情况
- 屏幕撕裂
图片渲染流程:
GPU进⾏渲染->帧缓存区⾥ ->视频控制器->读取帧缓存区信息(位图) -> 数模转化(数字信号处->模 拟型号) ->(逐⾏扫描)显示
冲上面的流程可以看出基本上分成两个阶段:- GPU将处理后的数据(位图)存放到帧缓冲区中
- 视频控制器冲帧缓冲区中拿到数据进行转化扫描显示
所以如果第一步过快第二步太慢就会造成撕裂现象。
总结一下:首先GPU将数据处理完成后存到帧缓冲区,完美的处理结果是视频控制器刚好显示完帧缓冲区中的数据的时候立马下一帧的数据更新到了帧缓冲区中,但是呢视频控制器处理速度有点慢,但是GPU处理又很快就会出现第一帧还没有渲染完成的时候第三帧的数据已经处理完成此时第三帧的数据就会将帧缓冲区中第二帧的数据替换掉这就造成了第二帧丢失第一帧完成后直接冲第三帧开始渲染,这就造成了撕裂现象
- 卡顿情况
针对撕裂的情况,苹果垂直同步Vsync + 双缓存区 DoubleBuffering,垂直同步意思就是给帧缓冲区上把锁,放到帧缓冲区中将该缓冲区上锁,等视频控制器拿到帧缓冲区中的数据,并扫描显示完成的时候在解锁,这样就解决了撕裂问题,但是问题又来了,一般呢渲染一帧的时间是16ms,超过16ms则会渲染下一帧,但是呢CPU/GPU处理数据的速度要大于16ms,这就造成在渲染下一帧的时候帧缓冲区中没有数据,此时就还会显示当前一帧(其实不加垂直信号也有可能出现掉帧的情况,但是情况要比加垂直同步的好得多,应为gpu处理完数据不会等待直接覆盖帧缓冲区中的内容,这样就保证了渲染过程中CPU/GPU一直在工作,二添加垂直同步之后就有可能会出现CPU/GPU等待的情况,所以就加大了掉帧的几率),为了更好的解决这个问题又引入了三缓冲区,其实就是更大化的利用GPU/CPU而已并不能冲根本上解决问题。
总结一下:掉帧不是一帧没了而是存在等待情况,其实就是CPU/GPU处理数据的速度跟不上渲染的速度,目前为止还没有能够完全解决掉帧的问题
- 屏幕撕裂
-
iOS下的渲染流程
- 显示逻辑:
- CoreAnimation提交会话,包括自己和子树(view hierarchy)的layout状态等;
- RenderServer解析提交的子树状态,生成绘制指令
- GPU执行绘制指令
- 显示渲染后的数据
- 提交多级
- 布局(Layout)
- 调用layoutSubviews方法
- 调用addSubview:方法
- 显示(Display)
- 通过drawRect绘制视图;
- 绘制string(字符串);
- 准备提交
- 解码图片;
- 图片格式转换;
- 提交
- 打包layers并发送到渲染server;
- 递归提交子树的layers;
- 如果子树太复杂,会消耗很大,对性能造成影响;
- 布局(Layout)
总结一下:
HandleEvents : 事件处理
Commit Transaction: 图⽚
Render Server :解码(CPU) -> CoreAnimation -> 提交OpenGL -> GPU ->渲染流程(顶点数据->顶点着⾊器->⽚元着⾊器-> runloop ->显示)
- 显示逻辑: