OpenGL/ES、Metal

N0.5 - 图像撕裂 、掉帧、 iOS中的渲染流程

2020-07-06  本文已影响0人  z夜流星

1、撕裂

图像撕裂

撕裂原因:
其本质是拿到图像后,GPU进⾏渲染->帧缓存区⾥ ->视频控制器->读取帧缓存区信息(位图) -> 数模转化(数字信号处->模 拟型号) ->(逐⾏扫描)显示,当第一帧图像扫描到某个位置时,GPU拿到新的数据并存到帧缓冲区,这个时候视频控制器从帧缓冲区扫描的是新拿到的一帧的图像,最后就形成了在我们肉眼看到的断层现象,即我们看到的一张图片其本质是两张图片组合而来,究其原因就是视频控制器显示速度小于了GPU处理图形的速度。

解决方案:
为了解决撕裂,苹果引入了: 垂直同步Vsync + 双缓存区 DoubleBuffering

(1)垂直同步Vsync:帧缓存区加锁 防⽌出现撕裂情况

(2)双缓存区 DoubleBuffering :就是GPU开辟AB两个帧缓冲区

执行流程就是当A帧缓冲区拿到第一帧数据,给A缓冲区加上一把锁,屏幕控制器从A拿到数据并逐行扫描完成,A帧缓冲区解锁,并且屏幕控制器指向B帧缓冲区,B帧缓冲区加锁并逐行扫描显示,在屏幕控制器扫描B帧缓冲区的时候,A帧缓冲区拿到GPU传过来的新一帧数据,以此类推,解决撕裂问题。

2、掉帧

为了解决撕裂问题而引入二级缓冲区机制后,出现了一个新的问题-(掉帧)


image

每帧画面的处理时间大概在16.7ms(1s/60 ≈16.7ms),当超过这个时间就会出现掉帧,如上图:当接收接收Vsync ,由于cpu/gpu图⽚数据(速度大于了16.7ms) -> 拿不到FrameBuffer ->这个时候屏幕控制器只能显示同一帧的数据,即: 掉帧(重复渲染同⼀帧数据)

为了减少掉帧(注意不是解决,掉帧问题只能尽量的减少,而不是解决,三级缓冲区也有可能出现掉帧),引入三级缓存区,三级缓冲区是为了充分利用CPU/GPU的空余时间,开辟ABC三个帧缓冲区,A显示屏幕, B也渲染好,C再从GPU拿取渲染数据,当屏幕缓冲区和帧缓冲区都弄好了,然后视频控制器再指向帧缓冲区的另外一个,再显示,这样交替,达到减少掉帧的情况,这样做就比二级缓冲区多了一个确认的操作

3、屏幕卡顿的原因

4、iOS中的渲染流程

iOS中渲染的整体流程如下


iOS中渲染的整体流程

View 与 CALayer 的关系

首先分别简单了解下UIView和CALayer

UIView
CALayer
总结:

UIView基于UIKit框架,可以处理用户触摸事件,并管理子视图
CALayer基于CoreAnimation,而CoreAnimation是基于QuartzCode的。所以CALayer只负责显示,不能处理用户的触摸事件
从父类来说,CALayer继承的是NSObject,而UIView是直接继承自UIResponder的,所以UIVIew相比CALayer而言,只是多了事件处理功能,
从底层来说,UIView属于UIKit的组件,而UIKit的组件到最后都会被分解成layer,存储到图层树中
在应用层面来说,需要与用户交互时,使用UIView,不需要交互时,使用两者都可以

UIView 和 CALayer的渲染

CoreAnimation

在苹果官方的描述中,Render、Compose,and animate visual elements,CoreAnimationg中的动画只是一部分,它其实是一个复合引擎,主要的职责包括 渲染、构建和动画实现。
iOS 下CoreAnimation


image
CoreAnimation中的渲染流水线
CoreAnimation中渲染的流程
CoreAnimation部分
Render Server 操作分析
Render Server 操作分析
GPU部分
上一篇 下一篇

猜你喜欢

热点阅读