mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-24 20:00:37 +00:00
feat: APM
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# 离屏渲染
|
||||
|
||||
## 什么是离屏渲染
|
||||
如果要在显示屏上显示内容,我们至少需要一块与屏幕像素数据量一样大的 Frame Buffer(帧缓冲区),作为像素数据存储区域,然后由显示控制器把帧缓冲区的数据显示到屏幕上。如果因为面临一些限制,比如阴影、光栅、遮罩等,CPU 无法把渲染结果直接写写入 Frame Buffer,而是先暂时把中间的临时状态保存在额外的内存区域,之后再写入 Frame Buffer,那么这个过程被称为离屏渲染。
|
||||
如果要在显示屏上显示内容,我们至少需要一块与屏幕像素数据量一样大的 Frame Buffer(帧缓冲区),作为像素数据存储区域,然后由显示控制器把帧缓冲区的数据显示到屏幕上。如果因为面临一些限制,比如阴影、光栅、遮罩等,CPU 无法把渲染结果直接写入 Frame Buffer,而是先暂时把中间的临时状态保存在额外的内存区域,之后再写入 Frame Buffer,那么这个过程被称为离屏渲染。
|
||||
系统如果没有直接把渲染结果直接写入到 GPU FrameBuffer 中,则认为发生了一次离屏渲染。(离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作)
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ self.imageView.layer.cornerRadius = YES;
|
||||
```
|
||||
|
||||
## 离屏渲染的影响?
|
||||
离屏渲染,指的是 GPU 在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。由上面的一个结论视图和圆角的大小对帧率并没有什么影响,数量才是伤害的核心输出啊。可以知道离屏渲染耗时是发生在离屏这个动作上面,而不是渲染。为什么离屏这么耗时?原因主要有创建缓冲区和上下文切换。创建新的缓冲区代价都不算大,付出最大代价的是上下文切换。
|
||||
上下文切换,不管是在GPU渲染过程中,还是一直所熟悉的进程切换,上下文切换在哪里都是一个相当耗时的操作。首先我要保存当前屏幕渲染环境,然后切换到一个新的绘制环境,申请绘制资源,初始化环境,然后开始一个绘制,绘制完毕后销毁这个绘制环境,如需要切换到On-Screen Rendering 或者再开始一个新的离屏渲染重复之前的操作。
|
||||
离屏渲染,指的是 GPU 在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。由上面的一个结论视图和圆角的大小对帧率并没有什么影响,数量的多少才显著影响性能。可以知道离屏渲染耗时是发生在离屏这个动作上面,而不是渲染。为什么离屏这么耗时?原因主要有创建缓冲区和上下文切换。创建新的缓冲区代价都不算大,付出最大代价的是上下文切换。
|
||||
上下文切换,不管是在GPU渲染过程中,还是广为人知的进程切换,上下文切换都是一个相当耗时的操作。首先要保存当前屏幕渲染环境,然后切换到一个新的绘制环境,申请绘制资源,初始化环境,然后开始一个绘制,绘制完毕后销毁这个绘制环境,如需要切换到On-Screen Rendering 或者再开始一个新的离屏渲染重复之前的操作。
|
||||
|
||||
一次mask发生了两次离屏渲染和一次主屏渲染。即使忽略昂贵的上下文切换,一次mask需要渲染三次才能在屏幕上显示,这已经是普通视图显示3陪耗时,若再加上下文环境切换,一次mask就是普通渲染的n(n>3)倍以上耗时操作
|
||||
|
||||
@@ -81,7 +81,7 @@ self.imageView.layer.cornerRadius = YES;
|
||||
|
||||
GPU 利用片元将整个图片分为一个个像素,并且并行计算了每一个像素的颜色。在同一个栅格内可能存在多个视图,根据距离眼睛的远近,存在多个不同的物体。显而易见,我们应该将最近物体的颜色作为该栅栏的颜色,后面物体的颜色应该被遮挡(如果后面物体的颜色被传递给片元着色器,这时候就是一个显示错误,比如我们打游戏的时候可以看到墙后的人)
|
||||
|
||||
画家算法带来2个问题。第一个问题上相互交错的物体,按照画家算法,这样的情况,GPU 会无从下手。所以早期的时候,设计师总是避免这样相互交错的设计。
|
||||
画家算法带来2个问题。第一个问题是相互交错的物体(类似于死循环,无法pick出谁应该最先被渲染),按照画家算法,这样的情况,GPU 会无从下手。所以早期的时候,设计师总是避免这样相互交错的设计。
|
||||
第二个问题是过度绘制,因为画家算法总是一层层绘制,所以存在重合叠加的情况,层级较低的物体总是会被过度绘制,浪费资源。
|
||||
|
||||
因为 GPU 的设计是并发、无序的,所以我们期望的画家算法是不希望浪费、等待,同时为了绘制速度,所以在此基础上引入了 Depth Buffer 和 Early-Z 和深度缓冲。
|
||||
@@ -91,8 +91,7 @@ GPU 利用片元将整个图片分为一个个像素,并且并行计算了每
|
||||
明白了画家算法的工作原理,也就明白了为什么会发生离屏渲染。
|
||||
- 离屏渲染需要创建额外的帧缓冲区
|
||||
- 渲染相关的上下文对象、帧缓冲区都比较大,切换会带来性能损耗
|
||||
- 内存拷贝,需要将临时帧缓冲区的内容拷贝到真正的帧缓冲区
|
||||
单帧渲染都会比较耗费性能了,如果屏幕上多个视图渲染都存在离屏渲染,整个界面会发生卡顿。
|
||||
- 内存拷贝,需要将临时帧缓冲区的内容拷贝到真正的帧缓冲区。单帧渲染都会比较耗费性能了,如果屏幕上多个视图渲染都存在离屏渲染,整个界面会发生卡顿。
|
||||
|
||||
|
||||
## 如何检测离屏渲染
|
||||
|
||||
Reference in New Issue
Block a user