1. 使用bundle资源路径构造flutter::DartProject对象
1.1 bundle资源路径下需要 /data/flutter_assets,/data/icudtl.dat,/lib/libapp.so
1.1.1 icudtl.dat 由FlutterTool提供,作为资源使用
1.1.2 flutter_assets 由FlutterTool构建
1.1.3 libapp.so 由FlutterTool构建,用于aot构建
1.2 DartProject是官方的类,构造中仅保存三个文件路径
2. 创建flutter::FlutterViewController::ViewProperties对象,填充宽高,旋转角度,是否有光标等参数
3. 使用flutter::FlutterViewController::ViewProperties对象和flutter::DartProject对象构建FlutterWindow对象
3.1 FlutterWindow对象应该就是自定义的
4. 调用FlutterWindow::OnCreate()方法启动引擎
4.1 使用flutter::FlutterViewController::ViewProperties对象
和flutter::DartProject对象构造flutter::FlutterViewController对象
4.1.1 构造中会使用flutter::DartProject对象构造flutter::FlutterEngine对象
4.1.1.1 构造中会从DartProject中取出argc,argv,以及三资源的路径初始化FlutterDesktopEngineProperties
4.1.1.2 构造中会使用FlutterDesktopEngineProperties构造FlutterProjectBundle对象
4.1.1.3 构造中会创建一个TaskRunner对象(用于执行任务), 运行时会检测engine是否为空,
不为空则会调用flutter API接口运行task(engine为FlutterEngine(添加符号是为了以后拓展),此时还未初始化)
task_runner_ = std::make_unique<TaskRunner>(
std::this_thread::get_id(), embedder_api_.GetCurrentTime,
[this](const auto* task) {
if (!engine_) {
ELINUX_LOG(ERROR)
<< "Cannot post an engine task when engine is not running.";
return;
}
if (embedder_api_.RunTask(engine_, task) != kSuccess) {
ELINUX_LOG(ERROR) << "Failed to post an engine task.";
}
});
4.1.1.3 构造中会使用FlutterProjectBundle对象构造FlutterELinuxEngine对象
4.1.1.3.1 构造中初始化FlutterEngineProcTable对象(内含Flutter操作API)
4.1.1.3.2 构造中构造FlutterDesktopMessenger对象,并使用FlutterELinuxEngine初始化engine成员
4.1.1.3.3 构造中创建FlutterDesktopPluginRegistrar对象,并使用FlutterELinuxEngine初始化engine成员
4.1.1.3.4 构造中使用FlutterDesktopMessenger对象构造BinaryMessengerImpl对象
4.1.1.3.5 构造中使用FlutterDesktopMessenger对象构造IncomingMessageDispatcherImpl对象
4.1.1.3.6 构造中使用FlutterELinuxEngine对象构造FlutterELinuxTextureRegistrar对象
4.1.1.3.7 构造中使用FlutterDesktopMessager对象,JsonMessageCodec单例json解码器构建BasicMessageChannel对象
该消息通道的name为:"flutter/settings"
4.1.1.3.8 构造中创建一个VsyncWaiter对象(通过该对象向flutter发送vsync事件)
4.1.1.4 构造中会强制将FlutterELinuxEngine转化为FlutterDesktopEngine对象(实际就是个void*, 无法操作),
并返回,目的是避免别人操作该对象,去掉类属性
4.1.1.5 构造中会使用FlutterELinuxEngine对象中的FlutterDesktopMessenger对象构造BinaryMessengerImpl对象
4.1.2 构造中会使用flutter::FlutterViewController::ViewProperties对象,
构造FlutterDesktopViewProperties(flutter-elinux自定义)对象
4.1.3 构造中会使用FlutterDesktopViewProperties对象
和FlutterELinuxEngine对象调用FlutterDesktopViewControllerCreate
构造flutter::FlutterDesktopViewController对象
4.1.3.1 使用FlutterDesktopViewProperties构造ELinuxWindowX11(父类为WindowBindingHandler)对象
4.1.3.1.1 构造函数中将会创建Display对象(XOpenDisplay()过去Display)
4.1.3.2 构造FlutterDesktopViewControllerState对象
4.1.3.3 使用ELinuxWindowX11(父类为WindowBindingHandler)对象构造
FlutterELinuxView(父类为WindowBindingHandlerDelegate)对象,
并将FlutterELinuxView(父类为WindowBindingHandlerDelegate)对象保存到
FlutterDesktopViewControllerState对象中。
4.1.3.3.1 构造中还将FlutterELinuxView设置到ELinuxWindowX11中,实现双向绑定
4.1.3.4 调用FlutterDesktopViewController对象的CreateRenderSurface方法
4.1.3.4.1 获取ELinuxWindowX11的尺寸
4.1.3.4.2 调用ELinuxWindowX11的CreateRenderSurface方法(以下属于X11窗口机制,需要花事件理解)
4.1.3.4.2.1 使用Display对象构造EnvromentEgl对象
4.1.3.4.2.1.1 构造中使用EGLNativeDisplayType(理论上Dispaly应该是EGLNativeDisplayType的父类)
作为参数,调用eglGetDisplay获取EGLDisplay
4.1.3.4.2.1.2 调用InitializeEgl(初始化egl)
4.1.3.4.2.2 构造NativeWindowX11对象
4.1.3.4.2.2.1 创建EGLNativeWindowType对象(XCreateWindow)
4.1.3.4.2.3 使用EnvironmentElg对象构造SurfaceGL对象
4.1.3.4.2.4 将SurfaceGL对象和NativeWindowX11对象绑定
4.1.3.5 调用FlutterELinuxView::SetEngine将FlutterElinuxEngine设置到FlutterELinuxView对象中(双向绑定)
4.1.3.5.1 获取FlutterELinuxEngine中的FlutterDesktopPluginRegistrar对象
构造flutter::PluginRegistrar对象
4.1.3.5.1.1 使用FlutterDesktopPluginRegistrar中的FlutterDesktopMessenger
构造BinaryMessaengerImpl对象
4.1.3.5.1.2 获取FlutterDesktopPluginRegistrar中的FlutterELinuxTextureRegistrar对象,
并强制转换为FlutterDesktopTextureRegistrar(不可操作)
4.1.3.5.1.3 使用FlutterDesktopTextureRegistrar去构造TextureRegistrarImpl对象
4.1.3.5.2 取出flutter::PluginRegistrar对象中的BinaryMessengerImpl对象
4.1.3.5.3 使用BinaryMessengerImpl对象去构造flutter::KeyeventPlugin对象
4.1.3.5.3.1 构造中会初始化键盘输入上下文(xkb_context)
4.1.3.5.4 使用ELinuxWindowX11(父类为WindowBindingHandler)对象和BinaryMessengerImpl对象
去构造flutter::TextInputPlugin对象
4.1.3.5.4.1 构造中会使用messenger和plugin去
构造flutter::MethodChannel<rapidjson::Document>对象
4.1.3.5.4.2 设置MethodChannel的回调,回调中收到事件后
传给ELinuxWindowX11(::UpdateVirtualKeyboardStatus)
(事件从哪里来)
4.1.3.5.5 使用ELinuxWindowX11(父类为WindowBindingHandler)对象
和BinaryMessengerImpl对象去构造flutter::PlatformPlugin对象
(事件从哪里来)
4.1.3.5.5 使用ELinuxWindowX11(父类为WindowBindingHandler)对象
和BinaryMessengerImpl对象去构造flutter::MouseCursorPlugin对象
(事件从哪里来)
4.1.3.5.5 使用ELinuxWindowX11(父类为WindowBindingHandler)对象
和BinaryMessengerImpl对象去构造flutter::LifecyclePlugin对象
(事件从哪里来)
4.1.3.5.5 使用ELinuxWindowX11(父类为WindowBindingHandler)对象
和BinaryMessengerImpl对象去构造flutter::NavigationPlugin对象
(事件从哪里来)
4.1.3.5.5 使用ELinuxWindowX11(父类为WindowBindingHandler)对象
和BinaryMessengerImpl对象去构造flutter::PlatformViewsPlugin对象
(事件从哪里来)
4.1.3.6 调用FlutterELinuxEngine::RunWithEntrypoint运行引擎
4.1.3.6.1 调用FlutterProjectBundle::HasValidPaths检查路径是否有效
4.1.3.6.2 调用flutter_api的RunsAOTCompilesDartCode,应该是编译dart代码
4.1.3.6.3 调用FlutterProjectBundle::LoadAotData函数获取FlutterEngineAOTData对象
4.1.3.6.3.1 调用flutter_api的CreateAOTData构造FlutterEngineAOTData对象
(其内部将libapp.so映射出来,之后加载过程中解析libapp.so二进制文件的头,段表,以及记录.dynstr和.dynsym段位置,
然后读取段_kDartVmSnapshotData起始地址,保存到vm_data中
然后读取段_kDartVmSnapshotInstructions起始地址,保存到vm_instrs中
然后读取段_kDartIsolateSnapshotData起始地址,保存到isolate_data中
然后读取段_kDartIsolateSnapshotInstructions起始地址,保存到isolate_instrs中)
4.1.3.6.4 调用GetSwitchesFromEnvironment获取环境变量FLUTTER_ENGINE_SWITCH_${N}
然后将环境变量值加上前缀转换为--observatory-port=12345的形势
4.1.3.6.5 新建FlutterTaskRunnerDescription结构体对象
.struct_size = sizeof(FlutterTaskRunnerDescription)
.user_data = TaskRunner对象
// 判断是否是当前线程
.runs_task_on_current_thread_callback = [](void* user_data) -> bool {
return static_cast<TaskRunner*>(user_data)->RunsTasksOnCurrentThread();
};
// 抛出一个消息到主线程消息队列去执行
.post_task_callback = [](FlutterTask task,
uint64_t target_time_nanos,
void* user_data) -> void {
static_cast<TaskRunner*>(user_data)->PostFlutterTask(task, target_time_nanos);
};
4.1.3.6.6 新建FlutterCustomTaskRunners结构体对象
.struct_size = sizeof(FlutterCustomTaskRunners)
.platform_task_runner = FlutterTaskRunnerDescription对象
4.1.3.6.7 新建FlutterProjectArgs结构体对象
.struct_size = sizeof(FlutterCustomTaskRunners)
.assets_path = flutter_assets路径
.icu_data_path = icudtl.dat路径
// 引擎启动参数
.command_line_argc = 前面由环境变量生成的参数的个数
.command_line_argv = 前面由环境变量生成的参数
// dart脚本启动参数
.dart_entrypoint_arg = 前面由环境变量生成的参数的个数
.dart_entrypoint_argv = 前面由环境变量生成的参数
// 监听并处理flutter消息
.platform_message_callback = [](const FlutterPlatformMessage* engine_message,
void* user_data) -> void {
auto host = static_cast<FlutterELinuxEngine*>(user_data);
return host->HandlePlatformMessage(engine_message);
};
.custom_task_runners = FlutterCustomTaskRunners对象
.aot_data = FlutterEngineAOTData对象
// 指定dart脚本入口名, 为空默认main
.custom_dart_entrypoint = nullptr
// 日志消息处理
.log_message_callback = [](const char* tag, const char* message,void* user_data) {
};
4.1.3.6.8 调用GetRendererConfig构造FlutterRenderConfig对象
// opengl引擎
config.type = kOpenGL
config.open_gl.struct_size = sizeof(config.open_gl)
config.open_gl.make_current = [](void* user_data) -> bool {
auto host = static_cast<FlutterELinuxEngine*>(user_data);
if (!host->view()) {
return false;
}
return host->view()->MakeCurrent();
};
config.open_gl.clear_current = [](void* user_data) -> bool {
auto host = static_cast<FlutterELinuxEngine*>(user_data);
if (!host->view()) {
return false;
}
return host->view()->ClearCurrent();
};
config.open_gl.present = [](void* user_data) -> bool {
auto host = static_cast<FlutterELinuxEngine*>(user_data);
if (!host->view()) {
return false;
}
return host->view()->Present();
}
config.open_gl.fbo_callback = [](void* user_data) -> uint32_t {
auto host = static_cast<FlutterELinuxEngine*>(user_data);
if (!host->view()) {
return false;
}
return host->view()->GetOnscreenFBO();
};
config.open_gl.gl_proc_resolver = [](void *user_data,
const char* name) -> void* {
auto host = static_cast<FlutterELinuxEngine*>(user_data);
if (!host->view()) {
return nullptr;
}
return host->view()->ProcResolver(name);
};
config.open_gl.make_resource_current = [](void* user_data) -> bool {
auto host = static_cast<FlutterELinuxEngine*>(user_data);
if (!host->view()) {
return false;
}
return host->view()->MakeResourceCurrent();
};
config.open_gl.gl_external_texture_frame_callback = [](void* user_data,
int64_t texture_id, size_t width, size_t height, FlutterOpenGLTextture *texture) {
auto host = static_cast<FlutterELinuxEngine*>(user_data);
if (!host->texture_registrar()) {
return false;
}
return host->texture_registrar()->PopulateTexture(texture_id, width, height, texture);
};
config.open_gl.surface_transformation = [](void* user_data) {
auto host = static_cast<FlutterELinuxEngine*>(user_data);
return host->view()->GetRootSurfaceTransformation();
};
4.1.3.6.9 调用flutter_api->Run(),将FlutterEngine对象和FlutterRenderConfig对象对象作为参数传入
4.1.3.6.9.1 FlutterEngine对象传入后,flutter引擎会调用FlutterEngine::messenger()接口获取消息传递对象BinaryMessengerImpl
(BinaryMessengerImpl内部持有FlutterDesktopMessenger,而FlutterDesktopMessenger内部持有FlutterELinuxEngine)
4.1.3.6.9.2 flutter获取BinaryMessengerImpl后,会调用SetMeesageHandler接口,传递通道名以及消息传递对象BinaryMessageHandler过来
4.1.3.6.9.3 然后会通过BinaryMessengerImpl深处的FlutterELinuxEngine对象的IncomingMessageDispatcher对象的SetMessageCallback接口
4.1.3.6.9.4 将handler转换成FlutterDesktopMessageCallback对象保存起来,当flutter消息过来时触发回调,并处理消息
4.1.3.6.10 调用SendSystemSettings进行系统设置
4.1.3.6.9.1 获取所有支持的语言,并调用flutter_api的UpdateLocales,设置到引擎中
4.1.3.6.9.2 创建json的配置,调用BasicMessageChannel::Send发送配置
(发到flutter中,通道名为flutter/settings,
路线:BasicMessageChannel->BinaryMessengerImpl->FlutterDesktopMessengerSend->FlutterELinuxEngine::SendPlatformMessage)
4.2 调用FlutterWindow::Run()进入引擎的事件传递,分发,及处理
4.2.1 FlutterViewController对象->FlutterView::DispatchEvent()->FlutterELinuxView::DispatchEvent()->ELinuxWindowX11::DisplayEvent()
4.2.2 ELinuxWindowX11::DispatchEvent中将调用XNextEvent()获取用户输入
4.2.3 根据事件的不同类型调用FlutterELinuxView::OnKey()等等接口
4.2.4.1 首先调用KeyeventPlugin::OnKey()接口
4.2.4.1.1 通过构造KeyeventPlugin时初始化的BasicMessageChannel对象发送消息json格式的event事件
4.2.4.1.2 通过构造KeyeventPlugin时传入的BinaryMessengerImpl对象(flutter::PluginRegistrar构造内创建)去发送消息
4.2.4.1.3 调用FlutterDesktopMessengerSend接口去发送消息(第一个参数时FlutterELinuxEngine对象中的FlutterDeskTopMessenger对象)
4.2.4.1.4 通过FlutterDeskTopMessenger对象中的FlutterELinuxEngine对象的SendPlatformMessageResponse接口去发送
4.2.4.1.5 通过flutter_api->SendPlatformMessage去发送生成的PlatformMessage
(VSync是由窗口wayland发起的,x11没有发起vsync)