本篇是记录笔者探索离屏渲染的笔记,学习离屏渲染如何引起、如何解决。同时,好好理解一下什么离屏渲染(Offscreen-rendered),什么是当屏渲染(Onscreen-Rendered)。了解GPU与CPU的一些小知识。
本篇主要一起来学习学习:
在OpenGL中,GPU屏幕渲染有以下两种方式:
与当前屏幕渲染相比,离屏渲染的代价是很高的,主要体现在两个方面:
有以下方式可以引起离屏渲染:
在Instruments->Core Animation下,如下图,勾选上:
注意:要求在真机才可以的哦!
shouldRasterize = YES时,在其他属性触发离屏渲染的同时,会将光栅化后的内容缓存起来,以便在下一帧的时候可以直接复用。这会隐式地创建一个位图,各种阴影遮罩等效果也会保存到位图中并缓存起来,从而减少渲染的次数,提高一定的性能。
当我们设置了shaouldRasterize = YES后,我们就可以开启 “Color Hits Green and Misses Red” 来检查该场景下光栅化操作是否是一个好的选择。命中缓存则显示绿色,不命中缓存,则会显示为红色。
因此,我们要通过检测是否值得使用光栅化。比如,如果在设置为YES后,在快速滚动的时候,绿色较少,而红色较多,说明并不可观,表示不建议使用光栅化。相反,如果在快速滚动的时候,基本都是绿色的,只有极少数偶尔出现红色,那么使用光栅化来优化是可以达到很好的效果的。
我们启动Instruments->Core Animation勾选如下选项:
下面是笔者测试的效果图:
从GIF图中可以看出来,命中率并不高,因此不适合使用光栅化来优化。
设置光栅化只需要一行代码:
// 光栅化 imgView.layer.shouldRasterize = YES;
设置上面的代码后,引起了离屏渲染:
我们要根据实际检测的结果来决定是否应该使用光栅化。
通过以下设置会引起离屏渲染:
imgView.layer.cornerRadius = 10; imgView.layer.masksToBounds = YES;
或者这么设置:
// self.headImageView.layer.cornerRadius = 30; // self.headImageView.clipsToBounds = YES;
直接设置cornerRadius属性是不会引起离屏渲染的,而且连圆角也不会有,因为只有后面的设置为YES,才会真正地渲染。
圆角引起的离屏渲染效果如下:
我们测试一下设置阴影(随意设置的):
imgView.layer.shadowColor = [UIColor redColor].CGColor; imgView.layer.shadowOffset = CGSizeMake(10, 10); imgView.layer.shadowOpacity = 0.8;
检测到离屏渲染如下图:
笔者测试了一下,直接设置这几个,并没有检测出离屏渲染,请会的人给补上小例子。笔者的测试小侄子是这么写的:
if (type == 2) { // 测试发现未引起离屏渲染 imgView.layer.edgeAntialiasingMask = kCALayerTopEdge; imgView.layer.allowsEdgeAntialiasing = NO; } else if (type == 3) { // 透明,发现未引起离屏渲染 imgView.opaque = NO; imgView.layer.allowsGroupOpacity = YES; }
我想肯定是笔者理解错了,不了解这几个如何去使用~后续再补上吧!
摆在我们面前有三种选择:
我们应该选择使用哪种方式呢?这需要根据具体的使用场景来决定。但是,我们 尽量使用当前屏幕渲染 ,因为离屏渲染、CPU渲染可能会带来性能问题。所以,一般情况下我们要尽量使用当前屏幕渲染。
由于GPU的浮点运算能力比CPU强,CPU渲染的效率可能不如离屏渲染;但如果仅仅是实现一个简单的效果,直接使用CPU渲染的效率又可能比离屏渲染好,因为离屏渲染要涉及到缓冲区创建和上下文切换等耗时操作。
所以,具体的选择应该要我们通过性能测试所得的结果来决定到底采用哪一种方式优化的效果会更佳。
这里笔者去掉光栅化、去掉阴影、圆角采用生成圆角图片的方式异步加载,最终的效果如下:
已经没有黄色部分了,说明我们优化得差不多了!
本篇对应的源代码小Demo下载地址为: CoderJackyHuang:PerformaceDemo
关注 | 账号 | 备注 |
---|---|---|
标哥博客iOS交流群一 | 324400294(满) | 群一若已满,请申请群二 |
标哥博客iOS交流群二 | 494669518(满) | 群二若已满,请申请群三 |
标哥博客iOS交流群三 | 461252383(满) | 群三若已满,请申请群四 |
标哥博客iOS交流群四 | 250351140 | 群四若已满,会有提示信息 |
关注微信公众号 | iOSDevShares | 关注微信公众号,会定期地推送好文章 |
关注新浪微博账号 | 标哥的技术博客 | 关注微博,每次发布文章都会分享到新浪微博 |
关注标哥的GitHub | CoderJackyHuang | 这里有很多的Demo和开源组件 |
关于我 | 进一步了解标哥 | 如果觉得文章对您很有帮助,可捐助我! |