计算机的基础:CPU & GPU

16 篇文章 0 订阅
2 篇文章 0 订阅

一、在屏幕成像的过程中,CPU和GPU起着至关重要的作用
1、CPU(Central Processing Unit,中英处理器)
对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片格式的转换和解码、图像的绘制(Core Graphics)
2、GPU(GraphicsProcessing Unit,图像处理器)
纹理的渲染

二、屏幕成像原理
1、通常来说,计算机系统的CPU、GPU、显示器是以一种类似于串行的方式协调工作的。CPU计算好显示的内容交给GPU
2、GPU把CPU提交过来的内容渲染成显示器可以显示的格式(也就是我们常说的 一帧)。
3、GPU渲染完成之后将渲染结果(也就是一帧画面)放到屏幕的帧缓冲区(此处的帧缓冲区和离屏渲染的屏幕缓冲区、屏幕外缓冲区是一回事)
4、随后视频控制器会按照Vsync(垂直同步信号)读取帧缓冲区的数据,经过数模转换传递给显示器显示。
三、页面卡顿的原因
掉帧,也就说说CPU处理数据和GPU渲染时间过长导致掉帧,界面展示也就是卡顿
四、解决卡顿的思路
尽可能的减少CPU、GPU资源消耗
五、优化方案
a、卡顿优化 —— CPU
1、尽量使用轻量级的对象,比如用不到事件处理的地方,可以考虑使用CALayer取代UIview(使用ASDK框架布局)
2、不要频繁调用UIView的相关属性,比如frame、bounds、transform等属性、尽量减少不必要的修改
3、尽量提前计算好布局,在有需要时一次性调整对应的属性,不要多脆修改属性
4、Autolayout会比直接设置frame消耗更多的CPU资源
5、图片的size最好刚好跟UIImageView的size保持一致
6、控制胰腺癌线程的最大并发数量
7、尽量把耗时操作哦放到子线程
(文本处理(尺寸计算、绘制))
(图片处理(解码、绘制))
b、卡顿优化 —— GPU
1、尽量避免短时间内大量图片的显示,尽可能将多张图片合成一张进行显示
2、GPU能处理的最大纹理尺寸是4096x4096,一旦超过这个尺寸,就会占用CPU资源进行处理,所以纹理尽量不要超过这个尺寸
3、尽量减少视图数量和层次
4、减少透明的视图(alpha<1),不透明的就设置opaque为YES
5、尽量避免出现离屏渲染
六、什么是离屏渲染?
在OpenGL中,GPU有2种渲染方式 On-Screen Rendering:当前屏幕渲染,在当前用于显示的屏幕缓冲区进行渲染操作 Off-Screen Rendering:离屏渲染,在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作
1、离屏渲染消耗性能的原因: GPU 产生的离屏渲染主要是当 CALayer 使用圆角,阴影,遮罩等属性的的时候,图层属性的混合体被指定为 在未预合成之前 不能直接在屏幕中渲染,则过程中需要进行离屏渲染。
2、需要创建新的缓冲区
离屏渲染的整个过程,需要多次切换上下文环境,先是从当前屏幕(On-Screen)切换到离屏(Off-Screen);等到离屏渲染结束以后,将离屏缓冲区的渲染结果显示到屏幕上,又需要将上下文环境从离屏切换到当前屏幕
3、哪些操作会触发离屏渲染?
光栅化,layer.shouldRasterize = YES 遮罩,layer.mask 圆角,同时设置layer.masksToBounds = YES、layer.cornerRadius大于0 考虑通过CoreGraphics绘制裁剪圆角,或者叫美工提供圆角图片 阴影,layer.shadowXXX 如果设置了layer.shadowPath就不会产生离屏渲染

GPU离屏渲染

在上面的渲染流水线示意图中我们可以看到,主要的渲染操作都是由COREANIMATION的RENDER

SERVER模块,通过调用显卡驱动所提供的OPENGL/METAL接口来执行的.通常对于每一层LAYER.

RENDER SERVER会遵循"画家算法",按次序输出到FRAME BUFFER,后一层,就能得到最终

的显示结果(值得一提的是,与一般桌面架构不同,在IOS中,设备主存和GPU的显存共享物理内

存,这样可以省去一些数据传输开销).

"画家算法",把每一层依次输出到画布

然而有些场最并没有那么简单.作为"画家"的GPU虽然可以一层往画布上进行输出,但是无法

在某一层渲染完成之后,再回过头来擦除改变其中的某个部分一因为在这一层之前的若干层

LAYER像素数据,已经在渲染中被永久覆盖了.这就意味着,对于每一层LAYER,要么能找到一种通

过单次遍历就能完成渲染的算法,要么就不得不另开一块内存,借助这个临时中转区域来完成一些

更复杂的,多次的修改/剪裁操作.

如果要绘制一个带有圆角并剪切圆角以外内容的容器,就会触发离屏渲染.我的猜想是(如果读者

中有图形学专家希望能指正)

将一个LAYER的内容裁剪成圆角,可能不存在一次遍历就能完成的方法

.容器的子LAYER因为父容器有圆角,那么也会需要被裁剪,而这时它们还在渲染队列中排队,尚未

被组合到一块画布上,自然也无法统一裁剪

此时我们就不得不开辟一块独立于FRAMEBUFFER的空白内存,先把容器以及其所有子LAYER依次画

好,然后把四个角"剪"成圆形,再把结果画到FRAMEBUFFER中.这就是GPU的离屏渲染.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值