Flutter 绘制原理与 Flutter 基本框架

1,329 阅读3分钟

我正在参加跨端技术专题征文活动,详情查看:juejin.cn/post/710123…

关于图像的显示

不管是手机、电脑还是电视,我们在屏幕上可以看到的所有内容都是计算机绘制出来的图像。把相关图片连续播放就会产生动画效果,比如下面的小黄鸭的动画效果

小黄鸭.gif

将这个小黄鸭的动画拆解出来,其实就是很多张图片

截屏2022-05-29 上午10.11.58.png

  • 关于图片显示的整个过程有俩个相关概念

    • 帧率(fps):每秒钟显示多少帧,也可以理解为每秒钟显示多少画面
    • 刷新率:显示器在一秒内刷新的次数,比如 iPhone 的刷新频率是 60Hz,每秒刷新60次
  • 帧率和刷新率的关系

    在计算机中,CPU、GPU 和显示器以一种特定的方式协作

    • 将数据传递给 CPU,CPU进行处理

    • CPU 将处理好的显示内容提交给 GPU

    • GPU 渲染后放入帧缓冲区

    • 视频控制器按照 VSync 信号从帧缓冲区取出帧数据传递给显示器显示

      想要了解 VSync 信号原理可以看这篇文章 Android Vsync原理简析


Flutter 绘制原理

Android、iOS、Flutter 的 UI 渲染过程都一样,在整个 Flutter 架构中,Flutter 只关心向 GPU 提供显示数据,不用关心显示屏、视频控制器以及 GPU 是如何工作的

截屏2022-05-29 上午11.50.20.png

  • 绘制流程

    • GPU 收到 VSync 信号后通知 UI 线程

    • UI 线程用 Dart 来构建图层树

    • 图层树在 GPU 线程进行合成

    • 合成后的视图数据提供给 Skia 引擎

    • Skia 引擎通过 OpenGL 或者 Vulkan 将显示内容提供给 GPU

  • 关于 Skia 引擎

    • Skia(Skia Graphics Library)是一个由 C++ 编写的开源图形库

    • 在 Flutter 中,Skia 就是向 GPU 提供数据的途径

    • Skia 目前是 Android 官方的图像渲染引擎,因此,Flutter Android SDK 无需内嵌 Skia 引擎就可以获得 Skia 支持

    • 对于 iOS 来说,由于 Skia 是跨平台的,它作为Flutter iOS 的渲染引擎被嵌入到 Flutter 的 iOS SDK 中,替代了 iOS 平台本身的 Core Graphics/Core Animation/Core Text,所以, Flutter iOS 打包成 api 时体积会比 Android 大一些

    • 由于 Android 和 iOS 底层都是使用 Skia 引擎,所以底层渲染能力统一了,上层开发接口及功能体验也保持了一致

  • Flutter 和 React Native 的本质区别

    • React Native 之类的框架,只是通过 JavaScript 虚拟机扩展调用系统组件,最终由 Android 和 iOS 系统进行组件渲染
    • Flutter 是自己完成了组件渲染的闭环

Flutter 基本框架

Snip20220107_4.png

Flutter 框架分为三层:FrameworkEnginEmbedder

  • Framework

    Flutter Framework 是一个纯 Dart实现的 SDK。它实现了一套基础库, 用于处理动画、绘图和手势。并且基于绘图封装了一套 UI组件库,然后根据 Material(Android 风格) 和 Cupertino(iOS 风格)两种视觉风格区分开来。这个纯 Dart 实现的 SDK 被封装为了一个叫作 dart:ui 的 Dart 库。我们在使用 Flutter 写 App 的时候,直接导入这个库即可使用组件等功能。

  • Engin

    Flutter Engine 是一个纯 C++实现的 SDK。囊括了 Skia引擎、Dart运行时、文字排版引擎等。它是 Dart的一个运行时,它可以以 JIT、JIT Snapshot 或者 AOT的模式运行 Dart代码。这个运行时还控制着 VSync信号的传递、GPU数据的填充等,并且还负责把客户端的事件传递到运行时中的代码

  • Embedder

    是一个嵌入层,即把 Flutter 嵌入到各个平台上去,这里做的主要工作包括渲染 Surface 设置,线程设置,以及插件等。这里可以看出,Flutter 的平台相关层很低,平台只是提供一个画布,剩余的所有渲染相关的逻辑都在 Flutter 内部,这就使得它具有了很好的跨端一致性