![](https://img.kancloud.cn/cb/53/cb532dba43f338c449a02c5b63530c49_1280x723.png)
在Flutter框架中存在着一个渲染流水线(Rendering pipline)。这个渲染流水线是由垂直同步信号(Vsync)驱动的,当Vsync信号到来以后,Flutter 框架会按照图里的顺序执行一系列动作: 动画(Animate)、构建(Build)、布局(Layout)和绘制(Paint),最终生成一个场景(Scene)之后送往底层,由GPU绘制到屏幕上。
* 动画(Animate)阶段:因为动画会随每个Vsync信号的到来而改变状态(State),所以动画阶段是流水线的第一个阶段。
* 构建(Build)在这个阶段Flutter,在这个阶段那些需要被重新构建的Widget会在此时被重新构建。也就是我们熟悉的`StatelessWidget.build()`或者`State.build()`被调用的时候。
* 布局(Layout)阶段,这时会确定各个显示元素的位置,尺寸。此时是`RenderObject.performLayout()`被调用的时候。
* 绘制(Paint)阶段,此时是`RenderObject.paint()`被调用的时候。
## 框架交互
![](https://img.kancloud.cn/80/7b/807b9354506b058fd4e0ba3d3578666d_473x434.png)
将整个Flutter架构是分为两部分的。上层的框架(Framework)部分和底层的引擎(Engine)部分。
* 框架(Framework)部分是用Dart语言写的,也是本系列文章主要涉及的部分。
* 引擎(Engine)部分是用C++实现的。引擎为框架提供支撑,也是连接框架和系统(Android/iOS)的桥梁。
渲染流程从框架和引擎交互的角度用一个示意图来表示就是下面这个样子:
* 框架通知引擎(`scheduleFrame`)需要调度一帧。
* 在系统的Vsync信号到来以后,引擎会首先会回调框架的`_beginFrame`函数。此时框架的渲染流水线进入动画(Animate)阶段,
* 在动画(Animate)阶段阶段完成以后。引擎会处理完微任务队列,接着再回调框架的`_drawFrame`函数。渲染流水线继续按序运行构建、布局和绘制。
* 绘制结束以后,框架调用`render`将绘制完成的场景送入引擎以显示到屏幕上。
## window
`window`集中提供了Flutter引擎中和图形界面相关的接口。即对上层提供屏幕尺寸,调度接口,输入事件回调,图形绘制接口以及其他一些核心服务。
`Window`来自库`dart:ui`。相关源代码在`window.dart`中。`Window`是个单例:
~~~
final Window window = new Window._();
~~~
`Window`中和渲染流水线相关的api如下:
~~~
// vcync信号到来以后的回调
FrameCallback _onBeginFrame;
VoidCallback _onDrawFrame;
// 请求engine调度一帧
void scheduleFrame() native 'Window_scheduleFrame';
// 绘制完成后将场景送入engine显示
void render(Scene scene) native 'Window_render';
~~~
## QA
### Vsync触发时机
Flutter app只有在状态发生变化的时候需要触发渲染流水线。当你的app什么都不做的时候是不需要重新渲染页面的。所以,Vsync信号需要Flutter app去调度。比如我们都知道如果你的某个页面需要发生变化的时候有可能会调用`State.setState()`,这个调用Flutter框架最终会发起一个调度Vsync信号`scheduleFrame`的请求给底层。然后底层会在Vsync信号到来的时候驱动渲染流水线开始运作。
//TODO Vsync