初识Flutter

2020-05-08  本文已影响0人  HJ_Technology
1.为什么会有Flutter出现

这要从移动端跨平台解决方案说起,目前大部分企业还是采用的

image.png
2.Flutter的绘制原理
image.png
  1. CPU/GPU 向 Buffer 中生成图像,屏幕从 Buffer 中取 图像、刷新后显示。这 是一个典型的生产者——消费者模型。理想的情况是帧率和刷新频率相等,每绘制一帧,屏幕显示一帧。但是实际往往它们的大小是不同的。
  2. 如果没有锁来控制同步,很容易出现问题。例如: 当帧率大于刷新频率,当屏幕还没有刷新第 n-1 帧的时候,GPU 已经在生成第 n 帧了, 从上往下开始覆盖第 n-1 帧的数据,当屏幕开始刷新第 n-1 帧的时候,Buffer 中的数据上半部分是第 n 帧数据, 而下半部分是第 n-1 帧的数据, 显示出来的图像就会出现上半部分和下半部分明显偏差 的现象,我们称之为 “tearing”(撕裂)
  1. 为了解决单缓存的“tearing”问题,就出现了 双重缓存和 VSync ,
    两个缓存区分别为 Back Buffer 和 Frame Buffer。
    GPU 向 Back Buffer 中写数据,屏幕从 Frame Buffer 中读数据。
    VSync 信号负责调度从 Back Buffer 到 Frame Buffer 的复制操作,当然底层不是通过复制,而是通过交换内存地址方式,所以可以瞬 间完成,效率是非常高的;
  2. 工作流程
    在某个时间点,一个屏幕刷新周期完成,VSync 信号产生,先完成复制操作,然 后通知 CPU/GPU 绘制下一帧图像。
    复制操作完成后屏幕开始下一个刷新周期,即将刚复制到 Frame Buffer 的数据显示到屏幕上。
    在这种模型下,只有当 VSync 信号产生时,CPU/GPU 才会开始绘 制。
image.png
  1. 双重缓存的缺陷在于:当 CPU/GPU 绘制一帧的时间过长(比如超过 16ms)时,会产生 Jank(画面停顿,甚至空白)。
  2. 蓝色代表 CPU 生成 Display List;
  3. 绿色代表 GPU 执行 Display List 中的命令从而生成帧; p 黄色代表生成帧完成,在屏幕上显示;
    图片说明: CPU生成蓝色B的数据,由GPU进行B的绘制,但是这个过长由于过长,那么第二个A就产生了Jank。 B在屏幕上显示之后,发出Vsync信号,A开始绘制,但是由于绘制时间 过长,第二个B位置又产生了Jank
image.png

如何解决双重缓存的问题了?

  1. 在第二个A展示,Vsync信号发出后,直接绘制C Buffer
  2. 在第一个B展示,Vsync信号发出后,绘制A Buffer
  3. 因为C已经在缓存中,可以直接从缓存中取出C Buff来进行展示,依次类 推
  4. 其实本质是在每次Vsync信号发出后,多缓存一个Buffer作为备用
  1. GPU将信号同步到 UI 线程
  2. UI 线程用Dart来构建图层树
  3. 图层树在GPU 线程进行合成
  4. 合成后的视图数据提供给Skia 引擎
  5. Skia 引擎通过OpenGL 或者 Vulkan将显示内容提供给GPU
  1. React Native 之类的框架,只是通过 JavaScript 虚拟机扩展调用系统组件,由 Android 和 iOS 系统进行组件的渲染; Flutter 是自己完成了组件渲染的闭环
  1. 目前,Skia 已然是 Android 官方的图像渲染引擎了,因此 Flutter Android SDK 无需内嵌 Skia 引擎就可以获得天然的 Skia 支持;
  2. 而对于 iOS 平台来说,由于 Skia 是跨平台的,因此它作为 Flutter iOS 渲染引 擎被嵌入到 Flutter 的 iOS SDK 中,替代了 iOS 闭源的 Core Graphics/Core Animation/Core Text,这也正是 Flutter iOS SDK 打包的 App 包体积比 Android 要大一些的原因。
  3. 底层渲染能力统一了,上层开发接口和功能体验也就随即统一了,开发者再也不 用操心平台相关的渲染特性了。也就是说,Skia 保证了同一套代码调用在 Android 和 iOS 平台上的渲染效果是完全一致的。
上一篇 下一篇

猜你喜欢

热点阅读