编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 02.Android虚拟机知识
  • 03.App核心概念分析
  • 04.Android消息机制
  • 05.Android程序UI框架
  • 06.Android应用窗口
  • 07.WMS机制深入分析
  • 08.PMS机制深入分析
  • 09.AMS机制深入分析
  • 11.四大组件原理分析
  • 12.四大组件原理分析
  • 13.View绘制流程分析
  • 14.View渲染流程分析
  • 16.Android绘制原理
  • 17.Android事件传输
  • 18.Android事件拦截
  • 21.View自定义控件反思
  • 22.ViewGroup自定义控件
  • 25.IPC跨进程通信实践
  • 29.Binder机制的理解

14.View渲染流程分析

目录介绍

  • 02.View如何显示在屏幕
  • 03.绕不开的VSYNC
  • 04.生产者和消费者模型
  • 05.渲染上机制有哪些保护

02.View如何显示在屏幕

  • 一个 view 究竟是如何显示在屏幕上的?
    • 一般都比较了解 view 渲染的三大流程,但是 view 的渲染远不止于此:此处以一个通用的硬件加速流程来表征
    • image
      image
  • 关于整个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;

03.绕不开的VSYNC

  • 通常会说,屏幕的刷新率是 60 帧,需要在 16ms 内做完所有的操作才不会造成卡顿。但是这里需要明确几个基本问题:
    • 第一个问题:为什么是 16ms?16ms 内都需要完成什么?
    • 第二个问题:系统如何尽力保证任务在 16ms 内完成?16ms 内没有完成,一定会造成卡顿吗?
  • 第一个问题:为什么是 16ms?16ms 内都需要完成什么?
    • 一般的屏幕刷新率是 60fps,所以每个 vsync 信号的间隔也是 16ms。
    • 16ms内要做的:VSync 延迟、input输入处理、动画、测量/布局、绘制、同步和上传、命令问题、交换缓冲区。也就是我们常用的 GPU 严格模式。

04.生产者和消费者模型

  • 回到 Vsync 的话题,消费 Vsync 的双方分别是 App 和 s
    • 其中 App 代表的是生产者,sf 代表的是消费者,两者交付的中间产物则是 surface buffer。
    • image
      image
  • 再具体一点,生产者大致可以分为两类
    • 一类是以 window 为代表的页面,也就是我们平时所看到的 view 树这一套;
    • 另一类是以视频流为代表的可以直接和 surface 完成数据交换的来源,比如相机预览等。
  • 一般的生产者和消费者模式,会存在相互阻塞的问题
    • 比如生产者速度快但是消费者速度慢,亦或是生产者速度慢消费者速度快,都会导致整体速度慢且造成资源浪费。
    • 所以 Vsync 的协同以及双缓冲甚至三缓冲的作用就体现出来了。
  • 思考一个问题:是否缓冲的个数越多越好?过多的缓冲会造成什么问题?
    • 答案是会造成另一个严重的问题:lag,响应延迟
  • 这里结合 view 的一生,我们可以把两个流程合在一起,让我们的视角再高一层:
    • image
      image

05.渲染上机制有哪些保护

  • 系统如何尽力保证任务在 16ms 内完成?从系统的渲染架构上来说,机制上的保护主要有几方面:
    • Vsync机制的协同;
    • 多缓冲设计;
    • surface 的提供;
    • 同步屏障的保护;
    • 硬件绘制的支持;
    • 渲染线程的支持;
    • GPU 合成加速;
  • 这些机制上的保护在系统层面最大程度地保障了 App 体验的流畅性,但是并不能帮我们彻底解决卡顿。
    • 为了提供更加流畅的体验,一方面,我们可以加强系统的机制保护,比如 FWatchDog;另一方面,需要我们从 App 的角度入手,治理应用内的卡顿问题。
贡献者: yangchong211
上一篇
13.View绘制流程分析
下一篇
16.Android绘制原理