feat: APM

This commit is contained in:
LiuBinPeng
2022-03-30 16:58:48 +08:00
parent a3e54696ab
commit 2864a120ff
8 changed files with 444 additions and 10 deletions

View File

@@ -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就是普通渲染的nn>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 利用片元将整个图片分为一个个像素,并且并行计算了每
明白了画家算法的工作原理,也就明白了为什么会发生离屏渲染。
- 离屏渲染需要创建额外的帧缓冲区
- 渲染相关的上下文对象、帧缓冲区都比较大,切换会带来性能损耗
- 内存拷贝,需要将临时帧缓冲区的内容拷贝到真正的帧缓冲区
单帧渲染都会比较耗费性能了,如果屏幕上多个视图渲染都存在离屏渲染,整个界面会发生卡顿。
- 内存拷贝,需要将临时帧缓冲区的内容拷贝到真正的帧缓冲区。单帧渲染都会比较耗费性能了,如果屏幕上多个视图渲染都存在离屏渲染,整个界面会发生卡顿。
## 如何检测离屏渲染