
在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()`被調用的時候。
## 框架交互

將整個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