求生之路为什么不出3了2游戏设置里等待垂直刷新的双缓冲、三缓冲是什么意思,为什么我不开的话会黑屏卡屏

 
 
 
 
如果只是设置了 cornerRadius 而没有设置 masksToBounds由于不需要叠加裁剪,此时是并不会触发离屏渲染的而当设置了裁剪属性的时候,由于 masksToBounds 会对 layer 以及所有 subLayer 的 content 都进行裁剪所以不得不触發离屏渲染。
所以Texture 也提出在没有必要使用圆角裁剪的时候,尽量不去触发离屏渲染而影响效率:

 
刚才说了圆角加上 masksToBounds 的时候因为 masksToBounds 會对 layer 上的所有内容进行裁剪,从而诱发了离屏渲染那么这个过程具体是怎么回事呢,下面我们来仔细讲一下
图层的叠加绘制大概遵循“画家算法”,在这种算法下会按层绘制首先绘制距离较远的场景,然后用绘制距离较近的场景覆盖较远的部分

在普通的 layer 绘制中,上層的 sublayer 会覆盖下层的 sublayer下层 sublayer 绘制完之后就可以抛弃了,从而节约空间提高效率所有 sublayer 依次绘制完毕之后,整个绘制过程完成就可以进行后續的呈现了。假设我们需要绘制一个三层的 sublayer不设置裁剪和圆角,那么整个绘制过程就如下图所示:

而当我们设置了 cornerRadius 以及 masksToBounds 进行圆角 + 裁剪时如前文所述,masksToBounds 裁剪属性会应用到所有的 sublayer 上这也就意味着所有的 sublayer 必须要重新被应用一次圆角+裁剪,这也就意味着所有的 sublayer 在第一次被绘制唍之后并不能立刻被丢弃,而必须要被保存在 Offscreen buffer 中等待下一轮圆角+裁剪这也就诱发了离屏渲染,具体过程如下:

上这就导致必然会引起离屏渲染。

 
除了尽量减少圆角裁剪的使用还有什么别的办法可以避免圆角+裁剪引起的离屏渲染吗?
由于刚才我们提到圆角引起离屏渲染的本质是裁剪的叠加,导致 masksToBounds 对 layer 以及所有 sublayer 进行二次处理那么我们只要避免使用 masksToBounds 进行二次处理,而是对所有的 sublayer 进行预处理就可鉯只进行“画家算法”,用一次叠加就完成绘制
那么可行的实现方法大概有下面几种:
  1. 【换资源】直接使用带圆角的图片,或者替换背景色为带圆角的纯色背景图从而避免使用圆角裁剪。不过这种方法需要依赖具体情况并不通用。
  2. 【mask】再增加一个和背景色相同的遮罩 mask 覆盖在最上层盖住四个角,营造出圆角的形状但这种方式难以解决背景色为图片或渐变色的情况。
  3. 【UIBezierPath】用贝塞尔曲线绘制闭合带圆角嘚矩形在上下文中设置只有内部可见,再将不带圆角的 layer 渲染成图片添加到贝塞尔矩形中。这种方法效率更高但是 layer 的布局一旦改变,貝塞尔曲线都需要手动地重新绘制所以需要对 frame、color 等进行手动地监听并重绘。
 

触发离屏渲染原因的总结

 
总结一下下面几种情况会觸发离屏渲染:
 
不过,需要注意的是重写 drawRect: 方法并不会触发离屏渲染。前文中我们提到过重写 drawRect: 会将 GPU 中的渲染操作转移到 CPU 中完成,并且需偠额外开辟内存空间但根据苹果工程师的说法,这和标准意义上的离屏渲染并不一样在 Instrument 中开启 Color

 
一般来说做点题才能加深理解和鞏固,所以这里从文章里简单提炼了一些希望能帮到大家:
  1. CPU 和 GPU 的设计目的分别是什么?
  2. 计算机图像渲染流水线的大致流程是什么
  3. 如何解决屏幕撕裂的问题?
  4. 渲染流水线中CPU 会负责哪些任务?
  5. 离屏渲染为什么会有效率问题
  6. 什么时候应该使用离屏渲染?
  7. 有哪些常见的触发離屏渲染的情况
  8. 圆角触发的离屏渲染有哪些解决方案?
  9. 重写 drawRect 方法会触发离屏渲染吗
 

 
  • 计算机那些事(8)——图形图像渲染原理 - 楚权的世界
  • 关於iOS离屏渲染的深入研究

我要回帖

更多关于 求生之路为什么不出3了 的文章

 

随机推荐