链接:https://juejin.cn/post/7062552765117136903
https://developer.android.com/topic/performance/rendering/profile-gpu?hl=zh-cn
RenderThread的作用:
主线程的 draw 函数并没有真正的执行 drawCall ,而是把要 draw 的内容记录到 DIsplayList 里面(在 Measure、Layout、Draw 的 Draw 这个环节,Android 使用 DisplayList 进行绘制而非直接使用 CPU 绘制每一帧。),同步到 RenderThread 中,一旦同步完成,主线程就可以被释放出来做其他的事情,RenderThread 则继续进行渲染工作
2.3 生产者和消费者
我们再回到 Vsync 的话题,消费 Vsync 的双方分别是 App 和 sf,其中 App 代表的是生产者,sf 代表的是消费者,两者交付的中间产物则是 surface buffer。
再具体一点,生产者大致可以分为两类,一类是以 window 为代表的页面,也就是我们平时所看到的 view 树这一套;另一类是以视频流为代表的可以直接和 surface 完成数据交换的来源,比如相机预览等。
对于一般的生产者和消费者模式,我们知道会存在相互阻塞的问题。比如生产者速度快但是消费者速度慢,亦或是生产者速度慢消费者速度快,都会导致整体速度慢且造成资源浪费。所以 Vsync 的协同以及双缓冲甚至三缓冲的作用就体现出来了。
思考一个问题:是否缓冲的个数越多越好?过多的缓冲会造成什么问题?
答案是会造成另一个严重的问题:lag,响应延迟
这里结合 view 的一生,我们可以把两个流程合在一起,让我们的视角再高一层:
我们一般都比较了解 view 渲染的三大流程,但是 view 的渲染远不止于此:
此处以一个通用的硬件加速流程来表征
- Vsync 调度:很多同学的一个认知误区在于认为 vsync 是每 16ms 都会有的,但是其实 vsync 是需要调度的,没有调度就不会有回调;
- 消息调度:主要是 doframe 的消息调度,如果消息被阻塞,会直接造成卡顿;
- input 处理:触摸事件的处理;
- 动画处理:animator 动画执行和渲染;
- view 处理:主要是 view 相关的遍历和三大流程;
- measure、layout、draw:view 三大流程的执行;
- DisplayList 更新:view 硬件加速后的 draw op;
- OpenGL 指令转换:绘制指令转换为 OpenGL 指令;
- 指令 buffer 交换:OpenGL 的指令交换到 GPU 内部执行;
- GPU 处理:GPU 对数据的处理过程;
- layer 合成:surface buffer 合成屏幕显示 buffer 的流程;
- 光栅化:将矢量图转换为位图;
- Display:显示控制;
- buffer 切换:切换屏幕显示的帧 buffer;