9#define RAPIDJSON_HAS_STDSTRING 1
36#include "rapidjson/stringbuffer.h"
37#include "rapidjson/writer.h"
38#include "third_party/dart/runtime/include/dart_tools_api.h"
39#include "third_party/skia/include/codec/SkBmpDecoder.h"
40#include "third_party/skia/include/codec/SkCodec.h"
41#include "third_party/skia/include/codec/SkGifDecoder.h"
42#include "third_party/skia/include/codec/SkIcoDecoder.h"
43#include "third_party/skia/include/codec/SkJpegDecoder.h"
44#include "third_party/skia/include/codec/SkPngDecoder.h"
45#include "third_party/skia/include/codec/SkWbmpDecoder.h"
46#include "third_party/skia/include/codec/SkWebpDecoder.h"
47#include "third_party/skia/include/core/SkGraphics.h"
59std::unique_ptr<Engine> CreateEngine(
67 std::unique_ptr<Animator> animator,
71 const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch,
72 const std::shared_future<impeller::RuntimeStageBackend>&
73 runtime_stage_backend) {
74 return std::make_unique<Engine>(delegate,
86 runtime_stage_backend);
89void RegisterCodecsWithSkia() {
94 SkCodecs::Register(SkPngDecoder::Decoder());
95 SkCodecs::Register(SkJpegDecoder::Decoder());
96 SkCodecs::Register(SkWebpDecoder::Decoder());
97 SkCodecs::Register(SkGifDecoder::Decoder());
98 SkCodecs::Register(SkBmpDecoder::Decoder());
99 SkCodecs::Register(SkWbmpDecoder::Decoder());
100 SkCodecs::Register(SkIcoDecoder::Decoder());
109void PerformInitializationTasks(
Settings& settings) {
117 static std::once_flag gShellSettingsInitialization = {};
118 std::call_once(gShellSettingsInitialization, [&settings] {
133 FML_DLOG(INFO) <<
"Skia deterministic rendering is enabled.";
135 RegisterCodecsWithSkia();
143 FML_DLOG(WARNING) <<
"Skipping ICU initialization in the shell.";
205std::pair<DartVMRef, fml::RefPtr<const DartSnapshot>>
216 if (!isolate_snapshot) {
217 isolate_snapshot = vm->GetVMData()->GetIsolateSnapshot();
219 return {std::move(vm), isolate_snapshot};
228 bool is_gpu_disabled) {
230 PerformInitializationTasks(settings);
235 auto resource_cache_limit_calculator =
236 std::make_shared<ResourceCacheLimitCalculator>(
239 return CreateWithSnapshot(platform_data,
243 resource_cache_limit_calculator,
246 std::move(isolate_snapshot),
247 on_create_platform_view,
248 on_create_rasterizer,
249 CreateEngine, is_gpu_disabled);
252std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
255 std::shared_ptr<ShellIOManager> parent_io_manager,
256 const std::shared_ptr<ResourceCacheLimitCalculator>&
257 resource_cache_limit_calculator,
265 bool is_gpu_disabled) {
267 FML_LOG(ERROR) <<
"Task runners to run the shell were invalid.";
271 auto shell = std::unique_ptr<Shell>(
272 new Shell(std::move(vm), task_runners, std::move(parent_merger),
273 resource_cache_limit_calculator, settings, is_gpu_disabled));
283 std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise;
284 auto rasterizer_future = rasterizer_promise.get_future();
285 std::promise<fml::TaskRunnerAffineWeakPtr<SnapshotDelegate>>
286 snapshot_delegate_promise;
287 auto snapshot_delegate_future = snapshot_delegate_promise.get_future();
289 std::promise<std::shared_ptr<impeller::Context>> impeller_context_promise;
290 auto impeller_context_future =
291 std::make_shared<impeller::ImpellerContextFuture>(
292 impeller_context_promise.get_future());
296 [&rasterizer_promise,
297 &snapshot_delegate_promise, impeller_context_future,
298 on_create_rasterizer,
299 shell = shell.get()]() {
300 TRACE_EVENT0(
"flutter",
"ShellSetupGPUSubsystem");
301 std::unique_ptr<Rasterizer> rasterizer(on_create_rasterizer(*shell));
302 rasterizer->SetImpellerContext(impeller_context_future);
303 snapshot_delegate_promise.set_value(rasterizer->GetSnapshotDelegate());
304 rasterizer_promise.set_value(std::move(rasterizer));
311 std::promise<impeller::RuntimeStageBackend> runtime_stage_backend;
312 std::shared_future<impeller::RuntimeStageBackend> runtime_stage_future =
313 runtime_stage_backend.get_future();
318 [impeller_context_promise = std::move(impeller_context_promise),
319 runtime_stage_backend = std::move(runtime_stage_backend),
320 platform_view_ptr]()
mutable {
321 TRACE_EVENT0(
"flutter",
"CreateImpellerContext");
322 platform_view_ptr->SetupImpellerContext();
323 std::shared_ptr<impeller::Context> impeller_context =
324 platform_view_ptr->GetImpellerContext();
325 if (impeller_context) {
326 runtime_stage_backend.set_value(
327 impeller_context->GetRuntimeStageBackend());
328 impeller_context_promise.set_value(impeller_context);
330 runtime_stage_backend.set_value(
331 impeller::RuntimeStageBackend::kSkSL);
332 impeller_context_promise.set_value(nullptr);
347 std::promise<std::shared_ptr<ShellIOManager>> io_manager_promise;
348 auto io_manager_future = io_manager_promise.get_future();
349 std::promise<fml::WeakPtr<ShellIOManager>> weak_io_manager_promise;
350 auto weak_io_manager_future = weak_io_manager_promise.get_future();
351 std::promise<fml::RefPtr<SkiaUnrefQueue>> unref_queue_promise;
352 auto unref_queue_future = unref_queue_promise.get_future();
353 auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner();
359 [&io_manager_promise,
360 &weak_io_manager_promise,
362 &unref_queue_promise,
365 is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch(),
367 impeller_context_future]() {
368 TRACE_EVENT0(
"flutter",
"ShellSetupIOSubsystem");
369 std::shared_ptr<ShellIOManager> io_manager;
370 if (parent_io_manager) {
371 io_manager = parent_io_manager;
373 io_manager = std::make_shared<ShellIOManager>(
375 is_backgrounded_sync_switch,
377 impeller_context_future,
381 weak_io_manager_promise.set_value(io_manager->GetWeakPtr());
382 unref_queue_promise.set_value(io_manager->GetSkiaUnrefQueue());
383 io_manager_promise.set_value(io_manager);
387 io_manager->GetImpellerContext();
388 sk_sp<GrDirectContext> resource_context =
389 platform_view_ptr->CreateResourceContext();
390 io_manager->NotifyResourceContextAvailable(resource_context);
398 std::promise<std::unique_ptr<Engine>> engine_promise;
399 auto engine_future = engine_promise.get_future();
401 shell->GetTaskRunners().GetUITaskRunner(),
406 isolate_snapshot = std::move(isolate_snapshot),
407 vsync_waiter = std::move(vsync_waiter),
408 &weak_io_manager_future,
409 &snapshot_delegate_future,
410 &runtime_stage_future,
412 &on_create_engine]()
mutable {
413 TRACE_EVENT0(
"flutter",
"ShellSetupUISubsystem");
414 const auto& task_runners = shell->GetTaskRunners();
418 auto animator = std::make_unique<Animator>(*shell, task_runners,
419 std::move(vsync_waiter));
421 engine_promise.set_value(
422 on_create_engine(*shell,
425 std::move(isolate_snapshot),
428 shell->GetSettings(),
430 weak_io_manager_future.get(),
431 unref_queue_future.get(),
432 snapshot_delegate_future.get(),
433 shell->is_gpu_disabled_sync_switch_,
434 runtime_stage_future));
439 rasterizer_future.get(),
440 io_manager_future.get())
448std::unique_ptr<Shell> Shell::CreateWithSnapshot(
449 const PlatformData& platform_data,
450 const TaskRunners& task_runners,
452 const std::shared_ptr<ShellIOManager>& parent_io_manager,
453 const std::shared_ptr<ResourceCacheLimitCalculator>&
454 resource_cache_limit_calculator,
458 const Shell::CreateCallback<PlatformView>& on_create_platform_view,
459 const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
460 const Shell::EngineCreateCallback& on_create_engine,
461 bool is_gpu_disabled) {
463 PerformInitializationTasks(settings);
467 const bool callbacks_valid =
468 on_create_platform_view && on_create_rasterizer && on_create_engine;
469 if (!task_runners.IsValid() || !callbacks_valid) {
474 std::unique_ptr<Shell> shell;
475 auto platform_task_runner = task_runners.GetPlatformTaskRunner();
477 platform_task_runner,
480 parent_thread_merger,
482 resource_cache_limit_calculator,
483 task_runners = task_runners,
484 platform_data = platform_data,
487 isolate_snapshot = std::move(isolate_snapshot),
488 on_create_platform_view = on_create_platform_view,
489 on_create_rasterizer = on_create_rasterizer,
490 on_create_engine = on_create_engine,
491 is_gpu_disabled]()
mutable {
492 shell = CreateShellOnPlatformThread(std::move(vm),
493 parent_thread_merger,
495 resource_cache_limit_calculator,
499 std::move(isolate_snapshot),
500 on_create_platform_view,
501 on_create_rasterizer,
510Shell::Shell(DartVMRef vm,
511 const TaskRunners& task_runners,
513 const std::shared_ptr<ResourceCacheLimitCalculator>&
514 resource_cache_limit_calculator,
515 const Settings& settings,
516 bool is_gpu_disabled)
518 parent_raster_thread_merger_(
std::move(parent_merger)),
519 resource_cache_limit_calculator_(resource_cache_limit_calculator),
522 is_gpu_disabled_sync_switch_(new
fml::SyncSwitch(is_gpu_disabled)),
523 weak_factory_gpu_(nullptr),
524 weak_factory_(this) {
525 FML_CHECK(!settings.enable_software_rendering || !settings.enable_impeller)
526 <<
"Software rendering is incompatible with Impeller.";
527 if (!settings.enable_impeller && settings.warn_on_impeller_opt_out) {
529 R
"warn([Action Required]: Impeller opt-out deprecated.
530 The application opted out of Impeller by either using the
531 `--no-enable-impeller` flag or the
532 `io.flutter.embedding.android.EnableImpeller` `AndroidManifest.xml` entry.
533 These options are going to go away in an upcoming Flutter release. Remove
534 the explicit opt-out. If you need to opt-out, please report a bug describing
537 https://github.com/flutter/flutter/issues/new?template=02_bug.yml
540 FML_CHECK(vm_) << "Must have access to VM to create a shell.";
544 display_manager_ = std::make_unique<DisplayManager>();
545 resource_cache_limit_calculator->AddResourceCacheLimitItem(
546 weak_factory_.GetWeakPtr());
553 this->weak_factory_gpu_ =
554 std::make_unique<fml::TaskRunnerAffineWeakPtrFactory<Shell>>(this);
561 std::bind(&Shell::OnServiceProtocolScreenshot,
this,
562 std::placeholders::_1, std::placeholders::_2)};
565 std::bind(&Shell::OnServiceProtocolScreenshotSKP,
this,
566 std::placeholders::_1, std::placeholders::_2)};
569 std::bind(&Shell::OnServiceProtocolRunInView,
this, std::placeholders::_1,
570 std::placeholders::_2)};
571 service_protocol_handlers_
574 std::bind(&Shell::OnServiceProtocolFlushUIThreadTasks,
this,
575 std::placeholders::_1, std::placeholders::_2)};
576 service_protocol_handlers_
579 std::bind(&Shell::OnServiceProtocolSetAssetBundlePath,
this,
580 std::placeholders::_1, std::placeholders::_2)};
581 service_protocol_handlers_
584 std::bind(&Shell::OnServiceProtocolGetDisplayRefreshRate,
this,
585 std::placeholders::_1, std::placeholders::_2)};
588 std::bind(&Shell::OnServiceProtocolGetSkSLs,
this, std::placeholders::_1,
589 std::placeholders::_2)};
590 service_protocol_handlers_
593 std::bind(&Shell::OnServiceProtocolEstimateRasterCacheMemory,
this,
594 std::placeholders::_1, std::placeholders::_2)};
597 std::bind(&Shell::OnServiceProtocolReloadAssetFonts,
this,
598 std::placeholders::_1, std::placeholders::_2)};
601 std::bind(&Shell::OnServiceProtocolGetPipelineUsage,
this,
602 std::placeholders::_1, std::placeholders::_2)};
614 platform_latch, io_latch;
619 engine_->ShutdownPlatformIsolates();
620 platiso_latch.Signal();
622 platiso_latch.
Wait();
635 [
this, rasterizer = std::move(rasterizer_), &gpu_latch]()
mutable {
637 this->weak_factory_gpu_.reset();
646 &io_latch]()
mutable {
647 std::weak_ptr<ShellIOManager> weak_io_manager(io_manager);
652 if (platform_view && weak_io_manager.expired()) {
653 platform_view->ReleaseResourceContext();
666 &platform_latch]()
mutable {
667 platform_view.reset();
668 platform_latch.Signal();
670 platform_latch.
Wait();
677 auto platform_queue_id =
680 if (task_queues->Owns(platform_queue_id, ui_queue_id)) {
681 task_queues->Unmerge(platform_queue_id, ui_queue_id);
687 RunConfiguration run_configuration,
688 const std::string& initial_route,
689 const CreateCallback<PlatformView>& on_create_platform_view,
690 const CreateCallback<Rasterizer>& on_create_rasterizer)
const {
697 FML_LOG(ERROR) <<
"MergedPlatformUIThread::kMergeAfterLaunch does not "
703 bool is_gpu_disabled =
false;
706 .SetIfFalse([&is_gpu_disabled] { is_gpu_disabled =
false; })
707 .SetIfTrue([&is_gpu_disabled] { is_gpu_disabled =
true; }));
708 std::unique_ptr<Shell> result = CreateWithSnapshot(
709 PlatformData{}, task_runners_, rasterizer_->GetRasterThreadMerger(),
710 io_manager_, resource_cache_limit_calculator_,
GetSettings(), vm_,
711 vm_->
GetVMData()->GetIsolateSnapshot(), on_create_platform_view,
712 on_create_rasterizer,
713 [
engine = this->engine_.get(), initial_route](
714 Engine::Delegate& delegate,
717 const TaskRunners& task_runners,
const PlatformData& platform_data,
718 const Settings& settings, std::unique_ptr<Animator> animator,
722 const std::shared_ptr<fml::SyncSwitch>& is_gpu_disabled_sync_switch,
723 const std::shared_future<impeller::RuntimeStageBackend>&
724 runtime_stage_backend) {
725 return engine->Spawn(
732 std::move(snapshot_delegate),
733 is_gpu_disabled_sync_switch);
736 result->RunEngine(std::move(run_configuration));
748 ::Dart_NotifyLowMemory();
751 [rasterizer = rasterizer_->GetWeakPtr(), trace_id = trace_id]() {
753 rasterizer->NotifyLowMemoryWarning();
764 engine_->FlushMicrotaskQueue();
769 RunEngine(std::move(run_configuration),
nullptr);
773 RunConfiguration run_configuration,
777 if (!result_callback) {
780 platform_runner->PostTask(
781 [result_callback, run_result]() { result_callback(run_result); });
789 [run_configuration = std::move(run_configuration),
790 weak_engine = weak_engine_, result]()
mutable {
793 <<
"Could not launch engine with configuration - no engine.";
794 result(Engine::RunStatus::Failure);
797 auto run_result = weak_engine->Run(std::move(run_configuration));
799 FML_LOG(ERROR) <<
"Could not launch engine with configuration.";
813 switch (weak_engine_->GetUIIsolateLastError()) {
834 return weak_engine_->UIIsolateHasLivePorts();
845 return weak_engine_->UIIsolateHasPendingMicrotasks();
852bool Shell::Setup(std::unique_ptr<PlatformView>
platform_view,
853 std::unique_ptr<Engine>
engine,
854 std::unique_ptr<Rasterizer> rasterizer,
855 const std::shared_ptr<ShellIOManager>& io_manager) {
865 platform_message_handler_ = platform_view_->GetPlatformMessageHandler();
866 route_messages_through_platform_thread_.store(
true);
868 [
self = weak_factory_.GetWeakPtr()] {
870 self->route_messages_through_platform_thread_.store(false);
873 engine_ = std::move(
engine);
874 rasterizer_ = std::move(rasterizer);
878 auto view_embedder = platform_view_->CreateExternalViewEmbedder();
879 rasterizer_->SetExternalViewEmbedder(view_embedder);
880 rasterizer_->SetSnapshotSurfaceProducer(
881 platform_view_->CreateSnapshotSurfaceProducer());
885 weak_engine_ = engine_->GetWeakPtr();
886 weak_rasterizer_ = rasterizer_->GetWeakPtr();
887 weak_platform_view_ = platform_view_->GetWeakPtr();
891 FML_DCHECK(added) <<
"Failed to add the implicit view";
899 engine->SetupDefaultFontManager();
926 return task_runners_;
931 return parent_raster_thread_merger_;
936 return weak_rasterizer_;
946 return weak_platform_view_;
951 return io_manager_->GetWeakPtr();
959void Shell::OnPlatformViewCreated(std::unique_ptr<Surface> surface) {
960 TRACE_EVENT0(
"flutter",
"Shell::OnPlatformViewCreated");
973 rasterizer_->DisableThreadMergerIfNeeded();
985 const bool should_post_raster_task =
989 [&waiting_for_first_frame = waiting_for_first_frame_,
990 rasterizer = rasterizer_->GetWeakPtr(),
991 surface = std::move(surface)
996 rasterizer->EnableThreadMergerIfNeeded();
997 rasterizer->Setup(std::move(surface));
1000 waiting_for_first_frame.store(
true);
1003 auto ui_task = [
engine = engine_->GetWeakPtr()] {
1020 raster_task, should_post_raster_task, &latch] {
1021 if (io_manager && !io_manager->GetResourceContext()) {
1022 sk_sp<GrDirectContext> resource_context =
1024 io_manager->NotifyResourceContextAvailable(resource_context);
1032 if (should_post_raster_task) {
1041 if (!should_post_raster_task) {
1051void Shell::OnPlatformViewDestroyed() {
1052 TRACE_EVENT0(
"flutter",
"Shell::OnPlatformViewDestroyed");
1064 rasterizer_->DisableThreadMergerIfNeeded();
1076 auto io_task = [io_manager = io_manager_.get(), &latch]() {
1079 io_manager->GetIsGpuDisabledSyncSwitch()->Execute(
1081 [&] { io_manager->GetSkiaUnrefQueue()->Drain(); }));
1087 auto raster_task = [rasterizer = rasterizer_->GetWeakPtr(),
1094 rasterizer->EnableThreadMergerIfNeeded();
1095 rasterizer->Teardown();
1113 rasterizer_->TeardownExternalViewEmbedder();
1117void Shell::OnPlatformViewScheduleFrame() {
1118 TRACE_EVENT0(
"flutter",
"Shell::OnPlatformViewScheduleFrame");
1123 [
engine = engine_->GetWeakPtr()]() {
1125 engine->ScheduleFrame();
1131void Shell::OnPlatformViewSetViewportMetrics(int64_t
view_id,
1132 const ViewportMetrics& metrics) {
1136 if (!ValidateViewportMetrics(metrics)) {
1143 resource_cache_limit_ =
1144 metrics.physical_width * metrics.physical_height * 12 * 4;
1145 size_t resource_cache_max_bytes =
1146 resource_cache_limit_calculator_->GetResourceCacheMaxBytes();
1148 [rasterizer = rasterizer_->GetWeakPtr(), resource_cache_max_bytes] {
1150 rasterizer->SetResourceCacheMaxBytes(resource_cache_max_bytes, false);
1158 engine->SetViewportMetrics(view_id, metrics);
1163 std::scoped_lock<std::mutex> lock(resize_mutex_);
1165 expected_frame_constraints_[
view_id] =
1166 BoxConstraints(
Size(metrics.physical_min_width_constraint,
1167 metrics.physical_min_height_constraint),
1168 Size(metrics.physical_max_width_constraint,
1169 metrics.physical_max_height_constraint));
1170 device_pixel_ratio_ = metrics.device_pixel_ratio;
1175void Shell::OnPlatformViewDispatchPlatformMessage(
1176 std::unique_ptr<PlatformMessage>
message) {
1178#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
1180 std::scoped_lock lock(misbehaving_message_channels_mutex_);
1181 auto inserted = misbehaving_message_channels_.insert(
message->channel());
1182 if (inserted.second) {
1184 <<
"The '" <<
message->channel()
1185 <<
"' channel sent a message from native to Flutter on a "
1186 "non-platform thread. Platform channel messages must be sent on "
1187 "the platform thread. Failure to do so may result in data loss or "
1188 "crashes, and must be fixed in the plugin or application code "
1189 "creating that channel.\n"
1190 "See https://docs.flutter.dev/platform-integration/"
1191 "platform-channels#channels-and-platform-threading for more "
1204 engine->DispatchPlatformMessage(std::move(message));
1210void Shell::OnPlatformViewDispatchPointerDataPacket(
1211 std::unique_ptr<PointerDataPacket> packet) {
1213 "flutter",
"Shell::OnPlatformViewDispatchPointerDataPacket",
1214 1, &next_pointer_flow_id_);
1221 flow_id = next_pointer_flow_id_]()
mutable {
1223 engine->DispatchPointerDataPacket(std::move(packet), flow_id);
1226 next_pointer_flow_id_++;
1229HitTestResponse Shell::OnPlatformViewHitTest(int64_t
view_id,
1235 return engine_->HitTest(
view_id, offset);
1237 return {.has_platform_view =
false};
1241void Shell::OnPlatformViewDispatchSemanticsAction(int64_t
view_id,
1253 engine->DispatchSemanticsAction(view_id, node_id, action,
1260void Shell::OnPlatformViewSetSemanticsEnabled(
bool enabled) {
1266 [
engine = engine_->GetWeakPtr(), enabled] {
1268 engine->SetSemanticsEnabled(enabled);
1274void Shell::OnPlatformViewSetAccessibilityFeatures(int32_t flags) {
1281 engine->SetAccessibilityFeatures(flags);
1287void Shell::OnPlatformViewRegisterTexture(
1288 std::shared_ptr<flutter::Texture>
texture) {
1293 [rasterizer = rasterizer_->GetWeakPtr(),
texture] {
1295 if (auto registry = rasterizer->GetTextureRegistry()) {
1296 registry->RegisterTexture(texture);
1303void Shell::OnPlatformViewUnregisterTexture(int64_t
texture_id) {
1308 [rasterizer = rasterizer_->GetWeakPtr(),
texture_id]() {
1310 if (auto registry = rasterizer->GetTextureRegistry()) {
1311 registry->UnregisterTexture(texture_id);
1318void Shell::OnPlatformViewMarkTextureFrameAvailable(int64_t
texture_id) {
1324 [rasterizer = rasterizer_->GetWeakPtr(),
texture_id]() {
1328 auto registry = rasterizer->GetTextureRegistry();
1340 texture->MarkNewFrameAvailable();
1345 [
engine = engine_->GetWeakPtr()]() {
1347 engine->ScheduleFrame(false);
1353void Shell::OnPlatformViewSetNextFrameCallback(
const fml::closure& closure) {
1358 [rasterizer = rasterizer_->GetWeakPtr(), closure = closure]() {
1360 rasterizer->SetNextFrameCallback(closure);
1366const Settings& Shell::OnPlatformViewGetSettings()
const {
1371void Shell::OnAnimatorBeginFrame(
fml::TimePoint frame_target_time,
1372 uint64_t frame_number) {
1378 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1379 latest_frame_target_time_.emplace(frame_target_time);
1382 engine_->BeginFrame(frame_target_time, frame_number);
1392 engine_->NotifyIdle(deadline);
1396void Shell::OnAnimatorUpdateLatestFrameTargetTime(
1402 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1403 if (!latest_frame_target_time_) {
1404 latest_frame_target_time_ = frame_target_time;
1405 }
else if (latest_frame_target_time_ < frame_target_time) {
1406 latest_frame_target_time_ = frame_target_time;
1412void Shell::OnAnimatorDraw(std::shared_ptr<FramePipeline> pipeline) {
1416 [&waiting_for_first_frame = waiting_for_first_frame_,
1417 &waiting_for_first_frame_condition = waiting_for_first_frame_condition_,
1418 rasterizer = rasterizer_->GetWeakPtr(),
1419 weak_pipeline = std::weak_ptr<FramePipeline>(pipeline)]()
mutable {
1421 std::shared_ptr<FramePipeline> pipeline = weak_pipeline.lock();
1423 rasterizer->Draw(pipeline);
1426 if (waiting_for_first_frame.load()) {
1427 waiting_for_first_frame.store(false);
1428 waiting_for_first_frame_condition.notify_all();
1435void Shell::OnAnimatorDrawLastLayerTrees(
1436 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) {
1440 [rasterizer = rasterizer_->GetWeakPtr(),
1441 frame_timings_recorder = std::move(frame_timings_recorder)]()
mutable {
1443 rasterizer->DrawLastLayerTrees(std::move(frame_timings_recorder));
1451void Shell::OnEngineUpdateSemantics(int64_t
view_id,
1459 [view = platform_view_->GetWeakPtr(), update = std::move(update),
1462 view->UpdateSemantics(view_id, update, actions);
1468void Shell::OnEngineSetApplicationLocale(std::string locale) {
1474 [view = platform_view_->GetWeakPtr(), locale_holder = std::move(locale)] {
1476 view->SetApplicationLocale(locale_holder);
1482void Shell::OnEngineSetSemanticsTreeEnabled(
bool enabled) {
1488 [view = platform_view_->GetWeakPtr(), enabled] {
1490 view->SetSemanticsTreeEnabled(enabled);
1496void Shell::OnEngineHandlePlatformMessage(
1497 std::unique_ptr<PlatformMessage>
message) {
1502 HandleEngineSkiaMessage(std::move(
message));
1506 if (platform_message_handler_) {
1507 if (route_messages_through_platform_thread_ &&
1508 !platform_message_handler_
1509 ->DoesHandlePlatformMessageOnPlatformThread()) {
1527 [weak_platform_message_handler =
1528 std::weak_ptr<PlatformMessageHandler>(platform_message_handler_),
1530 ui_task_runner->PostTask(
1533 auto platform_message_handler =
1534 weak_platform_message_handler.lock();
1535 if (platform_message_handler) {
1536 platform_message_handler->HandlePlatformMessage(
1542 platform_message_handler_->HandlePlatformMessage(std::move(
message));
1549 view->HandlePlatformMessage(std::move(message));
1555void Shell::OnEngineChannelUpdate(std::string
name,
bool listening) {
1559 [view = platform_view_->GetWeakPtr(),
name = std::move(
name), listening] {
1561 view->SendChannelUpdate(name, listening);
1566void Shell::HandleEngineSkiaMessage(std::unique_ptr<PlatformMessage>
message) {
1569 rapidjson::Document document;
1570 document.Parse(
reinterpret_cast<const char*
>(
data.GetMapping()),
1572 if (document.HasParseError() || !document.IsObject()) {
1575 auto root = document.GetObj();
1576 auto method = root.FindMember(
"method");
1577 if (method->value !=
"Skia.setResourceCacheMaxBytes") {
1580 auto args = root.FindMember(
"args");
1581 if (
args == root.MemberEnd() || !
args->value.IsInt()) {
1586 [rasterizer = rasterizer_->GetWeakPtr(), max_bytes =
args->value.GetInt(),
1587 response =
message->response()] {
1589 rasterizer->SetResourceCacheMaxBytes(static_cast<size_t>(max_bytes),
1595 std::vector<uint8_t>
data = {
'[',
't',
'r',
'u',
'e',
']'};
1597 std::make_unique<fml::DataMapping>(std::move(
data)));
1603void Shell::OnPreEngineRestart() {
1610 [view = platform_view_->GetWeakPtr(), &latch]() {
1612 view->OnPreEngineRestart();
1622void Shell::OnRootIsolateCreated() {
1623 if (is_added_to_service_protocol_) {
1626 auto description = GetServiceProtocolDescription();
1629 [
self = weak_factory_.GetWeakPtr(),
1630 description = std::move(description)]() {
1632 self->vm_->GetServiceProtocol()->AddHandler(self.get(), description);
1635 is_added_to_service_protocol_ =
true;
1639void Shell::UpdateIsolateDescription(
const std::string isolate_name,
1640 int64_t isolate_port) {
1641 Handler::Description description(isolate_port, isolate_name);
1645void Shell::SetNeedsReportTimings(
bool value) {
1646 needs_report_timings_ =
value;
1650std::unique_ptr<std::vector<std::string>> Shell::ComputePlatformResolvedLocale(
1651 const std::vector<std::string>& supported_locale_data) {
1652 return platform_view_->ComputePlatformResolvedLocales(supported_locale_data);
1655void Shell::LoadDartDeferredLibrary(
1656 intptr_t loading_unit_id,
1657 std::unique_ptr<const fml::Mapping> snapshot_data,
1658 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
1660 [
engine = engine_->GetWeakPtr(), loading_unit_id,
1661 data = std::move(snapshot_data),
1662 instructions = std::move(snapshot_instructions)]()
mutable {
1664 engine->LoadDartDeferredLibrary(loading_unit_id, std::move(data),
1665 std::move(instructions));
1670void Shell::LoadDartDeferredLibraryError(intptr_t loading_unit_id,
1671 const std::string error_message,
1675 [
engine = weak_engine_, loading_unit_id, error_message, transient] {
1677 engine->LoadDartDeferredLibraryError(loading_unit_id, error_message,
1683void Shell::UpdateAssetResolverByType(
1684 std::unique_ptr<AssetResolver> updated_asset_resolver,
1690 asset_resolver = std::move(updated_asset_resolver)]()
mutable {
1692 engine->GetAssetManager()->UpdateResolverByType(
1693 std::move(asset_resolver), type);
1699void Shell::RequestDartDeferredLibrary(intptr_t loading_unit_id) {
1701 [view = platform_view_->GetWeakPtr(), loading_unit_id] {
1703 view->RequestDartDeferredLibrary(loading_unit_id);
1709double Shell::GetScaledFontSize(
double unscaled_font_size,
1710 int configuration_id)
const {
1711 return platform_view_->GetScaledFontSize(unscaled_font_size,
1715void Shell::RequestViewFocusChange(
const ViewFocusChangeRequest& request) {
1720 [view = platform_view_->GetWeakPtr(), request] {
1722 view->RequestViewFocusChange(request);
1727void Shell::ReportTimings() {
1731 auto timings = std::move(unreported_timings_);
1732 unreported_timings_ = {};
1735 engine->ReportTimings(timings);
1740size_t Shell::UnreportedFramesCount()
const {
1747void Shell::OnFrameRasterized(
const FrameTiming& timing) {
1757 if (!needs_report_timings_) {
1761 size_t old_count = unreported_timings_.size();
1763 for (
auto phase : FrameTiming::kPhases) {
1764 unreported_timings_.push_back(
1765 timing.Get(phase).ToEpochDelta().ToMicroseconds());
1767 unreported_timings_.push_back(timing.GetLayerCacheCount());
1768 unreported_timings_.push_back(timing.GetLayerCacheBytes());
1769 unreported_timings_.push_back(timing.GetPictureCacheCount());
1770 unreported_timings_.push_back(timing.GetPictureCacheBytes());
1771 unreported_timings_.push_back(timing.GetFrameNumber());
1787 if (!first_frame_rasterized_ || UnreportedFramesCount() >= 100) {
1788 first_frame_rasterized_ =
true;
1790 }
else if (!frame_timings_report_scheduled_) {
1792 constexpr int kBatchTimeInMilliseconds = 1000;
1794 constexpr int kBatchTimeInMilliseconds = 100;
1800 frame_timings_report_scheduled_ =
true;
1802 [
self = weak_factory_gpu_->GetWeakPtr()]() {
1806 self->frame_timings_report_scheduled_ =
false;
1807 if (
self->UnreportedFramesCount() > 0) {
1808 self->ReportTimings();
1816 if (cached_display_refresh_rate_.has_value()) {
1817 return cached_display_refresh_rate_.value();
1819 double display_refresh_rate = display_manager_->GetMainDisplayRefreshRate();
1820 if (display_refresh_rate > 0) {
1821 cached_display_refresh_rate_ =
1830 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1831 FML_CHECK(latest_frame_target_time_.has_value())
1832 <<
"GetLatestFrameTargetTime called before OnAnimatorBeginFrame";
1835 return latest_frame_target_time_.value();
1839bool Shell::ShouldDiscardLayerTree(int64_t
view_id,
1841 std::scoped_lock<std::mutex> lock(resize_mutex_);
1842 auto expected_frame_constraints = ExpectedFrameConstraints(
view_id);
1843 return !expected_frame_constraints.IsSatisfiedBy(
1849 std::string_view method)
const {
1851 auto found = service_protocol_handlers_.find(method);
1852 if (found != service_protocol_handlers_.end()) {
1853 return found->second.first;
1859bool Shell::HandleServiceProtocolMessage(
1860 std::string_view method,
1861 const ServiceProtocolMap&
params,
1862 rapidjson::Document* response) {
1863 auto found = service_protocol_handlers_.find(method);
1864 if (found != service_protocol_handlers_.end()) {
1865 return found->second.second(
params, response);
1871ServiceProtocol::Handler::Description Shell::GetServiceProtocolDescription()
1875 if (!weak_engine_) {
1880 weak_engine_->GetUIIsolateMainPort(),
1881 weak_engine_->GetUIIsolateName(),
1886 std::string error_details) {
1887 auto&
allocator = response->GetAllocator();
1888 response->SetObject();
1889 const int64_t kInvalidParams = -32602;
1891 response->AddMember(
"message",
"Invalid params",
allocator);
1893 rapidjson::Value details(rapidjson::kObjectType);
1894 details.AddMember(
"details", std::move(error_details),
allocator);
1895 response->AddMember(
"data", details,
allocator);
1901 auto&
allocator = response->GetAllocator();
1902 response->SetObject();
1903 const int64_t kJsonServerError = -32000;
1904 response->AddMember(
"code", kJsonServerError,
allocator);
1909bool Shell::OnServiceProtocolScreenshot(
1911 rapidjson::Document* response) {
1913 auto screenshot = rasterizer_->ScreenshotLastLayerTree(
1915 if (screenshot.data) {
1916 response->SetObject();
1917 auto&
allocator = response->GetAllocator();
1918 response->AddMember(
"type",
"Screenshot",
allocator);
1919 rapidjson::Value
image;
1920 image.SetString(
static_cast<const char*
>(screenshot.data->data()),
1930bool Shell::OnServiceProtocolScreenshotSKP(
1932 rapidjson::Document* response) {
1936 response,
"Cannot capture SKP screenshot with Impeller enabled.");
1939 auto screenshot = rasterizer_->ScreenshotLastLayerTree(
1941 if (screenshot.data) {
1942 response->SetObject();
1943 auto&
allocator = response->GetAllocator();
1944 response->AddMember(
"type",
"ScreenshotSkp",
allocator);
1945 rapidjson::Value skp;
1946 skp.SetString(
static_cast<const char*
>(screenshot.data->data()),
1948 response->AddMember(
"skp", skp,
allocator);
1956bool Shell::OnServiceProtocolRunInView(
1958 rapidjson::Document* response) {
1961 if (
params.count(
"mainScript") == 0) {
1963 "'mainScript' parameter is missing.");
1967 if (
params.count(
"assetDirectory") == 0) {
1969 "'assetDirectory' parameter is missing.");
1973 std::string main_script_path =
1975 std::string asset_directory_path =
1978 auto main_script_file_mapping =
1983 std::move(main_script_file_mapping));
1985 RunConfiguration configuration(std::move(isolate_configuration));
1987 configuration.SetEntrypointAndLibrary(engine_->GetLastEntrypoint(),
1988 engine_->GetLastEntrypointLibrary());
1989 configuration.SetEntrypointArgs(engine_->GetLastEntrypointArgs());
1991 configuration.SetEngineId(engine_->GetLastEngineId());
1993 configuration.AddAssetResolver(std::make_unique<DirectoryAssetBundle>(
2000 auto old_asset_manager = engine_->GetAssetManager();
2001 if (old_asset_manager !=
nullptr) {
2002 for (
auto& old_resolver : old_asset_manager->TakeResolvers()) {
2003 if (old_resolver->IsValidAfterAssetManagerChange()) {
2004 configuration.AddAssetResolver(std::move(old_resolver));
2009 auto&
allocator = response->GetAllocator();
2010 response->SetObject();
2011 if (engine_->Restart(std::move(configuration))) {
2012 response->AddMember(
"type",
"Success",
allocator);
2013 auto new_description = GetServiceProtocolDescription();
2014 rapidjson::Value
view(rapidjson::kObjectType);
2015 new_description.Write(
this, view,
allocator);
2016 response->AddMember(
"view", view,
allocator);
2019 FML_DLOG(ERROR) <<
"Could not run configuration in engine.";
2021 "Could not run configuration in engine.");
2030bool Shell::OnServiceProtocolFlushUIThreadTasks(
2032 rapidjson::Document* response) {
2040 response->SetObject();
2041 response->AddMember(
"type",
"Success", response->GetAllocator());
2045bool Shell::OnServiceProtocolGetDisplayRefreshRate(
2047 rapidjson::Document* response) {
2049 response->SetObject();
2050 response->AddMember(
"type",
"DisplayRefreshRate", response->GetAllocator());
2051 response->AddMember(
"fps", display_manager_->GetMainDisplayRefreshRate(),
2052 response->GetAllocator());
2057 return display_manager_->GetMainDisplayRefreshRate();
2067 [
engine = engine_->GetWeakPtr(), factory = std::move(factory),
2070 engine->GetImageGeneratorRegistry()->AddFactory(factory, priority);
2075bool Shell::OnServiceProtocolGetSkSLs(
2077 rapidjson::Document* response) {
2079 response->SetObject();
2080 response->AddMember(
"type",
"GetSkSLs", response->GetAllocator());
2082 rapidjson::Value shaders_json(rapidjson::kObjectType);
2085 std::vector<PersistentCache::SkSLCache> sksls = persistent_cache->LoadSkSLs();
2086 for (
const auto& sksl : sksls) {
2088 sk_sp<SkData> b64_data = SkData::MakeUninitialized(b64_size + 1);
2089 char* b64_char =
static_cast<char*
>(b64_data->writable_data());
2090 Base64::Encode(sksl.value->data(), sksl.value->size(), b64_char);
2091 b64_char[b64_size] = 0;
2092 rapidjson::Value shader_value(b64_char, response->GetAllocator());
2093 std::string_view key_view(
reinterpret_cast<const char*
>(sksl.key->data()),
2096 if (!encode_result.first) {
2099 rapidjson::Value shader_key(encode_result.second, response->GetAllocator());
2100 shaders_json.AddMember(shader_key, shader_value, response->GetAllocator());
2103 response->AddMember(
"SkSLs", shaders_json, response->GetAllocator());
2107bool Shell::OnServiceProtocolEstimateRasterCacheMemory(
2109 rapidjson::Document* response) {
2112 uint64_t layer_cache_byte_size = 0u;
2113 uint64_t picture_cache_byte_size = 0u;
2116 const auto& raster_cache = rasterizer_->compositor_context()->raster_cache();
2117 layer_cache_byte_size = raster_cache.EstimateLayerCacheByteSize();
2118 picture_cache_byte_size = raster_cache.EstimatePictureCacheByteSize();
2121 response->SetObject();
2122 response->AddMember(
"type",
"EstimateRasterCacheMemory",
2123 response->GetAllocator());
2124 response->AddMember<uint64_t>(
"layerBytes", layer_cache_byte_size,
2125 response->GetAllocator());
2126 response->AddMember<uint64_t>(
"pictureBytes", picture_cache_byte_size,
2127 response->GetAllocator());
2132bool Shell::OnServiceProtocolSetAssetBundlePath(
2134 rapidjson::Document* response) {
2137 if (
params.count(
"assetDirectory") == 0) {
2139 "'assetDirectory' parameter is missing.");
2143 auto&
allocator = response->GetAllocator();
2144 response->SetObject();
2146 auto asset_manager = std::make_shared<AssetManager>();
2148 if (!asset_manager->PushFront(std::make_unique<DirectoryAssetBundle>(
2153 FML_DLOG(ERROR) <<
"Could not update asset directory.";
2160 auto old_asset_manager = engine_->GetAssetManager();
2161 if (old_asset_manager !=
nullptr) {
2162 for (
auto& old_resolver : old_asset_manager->TakeResolvers()) {
2163 if (old_resolver->IsValidAfterAssetManagerChange()) {
2164 asset_manager->PushBack(std::move(old_resolver));
2169 if (engine_->UpdateAssetManager(asset_manager)) {
2170 response->AddMember(
"type",
"Success",
allocator);
2171 auto new_description = GetServiceProtocolDescription();
2172 rapidjson::Value
view(rapidjson::kObjectType);
2173 new_description.Write(
this, view,
allocator);
2174 response->AddMember(
"view", view,
allocator);
2177 FML_DLOG(ERROR) <<
"Could not update asset directory.";
2186bool Shell::OnServiceProtocolGetPipelineUsage(
2188 rapidjson::Document* response) {
2191 response->SetObject();
2193 auto context = io_manager_->GetImpellerContext();
2196 FML_DLOG(ERROR) <<
"Pipeline usage profiling only available in Impeller";
2198 response,
"Pipeline usage profiling only available in Impeller");
2202 auto use_counts = context->GetPipelineLibrary()->GetPipelineUseCounts();
2204 rapidjson::Value pipelines_json(rapidjson::kObjectType);
2206 for (
const auto& pipelineCount : use_counts) {
2207 std::string_view pipeline_name = pipelineCount.first.GetLabel();
2208 rapidjson::Value pipeline_key(pipeline_name.data(), pipeline_name.length(),
2209 response->GetAllocator());
2211 pipelines_json.AddMember(pipeline_key, pipelineCount.second,
2212 response->GetAllocator());
2215 response->AddMember(
"Usages", pipelines_json, response->GetAllocator());
2219void Shell::SendFontChangeNotification() {
2222 rapidjson::Document document;
2223 document.SetObject();
2224 auto&
allocator = document.GetAllocator();
2225 rapidjson::Value message_value;
2229 rapidjson::StringBuffer
buffer;
2230 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
2231 document.Accept(writer);
2233 std::unique_ptr<PlatformMessage> fontsChangeMessage =
2234 std::make_unique<flutter::PlatformMessage>(
2237 OnPlatformViewDispatchPlatformMessage(std::move(fontsChangeMessage));
2240bool Shell::OnServiceProtocolReloadAssetFonts(
2242 rapidjson::Document* response) {
2247 engine_->GetFontCollection().RegisterFonts(engine_->GetAssetManager());
2248 engine_->GetFontCollection().GetFontCollection()->ClearFontFamilyCache();
2249 SendFontChangeNotification();
2251 auto&
allocator = response->GetAllocator();
2252 response->SetObject();
2253 response->AddMember(
"type",
"Success",
allocator);
2258void Shell::OnPlatformViewAddView(int64_t
view_id,
2259 const ViewportMetrics& viewport_metrics,
2265 <<
"Unexpected request to add the implicit view #"
2275 engine->AddView(view_id, viewport_metrics, callback);
2280void Shell::OnPlatformViewRemoveView(int64_t
view_id,
2286 <<
"Unexpected request to remove the implicit view #"
2289 std::scoped_lock<std::mutex> lock(resize_mutex_);
2290 expected_frame_constraints_.erase(
view_id);
2294 [&task_runners = task_runners_,
2295 engine = engine_->GetWeakPtr(),
2296 rasterizer = rasterizer_->GetWeakPtr(),
2300 bool removed = false;
2302 removed = engine->RemoveView(view_id);
2304 task_runners.GetRasterTaskRunner()->
PostTask(
2307 rasterizer->CollectView(view_id);
2317void Shell::OnPlatformViewSendViewFocusEvent(
const ViewFocusEvent& event) {
2318 TRACE_EVENT0(
"flutter",
"Shell:: OnPlatformViewSendViewFocusEvent");
2324 [
engine = engine_->GetWeakPtr(), event = event] {
2326 engine->SendViewFocusEvent(event);
2333 bool base64_encode) {
2335 switch (screenshot_type) {
2338 <<
"Impeller backend cannot produce ScreenshotType::SkiaPicture.";
2348 Rasterizer::Screenshot screenshot;
2357 screenshot = rasterizer->ScreenshotLastLayerTree(screenshot_type,
2371 "WaitForFirstFrame called from thread that can't wait "
2372 "because it is responsible for generating the frame.");
2376 auto now = std::chrono::steady_clock::now();
2377 auto max_duration = std::chrono::steady_clock::time_point::max() - now;
2378 auto desired_duration = std::chrono::milliseconds(timeout.
ToMilliseconds());
2380 now + (desired_duration > max_duration ? max_duration : desired_duration);
2382 std::unique_lock<std::mutex> lock(waiting_for_first_frame_mutex_);
2383 bool success = waiting_for_first_frame_condition_.wait_until(
2384 lock, duration, [&waiting_for_first_frame = waiting_for_first_frame_] {
2385 return !waiting_for_first_frame.load();
2401 engine_->SetupDefaultFontManager();
2402 engine_->GetFontCollection().GetFontCollection()->ClearFontFamilyCache();
2405 SendFontChangeNotification();
2411 return is_gpu_disabled_sync_switch_;
2416 switch (availability) {
2418 is_gpu_disabled_sync_switch_->SetSwitch(
false);
2424 [io_manager = io_manager_.get(), &latch]() {
2425 io_manager->GetSkiaUnrefQueue()->Drain();
2432 is_gpu_disabled_sync_switch_->SetSwitch(
true);
2443 std::vector<DisplayData> display_data;
2444 display_data.reserve(
displays.size());
2445 for (
const auto& display :
displays) {
2446 display_data.push_back(display->GetDisplayData());
2449 [
engine = engine_->GetWeakPtr(),
2450 display_data = std::move(display_data)]() {
2452 engine->SetDisplays(display_data);
2456 display_manager_->HandleDisplayUpdates(std::move(
displays));
2463const std::shared_ptr<PlatformMessageHandler>&
2465 return platform_message_handler_;
2472 return engine_->GetVsyncWaiter();
2475const std::shared_ptr<fml::ConcurrentTaskRunner>
2484BoxConstraints Shell::ExpectedFrameConstraints(int64_t
view_id) {
2485 auto found = expected_frame_constraints_.find(
view_id);
2487 if (found == expected_frame_constraints_.end()) {
2491 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 kGetPipelineUsageExtensionName
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 FlutterViewId view_id
FlutterDesktopBinaryReply callback
#define FML_DLOG(severity)
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
std::shared_ptr< ImpellerAllocator > allocator
@ 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)
impeller::ShaderType type
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)