3D模型渲染掉帧问题

2022-08-20 19:08
45

当CPU和GPU渲染图像的时间过长,在下一个垂直同步信号来的时候,GPU并没有处理完一帧的数据,帧缓冲区也就没有交换,视频控制器就会显示原来缓冲区的内容

三缓冲区

从上图可以看出,CPU和GPU是在垂直同步信号到来的时候才开始渲染的工作,为了减少掉帧的情况,引入了三缓冲区

A:显示到屏幕

B:提前渲染号

C:正在渲染

其实相当于预加载,充分利用CPU和GPU的空闲时间,提前渲染好一帧B(同时也会带来画面延迟,当然1帧的延迟是可以接受的),多留出了一帧的时间,即使在渲染C的时候出现了一次掉帧,依然能刘畅渲染,这种情况大大减小了掉帧的可能

但如果渲染C的时间过长(掉多帧),依然会带来掉帧的问题,三缓冲区本质上并不解决掉帧的问题,只是缓解

为了解决掉帧的问题,我们只能尽可能优化我们的代码,减少CPU和GPU的渲染时间

iOS的渲染框架

渲染框架

可以看到在iOS中的CoreGraphics, CoreAnimation, CoreImage都是通过OpenGL/Metal进行渲染的,我们的App也可以使用OpenGL/Metal来操作GPU进行渲染

CoreAnimation 渲染流⽔线

CoreAnimation会在Runloop注册一个Observer监听触摸事件,当点击事件到来的时候,Runloop会被唤醒处理相关的业务逻辑(UIView的创建,修改,添加动画等)

最终会在CALayer通过CATransaction提交到RenderServer中,RenderServer会对图片进行解码,并等待下一个VSync的到来

VSync信号到来后,RenderService会通过OpenGL/Metal做一些绘制操作,然后把处理完的数据(纹理,顶点,着色器等)提交给GPU

GPU通过下面渲染流程程(顶点数据->顶点着⾊器->⽚元着⾊器),渲染到帧缓冲区,然后交换帧缓冲区(双缓冲区)

下一个VSync信号到来的时候,视频控制器读取帧缓冲区的数据显示到屏幕上

如果此处有动画,CoreAnimation会通过DisplayLink等机制多次触发相关流程

渲染流程CPU阶段

布局(Frame): layoutSubviews, addSubview

显示(Core Graphics): drawRect, 绘制字符串

准备(QuartzCore/Core Animation):图片decode

提交:通过IPC提交(打包好的layers以及动画属性)给OpenGL/Metal,递归提交subview的layers

OpenGL ES/Metal阶段,主要是对图层进行取色,采样,生成纹理,绑定数据,生成前后帧缓存,为GPU渲染做准备

生成(Generate)

绑定(Bind)

缓存数据(Buffer Data)

启用(Enable)

设置指针(Set Pointers)

绘图(Draw)

清除(Delete)

GPU阶段

接收提交的纹理(Texture)和顶点描述(三角形)

应用变换(transform)

合并渲染(离屏渲染等)


昵称:
内容:
验证码:
提交评论
评论一下
联系我们
contact us
深圳总部
郭经理
手机:18665867986
座机:0755-32914332-800
邮箱:aaranguo@viewspread.com
地址:深圳市龙岗区布吉街道中兴路19号
重庆办事处
黄经理
手机:17830270255
座机:0755-32914332-801 / 023-88158245
邮箱:huangtao@viewspread.com
地址:重庆市渝北区长凯路9号
郑州办事处
周经理
手机:17610560506
座机:0755-32914332-803
邮箱:zhouxuetong@viewspread.com
地址:河南省郑州市金水区曼哈顿广场10号
联系我们
邮政编码:518116
服务热线:400-800-5338
公司邮箱:postmaster@viewspread.com
总部地址:深圳市龙岗区布吉街道中兴路19号布吉侨联大厦3层 303