9#define RAPIDJSON_HAS_STDSTRING 1
35#include "rapidjson/stringbuffer.h"
36#include "rapidjson/writer.h"
37#include "third_party/dart/runtime/include/dart_tools_api.h"
38#include "third_party/skia/include/codec/SkBmpDecoder.h"
39#include "third_party/skia/include/codec/SkCodec.h"
40#include "third_party/skia/include/codec/SkGifDecoder.h"
41#include "third_party/skia/include/codec/SkIcoDecoder.h"
42#include "third_party/skia/include/codec/SkJpegDecoder.h"
43#include "third_party/skia/include/codec/SkPngDecoder.h"
44#include "third_party/skia/include/codec/SkWbmpDecoder.h"
45#include "third_party/skia/include/codec/SkWebpDecoder.h"
46#include "third_party/skia/include/core/SkGraphics.h"
58std::unique_ptr<Engine> CreateEngine(
66 std::unique_ptr<Animator> animator,
70 const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch,
71 const std::shared_future<impeller::RuntimeStageBackend>&
72 runtime_stage_backend) {
73 return std::make_unique<Engine>(delegate,
85 runtime_stage_backend);
88void RegisterCodecsWithSkia() {
93 SkCodecs::Register(SkPngDecoder::Decoder());
94 SkCodecs::Register(SkJpegDecoder::Decoder());
95 SkCodecs::Register(SkWebpDecoder::Decoder());
96 SkCodecs::Register(SkGifDecoder::Decoder());
97 SkCodecs::Register(SkBmpDecoder::Decoder());
98 SkCodecs::Register(SkWbmpDecoder::Decoder());
99 SkCodecs::Register(SkIcoDecoder::Decoder());
108void PerformInitializationTasks(
Settings& settings) {
116 static std::once_flag gShellSettingsInitialization = {};
117 std::call_once(gShellSettingsInitialization, [&settings] {
132 FML_DLOG(INFO) <<
"Skia deterministic rendering is enabled.";
134 RegisterCodecsWithSkia();
142 FML_DLOG(WARNING) <<
"Skipping ICU initialization in the shell.";
204std::pair<DartVMRef, fml::RefPtr<const DartSnapshot>>
215 if (!isolate_snapshot) {
216 isolate_snapshot = vm->GetVMData()->GetIsolateSnapshot();
218 return {std::move(vm), isolate_snapshot};
227 bool is_gpu_disabled) {
229 PerformInitializationTasks(settings);
234 auto resource_cache_limit_calculator =
235 std::make_shared<ResourceCacheLimitCalculator>(
238 return CreateWithSnapshot(platform_data,
242 resource_cache_limit_calculator,
245 std::move(isolate_snapshot),
246 on_create_platform_view,
247 on_create_rasterizer,
248 CreateEngine, is_gpu_disabled);
251std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
254 std::shared_ptr<ShellIOManager> parent_io_manager,
255 const std::shared_ptr<ResourceCacheLimitCalculator>&
256 resource_cache_limit_calculator,
264 bool is_gpu_disabled) {
266 FML_LOG(ERROR) <<
"Task runners to run the shell were invalid.";
270 auto shell = std::unique_ptr<Shell>(
271 new Shell(std::move(vm), task_runners, std::move(parent_merger),
272 resource_cache_limit_calculator, settings, is_gpu_disabled));
282 std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise;
283 auto rasterizer_future = rasterizer_promise.get_future();
284 std::promise<fml::TaskRunnerAffineWeakPtr<SnapshotDelegate>>
285 snapshot_delegate_promise;
286 auto snapshot_delegate_future = snapshot_delegate_promise.get_future();
288 std::promise<std::shared_ptr<impeller::Context>> impeller_context_promise;
289 auto impeller_context_future =
290 std::make_shared<impeller::ImpellerContextFuture>(
291 impeller_context_promise.get_future());
295 [&rasterizer_promise,
296 &snapshot_delegate_promise, impeller_context_future,
297 on_create_rasterizer,
298 shell = shell.get()]() {
299 TRACE_EVENT0(
"flutter",
"ShellSetupGPUSubsystem");
300 std::unique_ptr<Rasterizer> rasterizer(on_create_rasterizer(*shell));
301 rasterizer->SetImpellerContext(impeller_context_future);
302 snapshot_delegate_promise.set_value(rasterizer->GetSnapshotDelegate());
303 rasterizer_promise.set_value(std::move(rasterizer));
310 std::promise<impeller::RuntimeStageBackend> runtime_stage_backend;
311 std::shared_future<impeller::RuntimeStageBackend> runtime_stage_future =
312 runtime_stage_backend.get_future();
317 [impeller_context_promise = std::move(impeller_context_promise),
318 runtime_stage_backend = std::move(runtime_stage_backend),
319 platform_view_ptr]()
mutable {
320 TRACE_EVENT0(
"flutter",
"CreateImpellerContext");
321 platform_view_ptr->SetupImpellerContext();
322 std::shared_ptr<impeller::Context> impeller_context =
323 platform_view_ptr->GetImpellerContext();
324 if (impeller_context) {
325 runtime_stage_backend.set_value(
326 impeller_context->GetRuntimeStageBackend());
327 impeller_context_promise.set_value(impeller_context);
329 runtime_stage_backend.set_value(
330 impeller::RuntimeStageBackend::kSkSL);
331 impeller_context_promise.set_value(nullptr);
346 std::promise<std::shared_ptr<ShellIOManager>> io_manager_promise;
347 auto io_manager_future = io_manager_promise.get_future();
348 std::promise<fml::WeakPtr<ShellIOManager>> weak_io_manager_promise;
349 auto weak_io_manager_future = weak_io_manager_promise.get_future();
350 std::promise<fml::RefPtr<SkiaUnrefQueue>> unref_queue_promise;
351 auto unref_queue_future = unref_queue_promise.get_future();
352 auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner();
358 [&io_manager_promise,
359 &weak_io_manager_promise,
361 &unref_queue_promise,
364 is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch(),
366 impeller_context_future]() {
367 TRACE_EVENT0(
"flutter",
"ShellSetupIOSubsystem");
368 std::shared_ptr<ShellIOManager> io_manager;
369 if (parent_io_manager) {
370 io_manager = parent_io_manager;
372 io_manager = std::make_shared<ShellIOManager>(
374 is_backgrounded_sync_switch,
376 impeller_context_future,
380 weak_io_manager_promise.set_value(io_manager->GetWeakPtr());
381 unref_queue_promise.set_value(io_manager->GetSkiaUnrefQueue());
382 io_manager_promise.set_value(io_manager);
386 io_manager->GetImpellerContext();
387 sk_sp<GrDirectContext> resource_context =
388 platform_view_ptr->CreateResourceContext();
389 io_manager->NotifyResourceContextAvailable(resource_context);
397 std::promise<std::unique_ptr<Engine>> engine_promise;
398 auto engine_future = engine_promise.get_future();
400 shell->GetTaskRunners().GetUITaskRunner(),
405 isolate_snapshot = std::move(isolate_snapshot),
406 vsync_waiter = std::move(vsync_waiter),
407 &weak_io_manager_future,
408 &snapshot_delegate_future,
409 &runtime_stage_future,
411 &on_create_engine]()
mutable {
412 TRACE_EVENT0(
"flutter",
"ShellSetupUISubsystem");
413 const auto& task_runners = shell->GetTaskRunners();
417 auto animator = std::make_unique<Animator>(*shell, task_runners,
418 std::move(vsync_waiter));
420 engine_promise.set_value(
421 on_create_engine(*shell,
424 std::move(isolate_snapshot),
427 shell->GetSettings(),
429 weak_io_manager_future.get(),
430 unref_queue_future.get(),
431 snapshot_delegate_future.get(),
432 shell->is_gpu_disabled_sync_switch_,
433 runtime_stage_future));
438 rasterizer_future.get(),
439 io_manager_future.get())
447std::unique_ptr<Shell> Shell::CreateWithSnapshot(
448 const PlatformData& platform_data,
449 const TaskRunners& task_runners,
451 const std::shared_ptr<ShellIOManager>& parent_io_manager,
452 const std::shared_ptr<ResourceCacheLimitCalculator>&
453 resource_cache_limit_calculator,
457 const Shell::CreateCallback<PlatformView>& on_create_platform_view,
458 const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
459 const Shell::EngineCreateCallback& on_create_engine,
460 bool is_gpu_disabled) {
462 PerformInitializationTasks(settings);
466 const bool callbacks_valid =
467 on_create_platform_view && on_create_rasterizer && on_create_engine;
468 if (!task_runners.IsValid() || !callbacks_valid) {
473 std::unique_ptr<Shell> shell;
474 auto platform_task_runner = task_runners.GetPlatformTaskRunner();
476 platform_task_runner,
479 parent_thread_merger,
481 resource_cache_limit_calculator,
482 task_runners = task_runners,
483 platform_data = platform_data,
486 isolate_snapshot = std::move(isolate_snapshot),
487 on_create_platform_view = on_create_platform_view,
488 on_create_rasterizer = on_create_rasterizer,
489 on_create_engine = on_create_engine,
490 is_gpu_disabled]()
mutable {
491 shell = CreateShellOnPlatformThread(std::move(vm),
492 parent_thread_merger,
494 resource_cache_limit_calculator,
498 std::move(isolate_snapshot),
499 on_create_platform_view,
500 on_create_rasterizer,
509Shell::Shell(DartVMRef vm,
510 const TaskRunners& task_runners,
512 const std::shared_ptr<ResourceCacheLimitCalculator>&
513 resource_cache_limit_calculator,
514 const Settings& settings,
515 bool is_gpu_disabled)
517 parent_raster_thread_merger_(
std::move(parent_merger)),
518 resource_cache_limit_calculator_(resource_cache_limit_calculator),
521 is_gpu_disabled_sync_switch_(new
fml::SyncSwitch(is_gpu_disabled)),
522 weak_factory_gpu_(nullptr),
523 weak_factory_(this) {
524 FML_CHECK(!settings.enable_software_rendering || !settings.enable_impeller)
525 <<
"Software rendering is incompatible with Impeller.";
526 if (!settings.enable_impeller && settings.warn_on_impeller_opt_out) {
528 R
"warn([Action Required]: Impeller opt-out deprecated.
529 The application opted out of Impeller by either using the
530 `--no-enable-impeller` flag or the
531 `io.flutter.embedding.android.EnableImpeller` `AndroidManifest.xml` entry.
532 These options are going to go away in an upcoming Flutter release. Remove
533 the explicit opt-out. If you need to opt-out, please report a bug describing
536 https://github.com/flutter/flutter/issues/new?template=02_bug.yml
539 FML_CHECK(vm_) << "Must have access to VM to create a shell.";
543 display_manager_ = std::make_unique<DisplayManager>();
544 resource_cache_limit_calculator->AddResourceCacheLimitItem(
545 weak_factory_.GetWeakPtr());
552 this->weak_factory_gpu_ =
553 std::make_unique<fml::TaskRunnerAffineWeakPtrFactory<Shell>>(this);
560 std::bind(&Shell::OnServiceProtocolScreenshot,
this,
561 std::placeholders::_1, std::placeholders::_2)};
564 std::bind(&Shell::OnServiceProtocolScreenshotSKP,
this,
565 std::placeholders::_1, std::placeholders::_2)};
568 std::bind(&Shell::OnServiceProtocolRunInView,
this, std::placeholders::_1,
569 std::placeholders::_2)};
570 service_protocol_handlers_
573 std::bind(&Shell::OnServiceProtocolFlushUIThreadTasks,
this,
574 std::placeholders::_1, std::placeholders::_2)};
575 service_protocol_handlers_
578 std::bind(&Shell::OnServiceProtocolSetAssetBundlePath,
this,
579 std::placeholders::_1, std::placeholders::_2)};
580 service_protocol_handlers_
583 std::bind(&Shell::OnServiceProtocolGetDisplayRefreshRate,
this,
584 std::placeholders::_1, std::placeholders::_2)};
587 std::bind(&Shell::OnServiceProtocolGetSkSLs,
this, std::placeholders::_1,
588 std::placeholders::_2)};
589 service_protocol_handlers_
592 std::bind(&Shell::OnServiceProtocolEstimateRasterCacheMemory,
this,
593 std::placeholders::_1, std::placeholders::_2)};
596 std::bind(&Shell::OnServiceProtocolReloadAssetFonts,
this,
597 std::placeholders::_1, std::placeholders::_2)};
609 platform_latch, io_latch;
614 engine_->ShutdownPlatformIsolates();
615 platiso_latch.Signal();
617 platiso_latch.
Wait();
630 [
this, rasterizer = std::move(rasterizer_), &gpu_latch]()
mutable {
632 this->weak_factory_gpu_.reset();
641 &io_latch]()
mutable {
642 std::weak_ptr<ShellIOManager> weak_io_manager(io_manager);
647 if (platform_view && weak_io_manager.expired()) {
648 platform_view->ReleaseResourceContext();
661 &platform_latch]()
mutable {
662 platform_view.reset();
663 platform_latch.Signal();
665 platform_latch.
Wait();
672 auto platform_queue_id =
675 if (task_queues->Owns(platform_queue_id, ui_queue_id)) {
676 task_queues->Unmerge(platform_queue_id, ui_queue_id);
682 RunConfiguration run_configuration,
683 const std::string& initial_route,
684 const CreateCallback<PlatformView>& on_create_platform_view,
685 const CreateCallback<Rasterizer>& on_create_rasterizer)
const {
692 FML_LOG(ERROR) <<
"MergedPlatformUIThread::kMergeAfterLaunch does not "
698 bool is_gpu_disabled =
false;
701 .SetIfFalse([&is_gpu_disabled] { is_gpu_disabled =
false; })
702 .SetIfTrue([&is_gpu_disabled] { is_gpu_disabled =
true; }));
703 std::unique_ptr<Shell> result = CreateWithSnapshot(
704 PlatformData{}, task_runners_, rasterizer_->GetRasterThreadMerger(),
705 io_manager_, resource_cache_limit_calculator_,
GetSettings(), vm_,
706 vm_->
GetVMData()->GetIsolateSnapshot(), on_create_platform_view,
707 on_create_rasterizer,
708 [
engine = this->engine_.get(), initial_route](
709 Engine::Delegate& delegate,
712 const TaskRunners& task_runners,
const PlatformData& platform_data,
713 const Settings& settings, std::unique_ptr<Animator> animator,
717 const std::shared_ptr<fml::SyncSwitch>& is_gpu_disabled_sync_switch,
718 const std::shared_future<impeller::RuntimeStageBackend>&
719 runtime_stage_backend) {
720 return engine->Spawn(
727 std::move(snapshot_delegate),
728 is_gpu_disabled_sync_switch);
731 result->RunEngine(std::move(run_configuration));
743 ::Dart_NotifyLowMemory();
746 [rasterizer = rasterizer_->GetWeakPtr(), trace_id = trace_id]() {
748 rasterizer->NotifyLowMemoryWarning();
759 engine_->FlushMicrotaskQueue();
764 RunEngine(std::move(run_configuration),
nullptr);
768 RunConfiguration run_configuration,
772 if (!result_callback) {
775 platform_runner->PostTask(
776 [result_callback, run_result]() { result_callback(run_result); });
784 [run_configuration = std::move(run_configuration),
785 weak_engine = weak_engine_, result]()
mutable {
788 <<
"Could not launch engine with configuration - no engine.";
789 result(Engine::RunStatus::Failure);
792 auto run_result = weak_engine->Run(std::move(run_configuration));
794 FML_LOG(ERROR) <<
"Could not launch engine with configuration.";
808 switch (weak_engine_->GetUIIsolateLastError()) {
829 return weak_engine_->UIIsolateHasLivePorts();
840 return weak_engine_->UIIsolateHasPendingMicrotasks();
847bool Shell::Setup(std::unique_ptr<PlatformView>
platform_view,
848 std::unique_ptr<Engine>
engine,
849 std::unique_ptr<Rasterizer> rasterizer,
850 const std::shared_ptr<ShellIOManager>& io_manager) {
860 platform_message_handler_ = platform_view_->GetPlatformMessageHandler();
861 route_messages_through_platform_thread_.store(
true);
863 [
self = weak_factory_.GetWeakPtr()] {
865 self->route_messages_through_platform_thread_.store(false);
868 engine_ = std::move(
engine);
869 rasterizer_ = std::move(rasterizer);
873 auto view_embedder = platform_view_->CreateExternalViewEmbedder();
874 rasterizer_->SetExternalViewEmbedder(view_embedder);
875 rasterizer_->SetSnapshotSurfaceProducer(
876 platform_view_->CreateSnapshotSurfaceProducer());
880 weak_engine_ = engine_->GetWeakPtr();
881 weak_rasterizer_ = rasterizer_->GetWeakPtr();
882 weak_platform_view_ = platform_view_->GetWeakPtr();
886 FML_DCHECK(added) <<
"Failed to add the implicit view";
894 engine->SetupDefaultFontManager();
921 return task_runners_;
926 return parent_raster_thread_merger_;
931 return weak_rasterizer_;
941 return weak_platform_view_;
946 return io_manager_->GetWeakPtr();
954void Shell::OnPlatformViewCreated(std::unique_ptr<Surface> surface) {
955 TRACE_EVENT0(
"flutter",
"Shell::OnPlatformViewCreated");
968 rasterizer_->DisableThreadMergerIfNeeded();
980 const bool should_post_raster_task =
984 [&waiting_for_first_frame = waiting_for_first_frame_,
985 rasterizer = rasterizer_->GetWeakPtr(),
986 surface = std::move(surface)
991 rasterizer->EnableThreadMergerIfNeeded();
992 rasterizer->Setup(std::move(surface));
995 waiting_for_first_frame.store(
true);
998 auto ui_task = [
engine = engine_->GetWeakPtr()] {
1015 raster_task, should_post_raster_task, &latch] {
1016 if (io_manager && !io_manager->GetResourceContext()) {
1017 sk_sp<GrDirectContext> resource_context =
1019 io_manager->NotifyResourceContextAvailable(resource_context);
1027 if (should_post_raster_task) {
1036 if (!should_post_raster_task) {
1046void Shell::OnPlatformViewDestroyed() {
1047 TRACE_EVENT0(
"flutter",
"Shell::OnPlatformViewDestroyed");
1059 rasterizer_->DisableThreadMergerIfNeeded();
1071 auto io_task = [io_manager = io_manager_.get(), &latch]() {
1074 io_manager->GetIsGpuDisabledSyncSwitch()->Execute(
1076 [&] { io_manager->GetSkiaUnrefQueue()->Drain(); }));
1082 auto raster_task = [rasterizer = rasterizer_->GetWeakPtr(),
1089 rasterizer->EnableThreadMergerIfNeeded();
1090 rasterizer->Teardown();
1108 rasterizer_->TeardownExternalViewEmbedder();
1112void Shell::OnPlatformViewScheduleFrame() {
1113 TRACE_EVENT0(
"flutter",
"Shell::OnPlatformViewScheduleFrame");
1118 [
engine = engine_->GetWeakPtr()]() {
1120 engine->ScheduleFrame();
1126void Shell::OnPlatformViewSetViewportMetrics(int64_t
view_id,
1127 const ViewportMetrics& metrics) {
1131 if (!ValidateViewportMetrics(metrics)) {
1138 resource_cache_limit_ =
1139 metrics.physical_width * metrics.physical_height * 12 * 4;
1140 size_t resource_cache_max_bytes =
1141 resource_cache_limit_calculator_->GetResourceCacheMaxBytes();
1143 [rasterizer = rasterizer_->GetWeakPtr(), resource_cache_max_bytes] {
1145 rasterizer->SetResourceCacheMaxBytes(resource_cache_max_bytes, false);
1153 engine->SetViewportMetrics(view_id, metrics);
1158 std::scoped_lock<std::mutex> lock(resize_mutex_);
1160 expected_frame_constraints_[
view_id] =
1161 BoxConstraints(
Size(metrics.physical_min_width_constraint,
1162 metrics.physical_min_height_constraint),
1163 Size(metrics.physical_max_width_constraint,
1164 metrics.physical_max_height_constraint));
1165 device_pixel_ratio_ = metrics.device_pixel_ratio;
1170void Shell::OnPlatformViewDispatchPlatformMessage(
1171 std::unique_ptr<PlatformMessage>
message) {
1173#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
1175 std::scoped_lock lock(misbehaving_message_channels_mutex_);
1176 auto inserted = misbehaving_message_channels_.insert(
message->channel());
1177 if (inserted.second) {
1179 <<
"The '" <<
message->channel()
1180 <<
"' channel sent a message from native to Flutter on a "
1181 "non-platform thread. Platform channel messages must be sent on "
1182 "the platform thread. Failure to do so may result in data loss or "
1183 "crashes, and must be fixed in the plugin or application code "
1184 "creating that channel.\n"
1185 "See https://docs.flutter.dev/platform-integration/"
1186 "platform-channels#channels-and-platform-threading for more "
1199 engine->DispatchPlatformMessage(std::move(message));
1205void Shell::OnPlatformViewDispatchPointerDataPacket(
1206 std::unique_ptr<PointerDataPacket> packet) {
1208 "flutter",
"Shell::OnPlatformViewDispatchPointerDataPacket",
1209 1, &next_pointer_flow_id_);
1216 flow_id = next_pointer_flow_id_]()
mutable {
1218 engine->DispatchPointerDataPacket(std::move(packet), flow_id);
1221 next_pointer_flow_id_++;
1225void Shell::OnPlatformViewDispatchSemanticsAction(int64_t
view_id,
1237 engine->DispatchSemanticsAction(view_id, node_id, action,
1244void Shell::OnPlatformViewSetSemanticsEnabled(
bool enabled) {
1250 [
engine = engine_->GetWeakPtr(), enabled] {
1252 engine->SetSemanticsEnabled(enabled);
1258void Shell::OnPlatformViewSetAccessibilityFeatures(int32_t flags) {
1265 engine->SetAccessibilityFeatures(flags);
1271void Shell::OnPlatformViewRegisterTexture(
1272 std::shared_ptr<flutter::Texture>
texture) {
1277 [rasterizer = rasterizer_->GetWeakPtr(),
texture] {
1279 if (auto registry = rasterizer->GetTextureRegistry()) {
1280 registry->RegisterTexture(texture);
1287void Shell::OnPlatformViewUnregisterTexture(int64_t
texture_id) {
1292 [rasterizer = rasterizer_->GetWeakPtr(),
texture_id]() {
1294 if (auto registry = rasterizer->GetTextureRegistry()) {
1295 registry->UnregisterTexture(texture_id);
1302void Shell::OnPlatformViewMarkTextureFrameAvailable(int64_t
texture_id) {
1308 [rasterizer = rasterizer_->GetWeakPtr(),
texture_id]() {
1312 auto registry = rasterizer->GetTextureRegistry();
1324 texture->MarkNewFrameAvailable();
1329 [
engine = engine_->GetWeakPtr()]() {
1331 engine->ScheduleFrame(false);
1337void Shell::OnPlatformViewSetNextFrameCallback(
const fml::closure& closure) {
1342 [rasterizer = rasterizer_->GetWeakPtr(), closure = closure]() {
1344 rasterizer->SetNextFrameCallback(closure);
1350const Settings& Shell::OnPlatformViewGetSettings()
const {
1355void Shell::OnAnimatorBeginFrame(
fml::TimePoint frame_target_time,
1356 uint64_t frame_number) {
1362 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1363 latest_frame_target_time_.emplace(frame_target_time);
1366 engine_->BeginFrame(frame_target_time, frame_number);
1376 engine_->NotifyIdle(deadline);
1380void Shell::OnAnimatorUpdateLatestFrameTargetTime(
1386 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1387 if (!latest_frame_target_time_) {
1388 latest_frame_target_time_ = frame_target_time;
1389 }
else if (latest_frame_target_time_ < frame_target_time) {
1390 latest_frame_target_time_ = frame_target_time;
1396void Shell::OnAnimatorDraw(std::shared_ptr<FramePipeline> pipeline) {
1400 [&waiting_for_first_frame = waiting_for_first_frame_,
1401 &waiting_for_first_frame_condition = waiting_for_first_frame_condition_,
1402 rasterizer = rasterizer_->GetWeakPtr(),
1403 weak_pipeline = std::weak_ptr<FramePipeline>(pipeline)]()
mutable {
1405 std::shared_ptr<FramePipeline> pipeline = weak_pipeline.lock();
1407 rasterizer->Draw(pipeline);
1410 if (waiting_for_first_frame.load()) {
1411 waiting_for_first_frame.store(false);
1412 waiting_for_first_frame_condition.notify_all();
1419void Shell::OnAnimatorDrawLastLayerTrees(
1420 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) {
1424 [rasterizer = rasterizer_->GetWeakPtr(),
1425 frame_timings_recorder = std::move(frame_timings_recorder)]()
mutable {
1427 rasterizer->DrawLastLayerTrees(std::move(frame_timings_recorder));
1435void Shell::OnEngineUpdateSemantics(int64_t
view_id,
1443 [
view = platform_view_->GetWeakPtr(), update = std::move(update),
1446 view->UpdateSemantics(view_id, update, actions);
1452void Shell::OnEngineSetApplicationLocale(std::string locale) {
1458 [
view = platform_view_->GetWeakPtr(), locale_holder = std::move(locale)] {
1460 view->SetApplicationLocale(locale_holder);
1466void Shell::OnEngineSetSemanticsTreeEnabled(
bool enabled) {
1472 [
view = platform_view_->GetWeakPtr(), enabled] {
1474 view->SetSemanticsTreeEnabled(enabled);
1480void Shell::OnEngineHandlePlatformMessage(
1481 std::unique_ptr<PlatformMessage>
message) {
1486 HandleEngineSkiaMessage(std::move(
message));
1490 if (platform_message_handler_) {
1491 if (route_messages_through_platform_thread_ &&
1492 !platform_message_handler_
1493 ->DoesHandlePlatformMessageOnPlatformThread()) {
1511 [weak_platform_message_handler =
1512 std::weak_ptr<PlatformMessageHandler>(platform_message_handler_),
1514 ui_task_runner->PostTask(
1517 auto platform_message_handler =
1518 weak_platform_message_handler.lock();
1519 if (platform_message_handler) {
1520 platform_message_handler->HandlePlatformMessage(
1526 platform_message_handler_->HandlePlatformMessage(std::move(
message));
1533 view->HandlePlatformMessage(std::move(message));
1539void Shell::OnEngineChannelUpdate(std::string
name,
bool listening) {
1543 [
view = platform_view_->GetWeakPtr(),
name = std::move(
name), listening] {
1545 view->SendChannelUpdate(name, listening);
1550void Shell::HandleEngineSkiaMessage(std::unique_ptr<PlatformMessage>
message) {
1553 rapidjson::Document document;
1554 document.Parse(
reinterpret_cast<const char*
>(
data.GetMapping()),
1556 if (document.HasParseError() || !document.IsObject()) {
1559 auto root = document.GetObject();
1560 auto method = root.FindMember(
"method");
1561 if (method->value !=
"Skia.setResourceCacheMaxBytes") {
1564 auto args = root.FindMember(
"args");
1565 if (
args == root.MemberEnd() || !
args->value.IsInt()) {
1570 [rasterizer = rasterizer_->GetWeakPtr(), max_bytes =
args->value.GetInt(),
1571 response =
message->response()] {
1573 rasterizer->SetResourceCacheMaxBytes(static_cast<size_t>(max_bytes),
1579 std::vector<uint8_t>
data = {
'[',
't',
'r',
'u',
'e',
']'};
1581 std::make_unique<fml::DataMapping>(std::move(
data)));
1587void Shell::OnPreEngineRestart() {
1594 [
view = platform_view_->GetWeakPtr(), &latch]() {
1596 view->OnPreEngineRestart();
1606void Shell::OnRootIsolateCreated() {
1607 if (is_added_to_service_protocol_) {
1610 auto description = GetServiceProtocolDescription();
1613 [
self = weak_factory_.GetWeakPtr(),
1614 description = std::move(description)]() {
1616 self->vm_->GetServiceProtocol()->AddHandler(self.get(), description);
1619 is_added_to_service_protocol_ =
true;
1623void Shell::UpdateIsolateDescription(
const std::string isolate_name,
1624 int64_t isolate_port) {
1625 Handler::Description description(isolate_port, isolate_name);
1629void Shell::SetNeedsReportTimings(
bool value) {
1630 needs_report_timings_ =
value;
1634std::unique_ptr<std::vector<std::string>> Shell::ComputePlatformResolvedLocale(
1635 const std::vector<std::string>& supported_locale_data) {
1636 return platform_view_->ComputePlatformResolvedLocales(supported_locale_data);
1639void Shell::LoadDartDeferredLibrary(
1640 intptr_t loading_unit_id,
1641 std::unique_ptr<const fml::Mapping> snapshot_data,
1642 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
1644 [
engine = engine_->GetWeakPtr(), loading_unit_id,
1645 data = std::move(snapshot_data),
1646 instructions = std::move(snapshot_instructions)]()
mutable {
1648 engine->LoadDartDeferredLibrary(loading_unit_id, std::move(data),
1649 std::move(instructions));
1654void Shell::LoadDartDeferredLibraryError(intptr_t loading_unit_id,
1655 const std::string error_message,
1659 [
engine = weak_engine_, loading_unit_id, error_message, transient] {
1661 engine->LoadDartDeferredLibraryError(loading_unit_id, error_message,
1667void Shell::UpdateAssetResolverByType(
1668 std::unique_ptr<AssetResolver> updated_asset_resolver,
1674 asset_resolver = std::move(updated_asset_resolver)]()
mutable {
1676 engine->GetAssetManager()->UpdateResolverByType(
1677 std::move(asset_resolver), type);
1683void Shell::RequestDartDeferredLibrary(intptr_t loading_unit_id) {
1685 [
view = platform_view_->GetWeakPtr(), loading_unit_id] {
1687 view->RequestDartDeferredLibrary(loading_unit_id);
1693double Shell::GetScaledFontSize(
double unscaled_font_size,
1694 int configuration_id)
const {
1695 return platform_view_->GetScaledFontSize(unscaled_font_size,
1699void Shell::RequestViewFocusChange(
const ViewFocusChangeRequest& request) {
1704 [
view = platform_view_->GetWeakPtr(), request] {
1706 view->RequestViewFocusChange(request);
1711void Shell::ReportTimings() {
1715 auto timings = std::move(unreported_timings_);
1716 unreported_timings_ = {};
1719 engine->ReportTimings(timings);
1724size_t Shell::UnreportedFramesCount()
const {
1731void Shell::OnFrameRasterized(
const FrameTiming& timing) {
1741 if (!needs_report_timings_) {
1745 size_t old_count = unreported_timings_.size();
1747 for (
auto phase : FrameTiming::kPhases) {
1748 unreported_timings_.push_back(
1749 timing.Get(phase).ToEpochDelta().ToMicroseconds());
1751 unreported_timings_.push_back(timing.GetLayerCacheCount());
1752 unreported_timings_.push_back(timing.GetLayerCacheBytes());
1753 unreported_timings_.push_back(timing.GetPictureCacheCount());
1754 unreported_timings_.push_back(timing.GetPictureCacheBytes());
1755 unreported_timings_.push_back(timing.GetFrameNumber());
1771 if (!first_frame_rasterized_ || UnreportedFramesCount() >= 100) {
1772 first_frame_rasterized_ =
true;
1774 }
else if (!frame_timings_report_scheduled_) {
1776 constexpr int kBatchTimeInMilliseconds = 1000;
1778 constexpr int kBatchTimeInMilliseconds = 100;
1784 frame_timings_report_scheduled_ =
true;
1786 [
self = weak_factory_gpu_->GetWeakPtr()]() {
1790 self->frame_timings_report_scheduled_ =
false;
1791 if (
self->UnreportedFramesCount() > 0) {
1792 self->ReportTimings();
1800 if (cached_display_refresh_rate_.has_value()) {
1801 return cached_display_refresh_rate_.value();
1803 double display_refresh_rate = display_manager_->GetMainDisplayRefreshRate();
1804 if (display_refresh_rate > 0) {
1805 cached_display_refresh_rate_ =
1814 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1815 FML_CHECK(latest_frame_target_time_.has_value())
1816 <<
"GetLatestFrameTargetTime called before OnAnimatorBeginFrame";
1819 return latest_frame_target_time_.value();
1823bool Shell::ShouldDiscardLayerTree(int64_t
view_id,
1825 std::scoped_lock<std::mutex> lock(resize_mutex_);
1826 auto expected_frame_constraints = ExpectedFrameConstraints(
view_id);
1827 return !expected_frame_constraints.IsSatisfiedBy(
1833 std::string_view method)
const {
1835 auto found = service_protocol_handlers_.find(method);
1836 if (found != service_protocol_handlers_.end()) {
1837 return found->second.first;
1843bool Shell::HandleServiceProtocolMessage(
1844 std::string_view method,
1845 const ServiceProtocolMap&
params,
1846 rapidjson::Document* response) {
1847 auto found = service_protocol_handlers_.find(method);
1848 if (found != service_protocol_handlers_.end()) {
1849 return found->second.second(
params, response);
1855ServiceProtocol::Handler::Description Shell::GetServiceProtocolDescription()
1859 if (!weak_engine_) {
1864 weak_engine_->GetUIIsolateMainPort(),
1865 weak_engine_->GetUIIsolateName(),
1870 std::string error_details) {
1871 auto& allocator = response->GetAllocator();
1872 response->SetObject();
1873 const int64_t kInvalidParams = -32602;
1874 response->AddMember(
"code", kInvalidParams, allocator);
1875 response->AddMember(
"message",
"Invalid params", allocator);
1877 rapidjson::Value details(rapidjson::kObjectType);
1878 details.AddMember(
"details", std::move(error_details), allocator);
1879 response->AddMember(
"data", details, allocator);
1885 auto& allocator = response->GetAllocator();
1886 response->SetObject();
1887 const int64_t kJsonServerError = -32000;
1888 response->AddMember(
"code", kJsonServerError, allocator);
1889 response->AddMember(
"message", std::move(
message), allocator);
1893bool Shell::OnServiceProtocolScreenshot(
1895 rapidjson::Document* response) {
1897 auto screenshot = rasterizer_->ScreenshotLastLayerTree(
1899 if (screenshot.data) {
1900 response->SetObject();
1901 auto& allocator = response->GetAllocator();
1902 response->AddMember(
"type",
"Screenshot", allocator);
1903 rapidjson::Value
image;
1904 image.SetString(
static_cast<const char*
>(screenshot.data->data()),
1905 screenshot.data->size(), allocator);
1906 response->AddMember(
"screenshot",
image, allocator);
1914bool Shell::OnServiceProtocolScreenshotSKP(
1916 rapidjson::Document* response) {
1920 response,
"Cannot capture SKP screenshot with Impeller enabled.");
1923 auto screenshot = rasterizer_->ScreenshotLastLayerTree(
1925 if (screenshot.data) {
1926 response->SetObject();
1927 auto& allocator = response->GetAllocator();
1928 response->AddMember(
"type",
"ScreenshotSkp", allocator);
1929 rapidjson::Value skp;
1930 skp.SetString(
static_cast<const char*
>(screenshot.data->data()),
1931 screenshot.data->size(), allocator);
1932 response->AddMember(
"skp", skp, allocator);
1940bool Shell::OnServiceProtocolRunInView(
1942 rapidjson::Document* response) {
1945 if (
params.count(
"mainScript") == 0) {
1947 "'mainScript' parameter is missing.");
1951 if (
params.count(
"assetDirectory") == 0) {
1953 "'assetDirectory' parameter is missing.");
1957 std::string main_script_path =
1959 std::string asset_directory_path =
1962 auto main_script_file_mapping =
1967 std::move(main_script_file_mapping));
1969 RunConfiguration configuration(std::move(isolate_configuration));
1971 configuration.SetEntrypointAndLibrary(engine_->GetLastEntrypoint(),
1972 engine_->GetLastEntrypointLibrary());
1973 configuration.SetEntrypointArgs(engine_->GetLastEntrypointArgs());
1975 configuration.SetEngineId(engine_->GetLastEngineId());
1977 configuration.AddAssetResolver(std::make_unique<DirectoryAssetBundle>(
1984 auto old_asset_manager = engine_->GetAssetManager();
1985 if (old_asset_manager !=
nullptr) {
1986 for (
auto& old_resolver : old_asset_manager->TakeResolvers()) {
1987 if (old_resolver->IsValidAfterAssetManagerChange()) {
1988 configuration.AddAssetResolver(std::move(old_resolver));
1993 auto& allocator = response->GetAllocator();
1994 response->SetObject();
1995 if (engine_->Restart(std::move(configuration))) {
1996 response->AddMember(
"type",
"Success", allocator);
1997 auto new_description = GetServiceProtocolDescription();
1998 rapidjson::Value
view(rapidjson::kObjectType);
1999 new_description.Write(
this,
view, allocator);
2000 response->AddMember(
"view",
view, allocator);
2003 FML_DLOG(ERROR) <<
"Could not run configuration in engine.";
2005 "Could not run configuration in engine.");
2014bool Shell::OnServiceProtocolFlushUIThreadTasks(
2016 rapidjson::Document* response) {
2024 response->SetObject();
2025 response->AddMember(
"type",
"Success", response->GetAllocator());
2029bool Shell::OnServiceProtocolGetDisplayRefreshRate(
2031 rapidjson::Document* response) {
2033 response->SetObject();
2034 response->AddMember(
"type",
"DisplayRefreshRate", response->GetAllocator());
2035 response->AddMember(
"fps", display_manager_->GetMainDisplayRefreshRate(),
2036 response->GetAllocator());
2041 return display_manager_->GetMainDisplayRefreshRate();
2051 [
engine = engine_->GetWeakPtr(), factory = std::move(factory),
2054 engine->GetImageGeneratorRegistry()->AddFactory(factory, priority);
2059bool Shell::OnServiceProtocolGetSkSLs(
2061 rapidjson::Document* response) {
2063 response->SetObject();
2064 response->AddMember(
"type",
"GetSkSLs", response->GetAllocator());
2066 rapidjson::Value shaders_json(rapidjson::kObjectType);
2069 std::vector<PersistentCache::SkSLCache> sksls = persistent_cache->LoadSkSLs();
2070 for (
const auto& sksl : sksls) {
2072 sk_sp<SkData> b64_data = SkData::MakeUninitialized(b64_size + 1);
2073 char* b64_char =
static_cast<char*
>(b64_data->writable_data());
2074 Base64::Encode(sksl.value->data(), sksl.value->size(), b64_char);
2075 b64_char[b64_size] = 0;
2076 rapidjson::Value shader_value(b64_char, response->GetAllocator());
2077 std::string_view key_view(
reinterpret_cast<const char*
>(sksl.key->data()),
2080 if (!encode_result.first) {
2083 rapidjson::Value shader_key(encode_result.second, response->GetAllocator());
2084 shaders_json.AddMember(shader_key, shader_value, response->GetAllocator());
2087 response->AddMember(
"SkSLs", shaders_json, response->GetAllocator());
2091bool Shell::OnServiceProtocolEstimateRasterCacheMemory(
2093 rapidjson::Document* response) {
2096 uint64_t layer_cache_byte_size = 0u;
2097 uint64_t picture_cache_byte_size = 0u;
2100 const auto& raster_cache = rasterizer_->compositor_context()->raster_cache();
2101 layer_cache_byte_size = raster_cache.EstimateLayerCacheByteSize();
2102 picture_cache_byte_size = raster_cache.EstimatePictureCacheByteSize();
2105 response->SetObject();
2106 response->AddMember(
"type",
"EstimateRasterCacheMemory",
2107 response->GetAllocator());
2108 response->AddMember<uint64_t>(
"layerBytes", layer_cache_byte_size,
2109 response->GetAllocator());
2110 response->AddMember<uint64_t>(
"pictureBytes", picture_cache_byte_size,
2111 response->GetAllocator());
2116bool Shell::OnServiceProtocolSetAssetBundlePath(
2118 rapidjson::Document* response) {
2121 if (
params.count(
"assetDirectory") == 0) {
2123 "'assetDirectory' parameter is missing.");
2127 auto& allocator = response->GetAllocator();
2128 response->SetObject();
2130 auto asset_manager = std::make_shared<AssetManager>();
2132 if (!asset_manager->PushFront(std::make_unique<DirectoryAssetBundle>(
2137 FML_DLOG(ERROR) <<
"Could not update asset directory.";
2144 auto old_asset_manager = engine_->GetAssetManager();
2145 if (old_asset_manager !=
nullptr) {
2146 for (
auto& old_resolver : old_asset_manager->TakeResolvers()) {
2147 if (old_resolver->IsValidAfterAssetManagerChange()) {
2148 asset_manager->PushBack(std::move(old_resolver));
2153 if (engine_->UpdateAssetManager(asset_manager)) {
2154 response->AddMember(
"type",
"Success", allocator);
2155 auto new_description = GetServiceProtocolDescription();
2156 rapidjson::Value
view(rapidjson::kObjectType);
2157 new_description.Write(
this,
view, allocator);
2158 response->AddMember(
"view",
view, allocator);
2161 FML_DLOG(ERROR) <<
"Could not update asset directory.";
2170void Shell::SendFontChangeNotification() {
2173 rapidjson::Document document;
2174 document.SetObject();
2175 auto& allocator = document.GetAllocator();
2176 rapidjson::Value message_value;
2178 document.AddMember(
kTypeKey, message_value, allocator);
2180 rapidjson::StringBuffer
buffer;
2181 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
2182 document.Accept(writer);
2184 std::unique_ptr<PlatformMessage> fontsChangeMessage =
2185 std::make_unique<flutter::PlatformMessage>(
2188 OnPlatformViewDispatchPlatformMessage(std::move(fontsChangeMessage));
2191bool Shell::OnServiceProtocolReloadAssetFonts(
2193 rapidjson::Document* response) {
2198 engine_->GetFontCollection().RegisterFonts(engine_->GetAssetManager());
2199 engine_->GetFontCollection().GetFontCollection()->ClearFontFamilyCache();
2200 SendFontChangeNotification();
2202 auto& allocator = response->GetAllocator();
2203 response->SetObject();
2204 response->AddMember(
"type",
"Success", allocator);
2209void Shell::OnPlatformViewAddView(int64_t
view_id,
2210 const ViewportMetrics& viewport_metrics,
2216 <<
"Unexpected request to add the implicit view #"
2226 engine->AddView(view_id, viewport_metrics, callback);
2231void Shell::OnPlatformViewRemoveView(int64_t
view_id,
2237 <<
"Unexpected request to remove the implicit view #"
2240 std::scoped_lock<std::mutex> lock(resize_mutex_);
2241 expected_frame_constraints_.erase(
view_id);
2245 [&task_runners = task_runners_,
2246 engine = engine_->GetWeakPtr(),
2247 rasterizer = rasterizer_->GetWeakPtr(),
2251 bool removed = false;
2253 removed = engine->RemoveView(view_id);
2255 task_runners.GetRasterTaskRunner()->
PostTask(
2258 rasterizer->CollectView(view_id);
2268void Shell::OnPlatformViewSendViewFocusEvent(
const ViewFocusEvent& event) {
2269 TRACE_EVENT0(
"flutter",
"Shell:: OnPlatformViewSendViewFocusEvent");
2275 [
engine = engine_->GetWeakPtr(), event = event] {
2277 engine->SendViewFocusEvent(event);
2284 bool base64_encode) {
2286 switch (screenshot_type) {
2289 <<
"Impeller backend cannot produce ScreenshotType::SkiaPicture.";
2299 Rasterizer::Screenshot screenshot;
2308 screenshot = rasterizer->ScreenshotLastLayerTree(screenshot_type,
2322 "WaitForFirstFrame called from thread that can't wait "
2323 "because it is responsible for generating the frame.");
2327 auto now = std::chrono::steady_clock::now();
2328 auto max_duration = std::chrono::steady_clock::time_point::max() - now;
2329 auto desired_duration = std::chrono::milliseconds(timeout.
ToMilliseconds());
2331 now + (desired_duration > max_duration ? max_duration : desired_duration);
2333 std::unique_lock<std::mutex> lock(waiting_for_first_frame_mutex_);
2334 bool success = waiting_for_first_frame_condition_.wait_until(
2335 lock, duration, [&waiting_for_first_frame = waiting_for_first_frame_] {
2336 return !waiting_for_first_frame.load();
2352 engine_->SetupDefaultFontManager();
2353 engine_->GetFontCollection().GetFontCollection()->ClearFontFamilyCache();
2356 SendFontChangeNotification();
2362 return is_gpu_disabled_sync_switch_;
2367 switch (availability) {
2369 is_gpu_disabled_sync_switch_->SetSwitch(
false);
2375 [io_manager = io_manager_.get(), &latch]() {
2376 io_manager->GetSkiaUnrefQueue()->Drain();
2383 is_gpu_disabled_sync_switch_->SetSwitch(
true);
2394 std::vector<DisplayData> display_data;
2395 display_data.reserve(
displays.size());
2396 for (
const auto& display :
displays) {
2397 display_data.push_back(display->GetDisplayData());
2400 [
engine = engine_->GetWeakPtr(),
2401 display_data = std::move(display_data)]() {
2403 engine->SetDisplays(display_data);
2407 display_manager_->HandleDisplayUpdates(std::move(
displays));
2414const std::shared_ptr<PlatformMessageHandler>&
2416 return platform_message_handler_;
2423 return engine_->GetVsyncWaiter();
2426const std::shared_ptr<fml::ConcurrentTaskRunner>
2435BoxConstraints Shell::ExpectedFrameConstraints(int64_t
view_id) {
2436 auto found = expected_frame_constraints_.find(
view_id);
2438 if (found == expected_frame_constraints_.end()) {
2442 return found->second;
AssetResolverType
Identifies the type of AssetResolver an instance is.
static fml::RefPtr< const DartSnapshot > VMSnapshotFromSettings(const Settings &settings)
From the fields present in the given settings object, infer the core snapshot.
static fml::RefPtr< const DartSnapshot > IsolateSnapshotFromSettings(const Settings &settings)
From the fields present in the given settings object, infer the isolate snapshot.
Describes a running instance of the Dart VM. There may only be one running instance of the Dart VM in...
std::shared_ptr< const DartVMData > GetVMData() const
The VM and isolate snapshots used by this running Dart VM instance.
std::shared_ptr< fml::ConcurrentTaskRunner > GetConcurrentWorkerTaskRunner() const
The task runner whose tasks may be executed concurrently on a pool of worker threads....
std::shared_ptr< ServiceProtocol > GetServiceProtocol() const
The service protocol instance associated with this running Dart VM instance. This object manages nati...
static DartVMRef Create(const Settings &settings, fml::RefPtr< const DartSnapshot > vm_snapshot=nullptr, fml::RefPtr< const DartSnapshot > isolate_snapshot=nullptr)
While the engine operates entirely on the UI task runner, it needs the capabilities of the other comp...
RunStatus
Indicates the result of the call to Engine::Run.
static constexpr int kStatisticsCount
static std::unique_ptr< IsolateConfiguration > CreateForKernel(std::unique_ptr< const fml::Mapping > kernel)
Creates a JIT isolate configuration using the specified snapshot. This is a convenience method for th...
const DlISize & frame_size() const
void RemoveWorkerTaskRunner(const fml::RefPtr< fml::TaskRunner > &task_runner)
static PersistentCache * GetCacheForProcess()
static void SetCacheSkSL(bool value)
void SetIsDumpingSkp(bool value)
void AddWorkerTaskRunner(const fml::RefPtr< fml::TaskRunner > &task_runner)
ScreenshotType
The type of the screenshot to obtain of the previously rendered layer tree.
std::map< std::string_view, std::string_view > ServiceProtocolMap
static const std::string_view kSetAssetBundlePathExtensionName
static const std::string_view kReloadAssetFonts
static const std::string_view kScreenshotSkpExtensionName
static const std::string_view kScreenshotExtensionName
static const std::string_view kGetDisplayRefreshRateExtensionName
static const std::string_view kRunInViewExtensionName
static const std::string_view kEstimateRasterCacheMemoryExtensionName
static const std::string_view kGetSkSLsExtensionName
static const std::string_view kFlushUIThreadTasksExtensionName
DartVM * GetDartVM()
Get a pointer to the Dart VM used by this running shell instance.
std::function< std::unique_ptr< Engine >(Engine::Delegate &delegate, const PointerDataDispatcherMaker &dispatcher_maker, DartVM &vm, fml::RefPtr< const DartSnapshot > isolate_snapshot, TaskRunners task_runners, const PlatformData &platform_data, Settings settings, std::unique_ptr< Animator > animator, fml::WeakPtr< IOManager > io_manager, fml::RefPtr< SkiaUnrefQueue > unref_queue, fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate, const std::shared_ptr< fml::SyncSwitch > &gpu_disabled_switch, const std::shared_future< impeller::RuntimeStageBackend > &runtime_stage_backend)> EngineCreateCallback
std::optional< DartErrorCode > GetUIIsolateLastError() const
Used by embedders to get the last error from the Dart UI Isolate, if one exists.
static std::unique_ptr< Shell > Create(const PlatformData &platform_data, const TaskRunners &task_runners, Settings settings, const CreateCallback< PlatformView > &on_create_platform_view, const CreateCallback< Rasterizer > &on_create_rasterizer, bool is_gpu_disabled=false)
Creates a shell instance using the provided settings. The callbacks to create the various shell subco...
void FlushMicrotaskQueue() const
Used by embedders to flush the microtask queue. Required when running with merged platform and UI thr...
fml::TaskRunnerAffineWeakPtr< Engine > GetEngine()
Engines may only be accessed on the UI thread. This method is deprecated, and implementers should ins...
bool EngineHasLivePorts() const
Used by embedders to check if the Engine is running and has any live ports remaining....
~Shell()
Destroys the shell. This is a synchronous operation and synchronous barrier blocks are introduced on ...
Rasterizer::Screenshot Screenshot(Rasterizer::ScreenshotType type, bool base64_encode)
Captures a screenshot and optionally Base64 encodes the data of the last layer tree rendered by the r...
static std::pair< DartVMRef, fml::RefPtr< const DartSnapshot > > InferVmInitDataFromSettings(Settings &settings)
fml::WeakPtr< ShellIOManager > GetIOManager()
The IO Manager may only be accessed on the IO task runner.
fml::TaskRunnerAffineWeakPtr< Rasterizer > GetRasterizer() const
Rasterizers may only be accessed on the raster task runner.
void RunEngine(RunConfiguration run_configuration)
Starts an isolate for the given RunConfiguration.
std::unique_ptr< Shell > Spawn(RunConfiguration run_configuration, const std::string &initial_route, const CreateCallback< PlatformView > &on_create_platform_view, const CreateCallback< Rasterizer > &on_create_rasterizer) const
Creates one Shell from another Shell where the created Shell takes the opportunity to share any inter...
const std::weak_ptr< VsyncWaiter > GetVsyncWaiter() const
const std::shared_ptr< PlatformMessageHandler > & GetPlatformMessageHandler() const override
Returns the delegate object that handles PlatformMessage's from Flutter to the host platform (and its...
const std::shared_ptr< fml::ConcurrentTaskRunner > GetConcurrentWorkerTaskRunner() const
void NotifyLowMemoryWarning() const
Used by embedders to notify that there is a low memory warning. The shell will attempt to purge cache...
bool EngineHasPendingMicrotasks() const
Used by embedders to check if the Engine is running and has any microtasks that have been queued but ...
const Settings & GetSettings() const override
fml::Status WaitForFirstFrame(fml::TimeDelta timeout)
Pauses the calling thread until the first frame is presented.
void OnDisplayUpdates(std::vector< std::unique_ptr< Display > > displays)
Notifies the display manager of the updates.
const TaskRunners & GetTaskRunners() const override
If callers wish to interact directly with any shell subcomponents, they must (on the platform thread)...
std::shared_ptr< const fml::SyncSwitch > GetIsGpuDisabledSyncSwitch() const override
Accessor for the disable GPU SyncSwitch.
void SetGpuAvailability(GpuAvailability availability)
Marks the GPU as available or unavailable.
void RegisterImageDecoder(ImageGeneratorFactory factory, int32_t priority)
Install a new factory that can match against and decode image data.
const fml::RefPtr< fml::RasterThreadMerger > GetParentRasterThreadMerger() const override
Getting the raster thread merger from parent shell, it can be a null RefPtr when it's a root Shell or...
std::function< std::unique_ptr< T >(Shell &)> CreateCallback
bool IsSetup() const
Used by embedders to check if all shell subcomponents are initialized. It is the embedder's responsib...
double GetMainDisplayRefreshRate()
Queries the DisplayManager for the main display refresh rate.
bool ReloadSystemFonts()
Used by embedders to reload the system fonts in FontCollection. It also clears the cached font famili...
fml::WeakPtr< PlatformView > GetPlatformView()
Platform views may only be accessed on the platform task runner.
fml::RefPtr< fml::TaskRunner > GetRasterTaskRunner() const
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
fml::RefPtr< fml::TaskRunner > GetIOTaskRunner() const
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
A Mapping like NonOwnedMapping, but uses Free as its release proc.
static MallocMapping Copy(const T *begin, const T *end)
static MessageLoopTaskQueues * GetInstance()
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
static void RunNowAndFlushMessages(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
virtual void PostTask(const fml::closure &task) override
virtual bool RunsTasksOnCurrentThread()
virtual TaskQueueId GetTaskQueueId()
virtual void PostDelayedTask(const fml::closure &task, fml::TimeDelta delay)
constexpr int64_t ToMilliseconds() const
static constexpr TimeDelta FromMilliseconds(int64_t millis)
const EmbeddedViewParams * params
FlutterVulkanImage * image
TaskRunners task_runners_
fml::WeakPtr< IOManager > io_manager_
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS GBytes * message
G_BEGIN_DECLS FlutterViewId view_id
FlutterDesktopBinaryReply callback
#define FML_DLOG(severity)
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
@ CompilationError
The Dart error code for a compilation error.
@ ApiError
The Dart error code for an API error.
@ NoError
No error has occurred.
@ UnknownError
The Dart error code for an unknown error.
constexpr int64_t kFlutterImplicitViewId
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
static void ServiceProtocolFailureError(rapidjson::Document *response, std::string message)
std::function< std::shared_ptr< ImageGenerator >(sk_sp< SkData > buffer)> ImageGeneratorFactory
ImageGeneratorFactory is the top level primitive for specifying an image decoder in Flutter....
std::unordered_map< int32_t, CustomAccessibilityAction > CustomAccessibilityActionUpdates
void InitSkiaEventTracer(bool enabled, const std::optional< std::vector< std::string > > &allowlist)
std::function< std::unique_ptr< PointerDataDispatcher >(PointerDataDispatcher::Delegate &)> PointerDataDispatcherMaker
Signature for constructing PointerDataDispatcher.
DEF_SWITCHES_START aot vmservice shared library name
constexpr char kFontChange[]
static void ServiceProtocolParameterError(rapidjson::Document *response, std::string error_details)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
constexpr char kTypeKey[]
constexpr char kSystemChannel[]
constexpr char kSkiaChannel[]
GpuAvailability
Values for |Shell::SetGpuAvailability|.
@ kFlushAndMakeUnavailable
@ kAvailable
Indicates that GPU operations should be permitted.
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
void InitializeICU(const std::string &icu_data_path)
void InitializeICUFromMapping(std::unique_ptr< Mapping > mapping)
std::string FromURI(const std::string &uri)
void TraceSetAllowlist(const std::vector< std::string > &allowlist)
std::chrono::duration< double, std::milli > Milliseconds
void SetLogSettings(const LogSettings &settings)
constexpr LogSeverity kLogError
fml::UniqueFD OpenDirectory(const char *path, bool create_if_necessary, FilePermission permission)
internal::CopyableLambda< T > MakeCopyable(T lambda)
std::pair< bool, std::string > Base32Encode(std::string_view input)
constexpr Milliseconds kDefaultFrameBudget
constexpr LogSeverity kLogInfo
std::function< void()> closure
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Milliseconds RefreshRateToFrameBudget(T refresh_rate)
void SetLogHandler(std::function< void(const char *)> handler)
static size_t Encode(const void *src, size_t length, void *dst)
static size_t EncodedSize(size_t srcDataLength)
bool prefetched_default_font_manager
bool icu_initialization_required
MergedPlatformUIThread merged_platform_ui_thread
bool skia_deterministic_rendering_on_cpu
bool purge_persistent_cache
std::vector< std::string > trace_allowlist
MappingCallback icu_mapper
bool dump_skp_on_shader_compilation
std::optional< std::vector< std::string > > trace_skia_allowlist
std::string icu_data_path
FrameRasterizedCallback frame_rasterized_callback
size_t resource_cache_max_bytes_threshold
double physical_max_height_constraint
double physical_max_width_constraint
double device_pixel_ratio
double physical_min_height_constraint
double physical_min_width_constraint
LogSeverity min_log_level
Represents the 2 code paths available when calling |SyncSwitchExecute|.
Handlers & SetIfFalse(const std::function< void()> &handler)
Sets the handler that will be executed if the |SyncSwitch| is false.
#define TRACE_FLOW_BEGIN(category, name, id)
#define TRACE_EVENT0(category_group, name)
#define TRACE_EVENT_ASYNC_END0(category_group, name, id)
#define TRACE_EVENT0_WITH_FLOW_IDS(category_group, name, flow_id_count, flow_ids)
#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id)