环境: flutter sdk v1.7.8+hotfix.3@stablejava
对应 flutter engine: 54ad777fandroid
这里关注的是C++层面的绘制流程,平台怎样驱动和响应绘制与渲染的过程,并非Dart部分的渲染。git
结合以前的分析,在虚拟机实例的构造函数中调用了一个重要方法DartUI::InitForGlobal()
, 调用流程再罗列一下:github
DartVMRef::Create
DartVMRef::DartVMRef
DartVM::Create
DartVMData::Create
DartVM::DartVM
DartUI::InitForGlobal()
复制代码
实现体很明了,注册了各类类对象的方法,也就是说,这些在dart语言继承NativeFieldWrapperClass2
的类都有一份在C++层的实现,也说明了DartSDK是如何提供接口绑定与C++层的实现,至关于java语言中的jni。 另外还有针对Isolate
的初始化,不过只是设置了一个能够import的路径,并不重要:shell
DartIsolate::CreateRootIsolate
DartIsolate::CreateDartVMAndEmbedderObjectPair
DartIsolate::LoadLibraries
DartUI::InitForIsolate
Dart_SetNativeResolver
复制代码
咱们知道RuntimeController持有一个Window实例,看Window实例被建立以后作了哪些制做:bash
RuntimeController::RuntimeController
Window::Window
DartIsolate::CreateRootIsolate
DartIsolate::DartIsolate
DartIsolate::SetWindow => UIDartState::SetWindow
WindowClient::UpdateIsolateDescription => RuntimeController::UpdateIsolateDescription
RuntimeDelegate::UpdateIsolateDescription => Shell::UpdateIsolateDescription
ServiceProtocol::SetHandlerDescription
Window::DidCreateIsolate
library_.Set("dart:ui")
RuntimeController::FlushRuntimeStateToIsolate
RuntimeController::SetViewportMetrics
Window::UpdateWindowMetrics
library_, _updateWindowMetrics
复制代码
操做从最里层的Window
一直传递到了Shell
,最重要的一个做用是初始化了ViewPort(视口:用做画布的大小,分辨率等尺寸信息),再跟一下ViewPort被初始化后又如何被设置的:app
FlutterView.onSizeChanged
FlutterView.updateViewportMetrics
FlutterJNI.setViewportMetrics
FlutterJNI.nativeSetViewportMetrics
::SetViewportMetrics
AndroidShellHolder::SetViewportMetrics
[async:ui]Engine::SetViewportMetrics
RuntimeController::SetViewportMetrics
Window::UpdateWindowMetrics
Engine::ScheduleFrame
复制代码
这里从Java调用到C++,FlutterView.onSizeChanged
这个操做是在FlutterView
实例建立以后被系统调用的(而FlutterView的建立发生在Activity.onCreate
时机),显然是响应平台层的通知,这符合咱们的认知预期,由于画布的大小可能由于用户操做发生变化,dart层须要被动响应。async
须要注意的是响应onSizeChanged
在Platform线程,调用Engine::SetViewportMetrics
切到了UI线程,铭记**Engine
的全部的操做都是在UI线程**。函数
Engine
在经过RuntimeController
设置了窗口的尺寸以后,调用了另外一个重要方法ScheduleFrame
,因而看它的实现:post
Engine::ScheduleFrame
Animator::RequestFrame
[async:ui]Animator::AwaitVSync
VsyncWaiter::AsyncWaitForVsync
callback_= {Animator::BeginFrame}
VsyncWaiter::AwaitVSync => VsyncWaiterAndroid::AwaitVSync
[async:platform]FlutterJNI.asyncWaitForVsync
AsyncWaitForVsyncDelegate.asyncWaitForVsync => VsyncWaiter.asyncWaitForVsyncDelegate
Choreographer.getInstance().postFrameCallback
Delegate::OnAnimatorNotifyIdle => Shell::OnAnimatorNotifyIdle
Engine::NotifyIdle
复制代码
这里操做有些凌乱,首先切到UI线程,又切到Platform线程,其实就是为了调用平台接口,搞清这个最终目的。 终于涉及到了绘制图像所须要的关键类Animator
和VSyncWaiter
:
VSync
信号,表示信号到达后执行Animator::BeginFrame
方法;VSync
信号?经过调用平台接口,平台操做必须都在Platform线程,因而从UI线程切到Platform线程,目的是去调用android的Choreographer.postFrameCallback
,这样又执行了一串从C++调到java的过程。由于是在java层调用的VSync
回调,只能先在Java层响应因而有:
FrameCallback.doFrame <= VsyncWaiter.asyncWaitForVsyncDelegate
FlutterJNI.nativeOnVsync
VsyncWaiterAndroid::OnNativeVsync
VsyncWaiterAndroid::ConsumePendingCallback
VsyncWaiter::FireCallback
[async:ui]callback() => Animator::BeginFrame
复制代码
在VSync信号到达以后,最终在UI线程响应了Animator::BeginFrame
,且看其实现:
Animator::BeginFrame
Animator::Delegate::OnAnimatorBeginFrame => Shell::
Engine::BeginFrame
Window::BeginFrame
library_."_beginFrame" => hooks.dart:_beginFrame
UIDartState::FlushMicrotasksNow
tonic::DartMicrotaskQueue::RunMicrotasks
library_."_drawFrame" => hooks.dart:_drawFrame
复制代码
最终的最终回到了dart层,并调用了其两个重要方法:_beginFrame
和_drawFrame
,完成了帧的绘制。
另外罗列一下VSyncWaiter
建立时机:
Shell::CreateShellOnPlatformThread
PlatformView::CreateVSyncWaiter => PlatformViewAndroid::CreateVSyncWaiter
VsyncWaiterAndroid()
Animator::Animator
Engine::Engine
复制代码
它是与建立Shell一样的时机,也就是说在Platform线程由PlatformView::CreateVSyncWaiter
建立的,并被Animator
持有,而Animator
又是被Engine
持有。VSyncWaiter
与Engine
同样,全部的操做都必须在UI线程中执行
窗口的渲染是由Dart层的Window完成的,其实调用了C++层的实现:
("Window_render", Render)
Render() (window.cc:30)
Scene=
WindowClient::Render
Scene::takeLayerTree
RuntimeDelegate::Render => Engine::Render
ProducerContinuation::Complete(layer_tree)
Animator::Delegate::OnAnimatorDraw => Shell::OnAnimatorDraw(layer_tree_pipeline_)
[async:gpu]Rasterizer::Draw => android_shell_holder.cc:76
Rasterizer::DoDraw
Rasterizer::DrawToSurface
Surface::AcquireFrame
ExternalViewEmbedder::BeginFrame
CompositorContext::AcquireFrame
ScopedFrame::Raster
SurfaceFrame::Submit
ExternalViewEmbedder::SubmitFrame
FireNextFrameCallbackIfPresent
Rasterizer::Delegate::OnFrameRasterized
"Window_scheduleFrame", ScheduleFrame
复制代码
这里涉及的对象更多了,并且紧密的与Dart层的绘制与渲染机制关联。值得注意的是具体的绘制操做(光栅化)是在GPU线程进行。
另外Dart层的Window也须要主动的调度帧,所以也绑定了ScheduleFrame
方法。