从架构到源码:一文了解Flutter渲染机制_阿里技术-CSDN博客
我们知道Android上的渲染都是在VSync信号驱动下进行的,Flutter在Android上的渲染也不例外,它会向Android系统注册并等待VSync信号,等到VSync信号到来以后,调用沿着C++ Engine->Java Engine,到达Dart Framework,开始执行Dart代码,经历Layout、Paint等过程,生成一棵Layer Tree,将绘制指令保存在Layer中,接着进行栅格化和合成上屏。
1)向Android系统注册并等待VSync信号
Flutter引擎启动时,会向Android系统的Choreographer(管理VSync信号的类)注册并接收VSync信号的回调。
2)接收到VSync信号,通过C++ Engine向Dart Framework发起渲染调用
当VSync信号产生以后,Flutter注册的回调被调用,VsyncWaiter::fireCallback() 方法被调用,接着会执行 Animator::BeiginFrame(),最终调用到 Window::BeginFrame() 方法,WIndow实例是连接底层Engine和Dart Framework的重要桥梁,基本上与平台相关的操作都会通过Window实例来连接,例如input事件、渲染、无障碍等。
3)Dart Framework开始在UI线程执行渲染逻辑,生成Layer Tree,并将栅格化任务post到GPU线程执行
Window::BeiginFrame() 接着调用,执行到 RenderBinding::drawFrame() 方法,这个方法会去驱动UI界面上的dirty节点(需要重绘的节点)进行重新布局和绘制,如果渲染过程中遇到图片,会先放到Worker Thead去加载和解码,然后再放到IO Thread生成图片纹理,由于IO Thread和GPI Thread共享EGContext,因此IO Thread生成的图片纹理可以被GPU Thread直接访问。
4)GPU线程接收到Layer Tree,进行栅格化以及合成上屏的工作
Dart Framework绘制完成以后会生成绘制指令保存在Layer Tree中,通过 Animator::RenderFrame() 把Layer Tree提交给GPU Thread,GPU Thread接着执行栅格化和上屏显示。之后通过 Animator::RequestFrame() 请求接收系统的下一次VSync信号,如此循环往复,驱动UI界面不断更新。
每帧都包含如下步骤:
此阶段又叫SchedulerPhase.transientCallbacks。
Window.onBeginFrame上注册的监听方法SchedulerBinding.handleBeginFrame,会被engine调用来准备framework来去产生一个新帧。
在handleBeginFrame中,会按顺序执行 在SchedulerBinding.scheduleFrameCallback()方法中注册的所有callback,这包括驱动AnimationController对象的所有Ticker实例,这意味着所有active动画对象都在这一点启动。
之所以叫transientCallbacks,是因为只会把注册的callback执行一次,之后就全部丢弃。
此阶段又叫SchedulerPhase.midFrameMicrotasks
handleBeginFrame 返回后,所有的microtasks(在callback中调度的)开始运行,This typically includes callbacks for futures from Tickers and AnimationControllers that completed this frame.
此阶段又叫SchedulerPhase.persistentCallbacks,
接着就是调用Window.onDrawFrame上注册的监听方法SchedulerBinding.handleDrawFrame,该调用将调用所有注册persistentCallbacks,
之所以叫persistentCallbacks是因为每帧都会执行,执行完后不会删除persistentCallbacks列表。
其中最引人注目的是此方法RendererBinding.drawFrame,其过程如下:
For more details, see PipelineOwner.
这个阶段是WidgetsBinding的drawFrame中的。WidgetsBinding 继承了SchedulerBinding。
if (renderViewElement != null) buildOwner.buildScope(renderViewElement); super.drawFrame();
Althe dirty Elements in the widget tree are rebuilt (see State.build).
See State.setState for further details on marking a widget dirty for building.
See BuildOwner for more information on this step.
Althe dirty RenderObjects in the system are laid out (see RenderObject.performLayout).
See RenderObject.markNeedsLayout for further details on marking an object dirty for layout.
The compositing bits on any dirty RenderObject objects are updated.
See RenderObject.markNeedsCompositingBitsUpdate.
Althe dirty RenderObjects in the system are repainted (see RenderObject.paint).
This generates the Layer tree.
See RenderObject.markNeedsPaint for further details on marking an object dirty for paint.
The layer tree is turned into a Scene and sent to the GPU.
Althe dirty RenderObjects in the system have their semantics updated.
This generates the SemanticsNode tree.
See RenderObject.markNeedsSemanticsUpdate for further details on marking an object dirty for semantics.
此阶段又叫SchedulerPhase.postFrameCallbacks,
在WidgetsBinding.drawFrame中执行完super.drawFrame后,会调用:
buildOwner.finalizeTree();
The widgets tree is finalized.
This causes State.dispose to be invoked on any objects that were removed from the widgets tree this frame.
在persistentCallbacks执行之后,SchedulerBinding.handleDrawFrame 会去调用在addPostFrameCallback()注册的postFrameCallbacks。
原文:https://www.cnblogs.com/muouren/p/14245332.html