TaskPerFrame

16ms 内都需要完成什么

from : https://juejin.cn/post/7062552765117136903

图片

// Vsync顶层

  1. Vsync 调度:硬件每隔16.6ms发出硬件Vsync信号,需要经过软件调度,类似注册,才能收到回调

  2. 消息调度:主要是 doframe 的消息调度,如果消息被阻塞,会直接造成卡顿;

  3. input 处理:触摸事件的处理;

  4. 动画处理:animator 动画执行和渲染;

  5. view 处理:主要是 view 相关的遍历和三大流程;

  6. measure、layout、draw:view 三大流程的执行;

    //Vsync底层

  7. DisplayList 更新:view 硬件加速后的 draw op;

  8. OpenGL 指令转换:canvas指令转换为 OpenGL 指令;

  9. 指令 buffer 交换:OpenGL 的指令交换到 GPU 内部执行;

  10. GPU 处理:GPU 对数据的处理过程;

  11. layer 合成:surface buffer 合成屏幕显示 buffer 的流程;

  12. 光栅化:将矢量图转换为位图;

  13. Display:显示控制;

  14. buffer 切换:切换屏幕显示的帧 buffer;

Read more

RenderBlock

链接: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 则继续进行渲染工作
image

2.3 生产者和消费者

图片

我们再回到 Vsync 的话题,消费 Vsync 的双方分别是 App 和 sf,其中 App 代表的是生产者,sf 代表的是消费者,两者交付的中间产物则是 surface buffer

再具体一点,生产者大致可以分为两类,一类是以 window 为代表的页面,也就是我们平时所看到的 view 树这一套;另一类是以视频流为代表的可以直接和 surface 完成数据交换的来源,比如相机预览等。

对于一般的生产者和消费者模式,我们知道会存在相互阻塞的问题。比如生产者速度快但是消费者速度慢,亦或是生产者速度慢消费者速度快,都会导致整体速度慢且造成资源浪费。所以 Vsync 的协同以及双缓冲甚至三缓冲的作用就体现出来了。

思考一个问题:是否缓冲的个数越多越好?过多的缓冲会造成什么问题?

答案是会造成另一个严重的问题:lag,响应延迟

这里结合 view 的一生,我们可以把两个流程合在一起,让我们的视角再高一层:

图片

我们一般都比较了解 view 渲染的三大流程,但是 view 的渲染远不止于此:

此处以一个通用的硬件加速流程来表征

图片

  1. Vsync 调度:很多同学的一个认知误区在于认为 vsync 是每 16ms 都会有的,但是其实 vsync 是需要调度的,没有调度就不会有回调;
  2. 消息调度:主要是 doframe 的消息调度,如果消息被阻塞,会直接造成卡顿;
  3. input 处理:触摸事件的处理;
  4. 动画处理:animator 动画执行和渲染;
  5. view 处理:主要是 view 相关的遍历和三大流程;
  6. measure、layout、draw:view 三大流程的执行;
  7. DisplayList 更新:view 硬件加速后的 draw op;
  8. OpenGL 指令转换:绘制指令转换为 OpenGL 指令;
  9. 指令 buffer 交换:OpenGL 的指令交换到 GPU 内部执行;
  10. GPU 处理:GPU 对数据的处理过程;
  11. layer 合成:surface buffer 合成屏幕显示 buffer 的流程;
  12. 光栅化:将矢量图转换为位图;
  13. Display:显示控制;
  14. buffer 切换:切换屏幕显示的帧 buffer;
Read more

Surface

  • SurfaceView: View 的子类,但不与宿主 Window 共享 Surface, 而是有自己独立的 Surface, 且可以在一个独立的线程中进行绘制,因此 SurfaceView 一般用来实现比较复杂的图像或动画/视频的显示。可以参考 Android双缓存与SurfaceView。由于其内容是绘制在一个独立的 Surface 上,因此无法用 scrollTo/By 等方法去移动操作 Canvas 里的内容,但是可对整个 View 进行平移,缩放,旋转等变换操作。
  • GLSurfaceView: 基于 SurfaceView 再次进行扩展,在 SurfaceView 基础上封装了 EGL 环境管理以及 Render 线程,专门为 OpenGl 显示渲染使用。参考 Android-OpenGL-ES笔记
  • TextrueView: Android 4.0 后引入 TextureView, 它将 SurfaceTexture 和 View 结合到了一起。与 SurfaceView 相比,它并没有创建一个单独的 Surface 来绘制,解决了 SurfaceView 无法在 Canvas 内容上做动画的问题。另外 TextureView 必须在硬件加速开启的窗口中使用。
Read more

ScreenDraw

从onCreate到页面绘制

当手指点击了桌面的App图标时发生了什么 - ProcessOn

Android 屏幕刷新机制

主要参考 https://juejin.cn/post/6863756420380196877#heading-12

省流版:

双缓存:为了解决画面撕裂;画面撕裂来自于只有一个buffer时,正在display的那一帧数据被后一帧的数据覆盖了

Vsync:系统在收到VSync pulse(Vsync脉冲)后,将马上开始下一帧的渲染,(CPU开始计算数据)。

三缓冲:当显示器正在写入FrameBuffer同时GPU也正在写入BackBuffer时,下一次渲染开始了,此时CPU可以使用新增的GraphicBuffer进行计算。减少了Jank。(更多缓冲需要耗费更大的内存)

ChoreoGrapher机制:规定了数据计算开始(measure、layout、draw)的时机(vsync信号),使计算到渲染图像数据能有一个完整的16.6ms:更新ui(request()/invalidate())后编舞者注册vsync信号回调,在下一个vsync信号到时候立刻进行view的测量布局绘制

Read more