Flutter布局和渲染流程
图像显示原理
- CPU负责
图像数据计算
, 然后交给 GPU - GPU负责
图像数据渲染
, 渲染后放入帧缓冲区
- 视频控制器根据
垂直同步信号(VSync)
以每秒60次的速度,从帧缓冲区读取帧数据交由显示器完成图像显示。
Flutter 图像显示流程
UI线程
使用Dart来构建视图结构数据
(Widget),这些数据会在GPU线程
进行图层合成
,随后交给Skia引擎加工成GPU数据
,- GPU数据通过OpenGL最终提供给GPU渲染。
- 需要在两个
VSync
信号之间完成这些操作,不然会卡顿
Skia是什么?
-
Skia是一款C++开发的、跨平台、性能优秀的2D图像绘制引擎
-
Skia是
Android
官方的图像渲染引擎,所以无需内嵌Skia引擎就可以获得天然的Skia支持; -
iOS
: 嵌入到Flutter的 iOS SDK中,替代了iOS闭源的Core Graphics/Core Animation/Core Text
,这也正是 iOS App包体积比Android要大一些的原因。 -
Skia 优点
Skia统一了各个系统的渲染逻辑, 保证同一套代码在Android和iOS平台上的渲染效果是完全一致的。
Flutter界面渲染过程
- 页面中的Widget以树的形式组织成
控件树
。 - 为控件树中的每个Widget创建不同类型的
渲染对象(RenderObject)
,组成渲染对象树
。 - 渲染对象树展示过程分为四个阶段:
布局、绘制、合成和渲染
。
布局
- Flutter采用
深度优先
遍历渲染对象树,决定渲染对象树中各渲染对象在屏幕上的位置和尺寸
。 - 渲染对象树中的每个渲染对象都会接收父对象的布局约束参数,决定自己的大小,
- 父对象按照控件逻辑决定各个子对象的位置,完成布局过程。
Flutter在某些节点设置布局边界
(Relayout Boundary),当边界内的任何对象发生重新布局时,不会影响边界外的对象。
绘制
- 把渲染对象绘制到不同的
图层
上。 - 绘制过程也是
深度优先
遍历,先绘制自身,再绘制子节点。
以下图为例:节点1在绘制完自身后,会再绘制节点2,然后绘制它的子节点3、4和5,最后绘制节点6。
子节点5与它的兄弟节点6处于了同一层,当
节点2重绘的时候
,与其无关的节点6也会被重绘
,带来性能损耗。
为了解决这一问题,Flutter使用重绘边界(Repaint Boundary)
, Flutter强制切换新的图层
,避免无关内容置于同一图层引起不必要的重绘。
Scrollview
使用重绘边界, 保证滚动时只重绘可视内容,不可见内容不重绘。
合成
- Flutter的渲染树层级很多,直接交付给渲染引擎进行
多图层渲染
,会出现大量渲染内容的重复绘制, - 图层合成: 将所有的图层根据大小、层级、透明度等规则计算出最终的显示效果,将相同的图层归类合并,简化渲染树,提高渲染效率。
渲染
合成完成后,Flutter将几何图层数据交由Skia引擎加工成二维图像数据,最终交由GPU进行渲染,完成界面的展示。
转载自:https://juejin.cn/post/7242815848087486520