美文网首页
离屏渲染 问题及原理

离屏渲染 问题及原理

作者: 爱你因为泰勒 | 来源:发表于2020-07-07 10:26 被阅读0次
    正常渲染流程

    首先假设我们app每秒显示60帧,数据会存在于帧缓冲区Frame Buffer当中,然后屏幕不断从帧缓冲区中取数据去显示。


    离屏渲染流程

    与正常流程不同的是,当触发离屏渲染时,数据不会先放到帧缓冲区,而是会先放到离屏缓冲区offscreen Buffer(这个缓冲区是帧缓冲区之外额外开辟的缓冲区)。等到几个结果叠加之后,然后会到帧缓冲区去显示出来。

    离屏渲染触发原理

    app进行额外的渲染和合并->offscreen Buffer组合->FrameBuffer->屏幕;

    离屏渲染会造成性能问题:
    1. 会造成额外的存储空间,可能会造成压力比较大
    2. 从离屏缓冲区(offscreen Buffer)到帧缓冲区(Frame Buffer)是需要一段时间的,其实离屏缓冲区的空间大小也是有限制的,为屏幕像素的2.5倍。
    3. 如果出现很多的离屏渲染情况,很容易出现掉帧情况
      反正尽可能能不要离屏渲染就不离屏渲染。
    离屏渲染的原因

    既然离屏渲染这么容易造成性能问题,为啥还要用它呢?

    • 特殊的效果(高斯模糊、抗锯齿、毛玻璃等等)使得我需要使用额外的offscreen Buffer来保存中间状态,不得不使用离屏渲染(系统自动触发离屏渲染,圆角、阴影也是)
    • 还有一个效率优势:既然效果会多次出现在屏幕上,我们为什么不能提前渲染好,保存在offscreen Buffer里面,然后可以达到复用目的,避免再重复的进行GPU、CPU的计算
    光栅化(shoulRasterize)

    也是出现离屏渲染的一种原因,不过光栅化是选择主动触发的

    光栅化使用建议:

    1. 如果layer不能被复用,则没有打开光栅化的必要。
    2. 如果layer不是静态的,需要被频繁修改,比如处于动画之中,那么开启离屏渲染反而影响效率。
    3. 离屏渲染缓存内容有时间限制,缓存内容 100ms 内没有被使用,那么它就会被丢弃,无法再进行复用了。
    4. 离屏渲染缓存空间有限,超过2.5倍屏幕像素大小的话,也会失效的,且无法进行复用。

    圆角触发的离屏渲染 (offscreen Rendering)

    圆角属性

    正常渲染逻辑

    正常渲染逻辑
    对于单一一个渲染(如只有一张内容图片),当sublayer绘制到屏幕后,就会将sublayer从帧缓冲区移除,以节省空间。

    离屏渲染逻辑(圆角)

    离屏渲染逻辑(圆角)

    对于多个组合在一起的(如有内容图片、有背景、有圆角、阴影等),如果想要圆角效果,需要背景圆角、边框圆角、图片内容圆角,然后组合在一起就是整体圆角效果了。这个时候系统就会自动触发离屏渲染,把所有的组合在离屏缓冲区组合在一起再一起显示再屏幕上。view.layer.masksToBounds == true 是触发离屏渲染的原因(必须要在多个图层的基础上触发)


    常见的离屏渲染的几种情况:

    • 使用了mask的layer(layer.mask)
    • 需要进行裁剪的layer(layer.masksToBounds / view.clipsToBounds)
    • 设置了透明度为YES,并且透明度不为1 的layer(layer.allowsGroupOpacity/layer.Opacity)
    • 添加了投影的layer(layer.shadow)
    • 采用了光栅化的layer(layer.shouldRasterize)
    • 绘制了文字的layer(UILabel, CATextLayer, coreText等)

    相关文章

      网友评论

          本文标题:离屏渲染 问题及原理

          本文链接:https://www.haomeiwen.com/subject/uoxaqktx.html