9#define RAPIDJSON_HAS_STDSTRING 1
37#include "rapidjson/stringbuffer.h"
38#include "rapidjson/writer.h"
39#include "third_party/dart/runtime/include/dart_tools_api.h"
40#include "third_party/skia/include/codec/SkBmpDecoder.h"
41#include "third_party/skia/include/codec/SkCodec.h"
42#include "third_party/skia/include/codec/SkGifDecoder.h"
43#include "third_party/skia/include/codec/SkIcoDecoder.h"
44#include "third_party/skia/include/codec/SkJpegDecoder.h"
45#include "third_party/skia/include/codec/SkPngDecoder.h"
46#include "third_party/skia/include/codec/SkWbmpDecoder.h"
47#include "third_party/skia/include/codec/SkWebpDecoder.h"
48#include "third_party/skia/include/core/SkGraphics.h"
60std::unique_ptr<Engine> CreateEngine(
68 std::unique_ptr<Animator> animator,
72 const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch,
73 const std::shared_future<impeller::RuntimeStageBackend>&
74 runtime_stage_backend) {
75 return std::make_unique<Engine>(delegate,
87 runtime_stage_backend);
90void RegisterCodecsWithSkia() {
95 SkCodecs::Register(SkPngDecoder::Decoder());
96 SkCodecs::Register(SkJpegDecoder::Decoder());
97 SkCodecs::Register(SkWebpDecoder::Decoder());
98 SkCodecs::Register(SkGifDecoder::Decoder());
99 SkCodecs::Register(SkBmpDecoder::Decoder());
100 SkCodecs::Register(SkWbmpDecoder::Decoder());
101 SkCodecs::Register(SkIcoDecoder::Decoder());
110void PerformInitializationTasks(
Settings& settings) {
118 static std::once_flag gShellSettingsInitialization = {};
119 std::call_once(gShellSettingsInitialization, [&settings] {
134 FML_DLOG(INFO) <<
"Skia deterministic rendering is enabled.";
136 RegisterCodecsWithSkia();
144 FML_DLOG(WARNING) <<
"Skipping ICU initialization in the shell.";
206std::pair<DartVMRef, fml::RefPtr<const DartSnapshot>>
217 if (!isolate_snapshot) {
218 isolate_snapshot = vm->GetVMData()->GetIsolateSnapshot();
220 return {std::move(vm), isolate_snapshot};
229 bool is_gpu_disabled) {
231 PerformInitializationTasks(settings);
236 auto resource_cache_limit_calculator =
237 std::make_shared<ResourceCacheLimitCalculator>(
240 return CreateWithSnapshot(platform_data,
244 resource_cache_limit_calculator,
247 std::move(isolate_snapshot),
248 on_create_platform_view,
249 on_create_rasterizer,
250 CreateEngine, is_gpu_disabled);
253std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
256 std::shared_ptr<ShellIOManager> parent_io_manager,
257 const std::shared_ptr<ResourceCacheLimitCalculator>&
258 resource_cache_limit_calculator,
266 bool is_gpu_disabled) {
268 FML_LOG(ERROR) <<
"Task runners to run the shell were invalid.";
272 auto shell = std::unique_ptr<Shell>(
273 new Shell(std::move(vm), task_runners, std::move(parent_merger),
274 resource_cache_limit_calculator, settings, is_gpu_disabled));
284 std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise;
285 auto rasterizer_future = rasterizer_promise.get_future();
286 std::promise<fml::TaskRunnerAffineWeakPtr<SnapshotDelegate>>
287 snapshot_delegate_promise;
288 auto snapshot_delegate_future = snapshot_delegate_promise.get_future();
290 std::promise<std::shared_ptr<impeller::Context>> impeller_context_promise;
291 auto impeller_context_future =
292 std::make_shared<impeller::ImpellerContextFuture>(
293 impeller_context_promise.get_future());
297 [&rasterizer_promise,
298 &snapshot_delegate_promise, impeller_context_future,
299 on_create_rasterizer,
300 shell = shell.get()]() {
301 TRACE_EVENT0(
"flutter",
"ShellSetupGPUSubsystem");
302 std::unique_ptr<Rasterizer> rasterizer(on_create_rasterizer(*shell));
303 rasterizer->SetImpellerContext(impeller_context_future);
304 snapshot_delegate_promise.set_value(rasterizer->GetSnapshotDelegate());
305 rasterizer_promise.set_value(std::move(rasterizer));
312 std::promise<impeller::RuntimeStageBackend> runtime_stage_backend;
313 std::shared_future<impeller::RuntimeStageBackend> runtime_stage_future =
314 runtime_stage_backend.get_future();
319 [impeller_context_promise = std::move(impeller_context_promise),
320 runtime_stage_backend = std::move(runtime_stage_backend),
321 platform_view_ptr]()
mutable {
322 TRACE_EVENT0(
"flutter",
"CreateImpellerContext");
323 platform_view_ptr->SetupImpellerContext();
324 std::shared_ptr<impeller::Context> impeller_context =
325 platform_view_ptr->GetImpellerContext();
326 if (impeller_context) {
327 runtime_stage_backend.set_value(
328 impeller_context->GetRuntimeStageBackend());
329 impeller_context_promise.set_value(impeller_context);
331 runtime_stage_backend.set_value(
332 impeller::RuntimeStageBackend::kSkSL);
333 impeller_context_promise.set_value(nullptr);
348 std::promise<std::shared_ptr<ShellIOManager>> io_manager_promise;
349 auto io_manager_future = io_manager_promise.get_future();
350 std::promise<fml::WeakPtr<ShellIOManager>> weak_io_manager_promise;
351 auto weak_io_manager_future = weak_io_manager_promise.get_future();
352 std::promise<fml::RefPtr<SkiaUnrefQueue>> unref_queue_promise;
353 auto unref_queue_future = unref_queue_promise.get_future();
354 auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner();
360 [&io_manager_promise,
361 &weak_io_manager_promise,
363 &unref_queue_promise,
366 is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch(),
368 impeller_context_future]() {
369 TRACE_EVENT0(
"flutter",
"ShellSetupIOSubsystem");
370 std::shared_ptr<ShellIOManager> io_manager;
371 if (parent_io_manager) {
372 io_manager = parent_io_manager;
374 io_manager = std::make_shared<ShellIOManager>(
376 is_backgrounded_sync_switch,
378 impeller_context_future,
382 weak_io_manager_promise.set_value(io_manager->GetWeakPtr());
383 unref_queue_promise.set_value(io_manager->GetSkiaUnrefQueue());
384 io_manager_promise.set_value(io_manager);
388 io_manager->GetImpellerContext();
389 sk_sp<GrDirectContext> resource_context =
390 platform_view_ptr->CreateResourceContext();
391 io_manager->NotifyResourceContextAvailable(resource_context);
399 std::promise<std::unique_ptr<Engine>> engine_promise;
400 auto engine_future = engine_promise.get_future();
402 shell->GetTaskRunners().GetUITaskRunner(),
407 isolate_snapshot = std::move(isolate_snapshot),
408 vsync_waiter = std::move(vsync_waiter),
409 &weak_io_manager_future,
410 &snapshot_delegate_future,
411 &runtime_stage_future,
413 &on_create_engine]()
mutable {
414 TRACE_EVENT0(
"flutter",
"ShellSetupUISubsystem");
415 const auto& task_runners = shell->GetTaskRunners();
419 auto animator = std::make_unique<Animator>(*shell, task_runners,
420 std::move(vsync_waiter));
422 engine_promise.set_value(
423 on_create_engine(*shell,
426 std::move(isolate_snapshot),
429 shell->GetSettings(),
431 weak_io_manager_future.get(),
432 unref_queue_future.get(),
433 snapshot_delegate_future.get(),
434 shell->is_gpu_disabled_sync_switch_,
435 runtime_stage_future));
440 rasterizer_future.get(),
441 io_manager_future.get())
449std::unique_ptr<Shell> Shell::CreateWithSnapshot(
450 const PlatformData& platform_data,
451 const TaskRunners& task_runners,
453 const std::shared_ptr<ShellIOManager>& parent_io_manager,
454 const std::shared_ptr<ResourceCacheLimitCalculator>&
455 resource_cache_limit_calculator,
459 const Shell::CreateCallback<PlatformView>& on_create_platform_view,
460 const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
461 const Shell::EngineCreateCallback& on_create_engine,
462 bool is_gpu_disabled) {
464 PerformInitializationTasks(settings);
468 const bool callbacks_valid =
469 on_create_platform_view && on_create_rasterizer && on_create_engine;
470 if (!task_runners.IsValid() || !callbacks_valid) {
475 std::unique_ptr<Shell> shell;
476 auto platform_task_runner = task_runners.GetPlatformTaskRunner();
478 platform_task_runner,
481 parent_thread_merger,
483 resource_cache_limit_calculator,
484 task_runners = task_runners,
485 platform_data = platform_data,
488 isolate_snapshot = std::move(isolate_snapshot),
489 on_create_platform_view = on_create_platform_view,
490 on_create_rasterizer = on_create_rasterizer,
491 on_create_engine = on_create_engine,
492 is_gpu_disabled]()
mutable {
493 shell = CreateShellOnPlatformThread(std::move(vm),
494 parent_thread_merger,
496 resource_cache_limit_calculator,
500 std::move(isolate_snapshot),
501 on_create_platform_view,
502 on_create_rasterizer,
511Shell::Shell(DartVMRef vm,
512 const TaskRunners& task_runners,
514 const std::shared_ptr<ResourceCacheLimitCalculator>&
515 resource_cache_limit_calculator,
516 const Settings& settings,
517 bool is_gpu_disabled)
519 parent_raster_thread_merger_(
std::move(parent_merger)),
520 resource_cache_limit_calculator_(resource_cache_limit_calculator),
523 is_gpu_disabled_sync_switch_(new
fml::SyncSwitch(is_gpu_disabled)),
524 weak_factory_gpu_(nullptr),
525 weak_factory_(this) {
526 FML_CHECK(!settings.enable_software_rendering || !settings.enable_impeller)
527 <<
"Software rendering is incompatible with Impeller.";
528 if (!settings.enable_impeller && settings.warn_on_impeller_opt_out) {
530 R
"warn([Action Required]: Impeller opt-out deprecated.
531 The application opted out of Impeller by either using the
532 `--no-enable-impeller` flag or the
533 `io.flutter.embedding.android.EnableImpeller` `AndroidManifest.xml` entry.
534 These options are going to go away in an upcoming Flutter release. Remove
535 the explicit opt-out. If you need to opt-out, please report a bug describing
538 https://github.com/flutter/flutter/issues/new?template=02_bug.yml
541 FML_CHECK(vm_) << "Must have access to VM to create a shell.";
545 display_manager_ = std::make_unique<DisplayManager>();
546 resource_cache_limit_calculator->AddResourceCacheLimitItem(
547 weak_factory_.GetWeakPtr());
549 std::shared_future<fml::WeakPtr<ShellIOManager>> weak_io_manager_future(
550 weak_io_manager_promise_.get_future());
551 shutdown_safe_io_task_runner_ =
552 std::make_shared<fml::ConditionalBasicTaskRunner>(
554 [weak_io_manager_future = std::move(weak_io_manager_future)] {
555 return static_cast<bool>(weak_io_manager_future.get());
563 this->weak_factory_gpu_ =
564 std::make_unique<fml::TaskRunnerAffineWeakPtrFactory<Shell>>(this);
571 std::bind(&Shell::OnServiceProtocolScreenshot,
this,
572 std::placeholders::_1, std::placeholders::_2)};
575 std::bind(&Shell::OnServiceProtocolScreenshotSKP,
this,
576 std::placeholders::_1, std::placeholders::_2)};
579 std::bind(&Shell::OnServiceProtocolRunInView,
this, std::placeholders::_1,
580 std::placeholders::_2)};
581 service_protocol_handlers_
584 std::bind(&Shell::OnServiceProtocolFlushUIThreadTasks,
this,
585 std::placeholders::_1, std::placeholders::_2)};
586 service_protocol_handlers_
589 std::bind(&Shell::OnServiceProtocolSetAssetBundlePath,
this,
590 std::placeholders::_1, std::placeholders::_2)};
591 service_protocol_handlers_
594 std::bind(&Shell::OnServiceProtocolGetDisplayRefreshRate,
this,
595 std::placeholders::_1, std::placeholders::_2)};
598 std::bind(&Shell::OnServiceProtocolGetSkSLs,
this, std::placeholders::_1,
599 std::placeholders::_2)};
600 service_protocol_handlers_
603 std::bind(&Shell::OnServiceProtocolEstimateRasterCacheMemory,
this,
604 std::placeholders::_1, std::placeholders::_2)};
607 std::bind(&Shell::OnServiceProtocolReloadAssetFonts,
this,
608 std::placeholders::_1, std::placeholders::_2)};
611 std::bind(&Shell::OnServiceProtocolGetPipelineUsage,
this,
612 std::placeholders::_1, std::placeholders::_2)};
624 platform_latch, io_latch;
629 engine_->ShutdownPlatformIsolates();
630 platiso_latch.Signal();
632 platiso_latch.
Wait();
645 [
this, rasterizer = std::move(rasterizer_), &gpu_latch]()
mutable {
647 this->weak_factory_gpu_.reset();
656 &io_latch]()
mutable {
657 std::weak_ptr<ShellIOManager> weak_io_manager(io_manager);
662 if (platform_view && weak_io_manager.expired()) {
663 platform_view->ReleaseResourceContext();
676 &platform_latch]()
mutable {
677 platform_view.reset();
678 platform_latch.Signal();
680 platform_latch.
Wait();
687 auto platform_queue_id =
690 if (task_queues->Owns(platform_queue_id, ui_queue_id)) {
691 task_queues->Unmerge(platform_queue_id, ui_queue_id);
697 RunConfiguration run_configuration,
698 const std::string& initial_route,
699 const CreateCallback<PlatformView>& on_create_platform_view,
700 const CreateCallback<Rasterizer>& on_create_rasterizer)
const {
707 FML_LOG(ERROR) <<
"MergedPlatformUIThread::kMergeAfterLaunch does not "
713 bool is_gpu_disabled =
false;
716 .SetIfFalse([&is_gpu_disabled] { is_gpu_disabled =
false; })
717 .SetIfTrue([&is_gpu_disabled] { is_gpu_disabled =
true; }));
718 std::unique_ptr<Shell> result = CreateWithSnapshot(
719 PlatformData{}, task_runners_, rasterizer_->GetRasterThreadMerger(),
720 io_manager_, resource_cache_limit_calculator_,
GetSettings(), vm_,
721 vm_->
GetVMData()->GetIsolateSnapshot(), on_create_platform_view,
722 on_create_rasterizer,
723 [
engine = this->engine_.get(), initial_route](
724 Engine::Delegate& delegate,
727 const TaskRunners& task_runners,
const PlatformData& platform_data,
728 const Settings& settings, std::unique_ptr<Animator> animator,
732 const std::shared_ptr<fml::SyncSwitch>& is_gpu_disabled_sync_switch,
733 const std::shared_future<impeller::RuntimeStageBackend>&
734 runtime_stage_backend) {
735 return engine->Spawn(
742 std::move(snapshot_delegate),
743 is_gpu_disabled_sync_switch);
746 result->RunEngine(std::move(run_configuration));
758 ::Dart_NotifyLowMemory();
761 [rasterizer = rasterizer_->GetWeakPtr(), trace_id = trace_id]() {
763 rasterizer->NotifyLowMemoryWarning();
774 engine_->FlushMicrotaskQueue();
779 RunEngine(std::move(run_configuration),
nullptr);
783 RunConfiguration run_configuration,
787 if (!result_callback) {
790 platform_runner->PostTask(
791 [result_callback, run_result]() { result_callback(run_result); });
799 [run_configuration = std::move(run_configuration),
800 weak_engine = weak_engine_, result]()
mutable {
803 <<
"Could not launch engine with configuration - no engine.";
804 result(Engine::RunStatus::Failure);
807 auto run_result = weak_engine->Run(std::move(run_configuration));
809 FML_LOG(ERROR) <<
"Could not launch engine with configuration.";
823 switch (weak_engine_->GetUIIsolateLastError()) {
844 return weak_engine_->UIIsolateHasLivePorts();
855 return weak_engine_->UIIsolateHasPendingMicrotasks();
862bool Shell::Setup(std::unique_ptr<PlatformView>
platform_view,
863 std::unique_ptr<Engine>
engine,
864 std::unique_ptr<Rasterizer> rasterizer,
865 const std::shared_ptr<ShellIOManager>& io_manager) {
875 platform_message_handler_ = platform_view_->GetPlatformMessageHandler();
876 route_messages_through_platform_thread_.store(
true);
878 [
self = weak_factory_.GetWeakPtr()] {
880 self->route_messages_through_platform_thread_.store(false);
883 engine_ = std::move(
engine);
884 rasterizer_ = std::move(rasterizer);
886 weak_io_manager_promise_.set_value(
io_manager_->GetWeakPtr());
889 auto view_embedder = platform_view_->CreateExternalViewEmbedder();
890 rasterizer_->SetExternalViewEmbedder(view_embedder);
891 rasterizer_->SetSnapshotSurfaceProducer(
892 platform_view_->CreateSnapshotSurfaceProducer());
896 weak_engine_ = engine_->GetWeakPtr();
897 weak_rasterizer_ = rasterizer_->GetWeakPtr();
898 weak_platform_view_ = platform_view_->GetWeakPtr();
902 FML_DCHECK(added) <<
"Failed to add the implicit view";
910 engine->SetupDefaultFontManager();
937 return task_runners_;
942 return parent_raster_thread_merger_;
947 return weak_rasterizer_;
957 return weak_platform_view_;
962 return io_manager_->GetWeakPtr();
966 return shutdown_safe_io_task_runner_;
974void Shell::OnPlatformViewCreated(std::unique_ptr<Surface> surface) {
975 TRACE_EVENT0(
"flutter",
"Shell::OnPlatformViewCreated");
988 rasterizer_->DisableThreadMergerIfNeeded();
1000 const bool should_post_raster_task =
1004 [&waiting_for_first_frame = waiting_for_first_frame_,
1005 rasterizer = rasterizer_->GetWeakPtr(),
1006 surface = std::move(surface)
1011 rasterizer->EnableThreadMergerIfNeeded();
1012 rasterizer->Setup(std::move(surface));
1015 waiting_for_first_frame.store(
true);
1018 auto ui_task = [
engine = engine_->GetWeakPtr()] {
1035 raster_task, should_post_raster_task, &latch] {
1036 if (io_manager && !io_manager->GetResourceContext()) {
1037 sk_sp<GrDirectContext> resource_context =
1039 io_manager->NotifyResourceContextAvailable(resource_context);
1047 if (should_post_raster_task) {
1056 if (!should_post_raster_task) {
1066void Shell::OnPlatformViewDestroyed() {
1067 TRACE_EVENT0(
"flutter",
"Shell::OnPlatformViewDestroyed");
1079 rasterizer_->DisableThreadMergerIfNeeded();
1091 auto io_task = [io_manager = io_manager_.get(), &latch]() {
1094 io_manager->GetIsGpuDisabledSyncSwitch()->Execute(
1096 [&] { io_manager->GetSkiaUnrefQueue()->Drain(); }));
1102 auto raster_task = [rasterizer = rasterizer_->GetWeakPtr(),
1109 rasterizer->EnableThreadMergerIfNeeded();
1110 rasterizer->Teardown();
1128 rasterizer_->TeardownExternalViewEmbedder();
1132void Shell::OnPlatformViewScheduleFrame() {
1133 TRACE_EVENT0(
"flutter",
"Shell::OnPlatformViewScheduleFrame");
1138 [
engine = engine_->GetWeakPtr()]() {
1140 engine->ScheduleFrame();
1146void Shell::OnPlatformViewSetViewportMetrics(int64_t
view_id,
1147 const ViewportMetrics& metrics) {
1151 if (!ValidateViewportMetrics(metrics)) {
1158 resource_cache_limit_ =
1159 metrics.physical_width * metrics.physical_height * 12 * 4;
1160 size_t resource_cache_max_bytes =
1161 resource_cache_limit_calculator_->GetResourceCacheMaxBytes();
1163 [rasterizer = rasterizer_->GetWeakPtr(), resource_cache_max_bytes] {
1165 rasterizer->SetResourceCacheMaxBytes(resource_cache_max_bytes, false);
1173 engine->SetViewportMetrics(view_id, metrics);
1178 std::scoped_lock<std::mutex> lock(resize_mutex_);
1180 expected_frame_constraints_[
view_id] =
1181 BoxConstraints(
Size(metrics.physical_min_width_constraint,
1182 metrics.physical_min_height_constraint),
1183 Size(metrics.physical_max_width_constraint,
1184 metrics.physical_max_height_constraint));
1185 device_pixel_ratio_ = metrics.device_pixel_ratio;
1190void Shell::OnPlatformViewDispatchPlatformMessage(
1191 std::unique_ptr<PlatformMessage>
message) {
1193#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
1195 std::scoped_lock lock(misbehaving_message_channels_mutex_);
1196 auto inserted = misbehaving_message_channels_.insert(
message->channel());
1197 if (inserted.second) {
1199 <<
"The '" <<
message->channel()
1200 <<
"' channel sent a message from native to Flutter on a "
1201 "non-platform thread. Platform channel messages must be sent on "
1202 "the platform thread. Failure to do so may result in data loss or "
1203 "crashes, and must be fixed in the plugin or application code "
1204 "creating that channel.\n"
1205 "See https://docs.flutter.dev/platform-integration/"
1206 "platform-channels#channels-and-platform-threading for more "
1219 engine->DispatchPlatformMessage(std::move(message));
1225void Shell::OnPlatformViewDispatchPointerDataPacket(
1226 std::unique_ptr<PointerDataPacket> packet) {
1228 "flutter",
"Shell::OnPlatformViewDispatchPointerDataPacket",
1229 1, &next_pointer_flow_id_);
1236 flow_id = next_pointer_flow_id_]()
mutable {
1238 engine->DispatchPointerDataPacket(std::move(packet), flow_id);
1241 next_pointer_flow_id_++;
1244HitTestResponse Shell::OnPlatformViewHitTest(int64_t
view_id,
1250 return engine_->HitTest(
view_id, offset);
1252 return {.has_platform_view =
false};
1256void Shell::OnPlatformViewDispatchSemanticsAction(int64_t
view_id,
1268 engine->DispatchSemanticsAction(view_id, node_id, action,
1275void Shell::OnPlatformViewSetSemanticsEnabled(
bool enabled) {
1281 [
engine = engine_->GetWeakPtr(), enabled] {
1283 engine->SetSemanticsEnabled(enabled);
1289void Shell::OnPlatformViewSetAccessibilityFeatures(int32_t flags) {
1296 engine->SetAccessibilityFeatures(flags);
1302void Shell::OnPlatformViewRegisterTexture(
1303 std::shared_ptr<flutter::Texture>
texture) {
1308 [rasterizer = rasterizer_->GetWeakPtr(),
texture] {
1310 if (auto registry = rasterizer->GetTextureRegistry()) {
1311 registry->RegisterTexture(texture);
1318void Shell::OnPlatformViewUnregisterTexture(int64_t
texture_id) {
1323 [rasterizer = rasterizer_->GetWeakPtr(),
texture_id]() {
1325 if (auto registry = rasterizer->GetTextureRegistry()) {
1326 registry->UnregisterTexture(texture_id);
1333void Shell::OnPlatformViewMarkTextureFrameAvailable(int64_t
texture_id) {
1339 [rasterizer = rasterizer_->GetWeakPtr(),
texture_id]() {
1343 auto registry = rasterizer->GetTextureRegistry();
1355 texture->MarkNewFrameAvailable();
1360 [
engine = engine_->GetWeakPtr()]() {
1362 engine->ScheduleFrame(false);
1368void Shell::OnPlatformViewSetNextFrameCallback(
const fml::closure& closure) {
1373 [rasterizer = rasterizer_->GetWeakPtr(), closure = closure]() {
1375 rasterizer->SetNextFrameCallback(closure);
1381const Settings& Shell::OnPlatformViewGetSettings()
const {
1386std::shared_ptr<fml::BasicTaskRunner>
1387Shell::OnPlatformViewGetShutdownSafeIOTaskRunner()
const {
1388 return shutdown_safe_io_task_runner_;
1392void Shell::OnAnimatorBeginFrame(
fml::TimePoint frame_target_time,
1393 uint64_t frame_number) {
1399 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1400 latest_frame_target_time_.emplace(frame_target_time);
1403 engine_->BeginFrame(frame_target_time, frame_number);
1413 engine_->NotifyIdle(deadline);
1417void Shell::OnAnimatorUpdateLatestFrameTargetTime(
1423 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1424 if (!latest_frame_target_time_) {
1425 latest_frame_target_time_ = frame_target_time;
1426 }
else if (latest_frame_target_time_ < frame_target_time) {
1427 latest_frame_target_time_ = frame_target_time;
1433void Shell::OnAnimatorDraw(std::shared_ptr<FramePipeline>
pipeline) {
1437 [&waiting_for_first_frame = waiting_for_first_frame_,
1438 &waiting_for_first_frame_condition = waiting_for_first_frame_condition_,
1439 rasterizer = rasterizer_->GetWeakPtr(),
1440 weak_pipeline = std::weak_ptr<FramePipeline>(
pipeline)]()
mutable {
1442 std::shared_ptr<FramePipeline> pipeline = weak_pipeline.lock();
1444 rasterizer->Draw(pipeline);
1447 if (waiting_for_first_frame.load()) {
1448 waiting_for_first_frame.store(false);
1449 waiting_for_first_frame_condition.notify_all();
1456void Shell::OnAnimatorDrawLastLayerTrees(
1457 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) {
1461 [rasterizer = rasterizer_->GetWeakPtr(),
1462 frame_timings_recorder = std::move(frame_timings_recorder)]()
mutable {
1464 rasterizer->DrawLastLayerTrees(std::move(frame_timings_recorder));
1472void Shell::OnEngineUpdateSemantics(int64_t
view_id,
1480 [view = platform_view_->GetWeakPtr(), update = std::move(update),
1483 view->UpdateSemantics(view_id, update, actions);
1489void Shell::OnEngineSetApplicationLocale(std::string locale) {
1495 [view = platform_view_->GetWeakPtr(), locale_holder = std::move(locale)] {
1497 view->SetApplicationLocale(locale_holder);
1503void Shell::OnEngineSetSemanticsTreeEnabled(
bool enabled) {
1509 [view = platform_view_->GetWeakPtr(), enabled] {
1511 view->SetSemanticsTreeEnabled(enabled);
1517void Shell::OnEngineHandlePlatformMessage(
1518 std::unique_ptr<PlatformMessage>
message) {
1523 HandleEngineSkiaMessage(std::move(
message));
1527 if (platform_message_handler_) {
1528 if (route_messages_through_platform_thread_ &&
1529 !platform_message_handler_
1530 ->DoesHandlePlatformMessageOnPlatformThread()) {
1548 [weak_platform_message_handler =
1549 std::weak_ptr<PlatformMessageHandler>(platform_message_handler_),
1551 ui_task_runner->PostTask(
1554 auto platform_message_handler =
1555 weak_platform_message_handler.lock();
1556 if (platform_message_handler) {
1557 platform_message_handler->HandlePlatformMessage(
1563 platform_message_handler_->HandlePlatformMessage(std::move(
message));
1570 view->HandlePlatformMessage(std::move(message));
1576void Shell::OnEngineChannelUpdate(std::string
name,
bool listening) {
1580 [view = platform_view_->GetWeakPtr(),
name = std::move(
name), listening] {
1582 view->SendChannelUpdate(name, listening);
1587void Shell::HandleEngineSkiaMessage(std::unique_ptr<PlatformMessage>
message) {
1590 rapidjson::Document document;
1591 document.Parse(
reinterpret_cast<const char*
>(
data.GetMapping()),
1593 if (document.HasParseError() || !document.IsObject()) {
1596 auto root = document.GetObj();
1597 auto method = root.FindMember(
"method");
1598 if (method->value !=
"Skia.setResourceCacheMaxBytes") {
1601 auto args = root.FindMember(
"args");
1602 if (
args == root.MemberEnd() || !
args->value.IsInt()) {
1607 [rasterizer = rasterizer_->GetWeakPtr(), max_bytes =
args->value.GetInt(),
1608 response =
message->response()] {
1610 rasterizer->SetResourceCacheMaxBytes(static_cast<size_t>(max_bytes),
1616 std::vector<uint8_t>
data = {
'[',
't',
'r',
'u',
'e',
']'};
1618 std::make_unique<fml::DataMapping>(std::move(
data)));
1624void Shell::OnPreEngineRestart() {
1631 [view = platform_view_->GetWeakPtr(), &latch]() {
1633 view->OnPreEngineRestart();
1643void Shell::OnRootIsolateCreated() {
1644 if (is_added_to_service_protocol_) {
1647 auto description = GetServiceProtocolDescription();
1650 [
self = weak_factory_.GetWeakPtr(),
1651 description = std::move(description)]() {
1653 self->vm_->GetServiceProtocol()->AddHandler(self.get(), description);
1656 is_added_to_service_protocol_ =
true;
1660void Shell::UpdateIsolateDescription(
const std::string isolate_name,
1661 int64_t isolate_port) {
1662 Handler::Description description(isolate_port, isolate_name);
1666void Shell::SetNeedsReportTimings(
bool value) {
1667 needs_report_timings_ =
value;
1671std::unique_ptr<std::vector<std::string>> Shell::ComputePlatformResolvedLocale(
1672 const std::vector<std::string>& supported_locale_data) {
1673 return platform_view_->ComputePlatformResolvedLocales(supported_locale_data);
1676void Shell::LoadDartDeferredLibrary(
1677 intptr_t loading_unit_id,
1678 std::unique_ptr<const fml::Mapping> snapshot_data,
1679 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
1681 [
engine = engine_->GetWeakPtr(), loading_unit_id,
1682 data = std::move(snapshot_data),
1683 instructions = std::move(snapshot_instructions)]()
mutable {
1685 engine->LoadDartDeferredLibrary(loading_unit_id, std::move(data),
1686 std::move(instructions));
1691void Shell::LoadDartDeferredLibraryError(intptr_t loading_unit_id,
1692 const std::string error_message,
1696 [
engine = weak_engine_, loading_unit_id, error_message, transient] {
1698 engine->LoadDartDeferredLibraryError(loading_unit_id, error_message,
1704void Shell::UpdateAssetResolverByType(
1705 std::unique_ptr<AssetResolver> updated_asset_resolver,
1711 asset_resolver = std::move(updated_asset_resolver)]()
mutable {
1713 engine->GetAssetManager()->UpdateResolverByType(
1714 std::move(asset_resolver), type);
1720void Shell::RequestDartDeferredLibrary(intptr_t loading_unit_id) {
1722 [view = platform_view_->GetWeakPtr(), loading_unit_id] {
1724 view->RequestDartDeferredLibrary(loading_unit_id);
1730double Shell::GetScaledFontSize(
double unscaled_font_size,
1731 int configuration_id)
const {
1732 return platform_view_->GetScaledFontSize(unscaled_font_size,
1736void Shell::RequestViewFocusChange(
const ViewFocusChangeRequest& request) {
1741 [view = platform_view_->GetWeakPtr(), request] {
1743 view->RequestViewFocusChange(request);
1748void Shell::ReportTimings() {
1752 auto timings = std::move(unreported_timings_);
1753 unreported_timings_ = {};
1756 engine->ReportTimings(timings);
1761size_t Shell::UnreportedFramesCount()
const {
1768void Shell::OnFrameRasterized(
const FrameTiming& timing) {
1778 if (!needs_report_timings_) {
1782 size_t old_count = unreported_timings_.size();
1784 for (
auto phase : FrameTiming::kPhases) {
1785 unreported_timings_.push_back(
1786 timing.Get(phase).ToEpochDelta().ToMicroseconds());
1788 unreported_timings_.push_back(timing.GetLayerCacheCount());
1789 unreported_timings_.push_back(timing.GetLayerCacheBytes());
1790 unreported_timings_.push_back(timing.GetPictureCacheCount());
1791 unreported_timings_.push_back(timing.GetPictureCacheBytes());
1792 unreported_timings_.push_back(timing.GetFrameNumber());
1808 if (!first_frame_rasterized_ || UnreportedFramesCount() >= 100) {
1809 first_frame_rasterized_ =
true;
1811 }
else if (!frame_timings_report_scheduled_) {
1813 constexpr int kBatchTimeInMilliseconds = 1000;
1815 constexpr int kBatchTimeInMilliseconds = 100;
1821 frame_timings_report_scheduled_ =
true;
1823 [
self = weak_factory_gpu_->GetWeakPtr()]() {
1827 self->frame_timings_report_scheduled_ =
false;
1828 if (
self->UnreportedFramesCount() > 0) {
1829 self->ReportTimings();
1837 if (cached_display_refresh_rate_.has_value()) {
1838 return cached_display_refresh_rate_.value();
1840 double display_refresh_rate = display_manager_->GetMainDisplayRefreshRate();
1841 if (display_refresh_rate > 0) {
1842 cached_display_refresh_rate_ =
1851 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1852 FML_CHECK(latest_frame_target_time_.has_value())
1853 <<
"GetLatestFrameTargetTime called before OnAnimatorBeginFrame";
1856 return latest_frame_target_time_.value();
1860bool Shell::ShouldDiscardLayerTree(int64_t
view_id,
1862 std::scoped_lock<std::mutex> lock(resize_mutex_);
1863 auto expected_frame_constraints = ExpectedFrameConstraints(
view_id);
1864 return !expected_frame_constraints.IsSatisfiedBy(
1870 std::string_view method)
const {
1872 auto found = service_protocol_handlers_.find(method);
1873 if (found != service_protocol_handlers_.end()) {
1874 return found->second.first;
1880bool Shell::HandleServiceProtocolMessage(
1881 std::string_view method,
1882 const ServiceProtocolMap&
params,
1883 rapidjson::Document* response) {
1884 auto found = service_protocol_handlers_.find(method);
1885 if (found != service_protocol_handlers_.end()) {
1886 return found->second.second(
params, response);
1892ServiceProtocol::Handler::Description Shell::GetServiceProtocolDescription()
1896 if (!weak_engine_) {
1901 weak_engine_->GetUIIsolateMainPort(),
1902 weak_engine_->GetUIIsolateName(),
1907 std::string error_details) {
1908 auto&
allocator = response->GetAllocator();
1909 response->SetObject();
1910 const int64_t kInvalidParams = -32602;
1912 response->AddMember(
"message",
"Invalid params",
allocator);
1914 rapidjson::Value details(rapidjson::kObjectType);
1915 details.AddMember(
"details", std::move(error_details),
allocator);
1916 response->AddMember(
"data", details,
allocator);
1922 auto&
allocator = response->GetAllocator();
1923 response->SetObject();
1924 const int64_t kJsonServerError = -32000;
1925 response->AddMember(
"code", kJsonServerError,
allocator);
1930bool Shell::OnServiceProtocolScreenshot(
1932 rapidjson::Document* response) {
1934 auto screenshot = rasterizer_->ScreenshotLastLayerTree(
1936 if (screenshot.data) {
1937 response->SetObject();
1938 auto&
allocator = response->GetAllocator();
1939 response->AddMember(
"type",
"Screenshot",
allocator);
1940 rapidjson::Value
image;
1941 image.SetString(
static_cast<const char*
>(screenshot.data->data()),
1951bool Shell::OnServiceProtocolScreenshotSKP(
1953 rapidjson::Document* response) {
1957 response,
"Cannot capture SKP screenshot with Impeller enabled.");
1960 auto screenshot = rasterizer_->ScreenshotLastLayerTree(
1962 if (screenshot.data) {
1963 response->SetObject();
1964 auto&
allocator = response->GetAllocator();
1965 response->AddMember(
"type",
"ScreenshotSkp",
allocator);
1966 rapidjson::Value skp;
1967 skp.SetString(
static_cast<const char*
>(screenshot.data->data()),
1969 response->AddMember(
"skp", skp,
allocator);
1977bool Shell::OnServiceProtocolRunInView(
1979 rapidjson::Document* response) {
1982 if (
params.count(
"mainScript") == 0) {
1984 "'mainScript' parameter is missing.");
1988 if (
params.count(
"assetDirectory") == 0) {
1990 "'assetDirectory' parameter is missing.");
1994 std::string main_script_path =
1996 std::string asset_directory_path =
1999 auto main_script_file_mapping =
2004 std::move(main_script_file_mapping));
2006 RunConfiguration configuration(std::move(isolate_configuration));
2008 configuration.SetEntrypointAndLibrary(engine_->GetLastEntrypoint(),
2009 engine_->GetLastEntrypointLibrary());
2010 configuration.SetEntrypointArgs(engine_->GetLastEntrypointArgs());
2012 configuration.SetEngineId(engine_->GetLastEngineId());
2014 configuration.AddAssetResolver(std::make_unique<DirectoryAssetBundle>(
2021 auto old_asset_manager = engine_->GetAssetManager();
2022 if (old_asset_manager !=
nullptr) {
2023 for (
auto& old_resolver : old_asset_manager->TakeResolvers()) {
2024 if (old_resolver->IsValidAfterAssetManagerChange()) {
2025 configuration.AddAssetResolver(std::move(old_resolver));
2030 auto&
allocator = response->GetAllocator();
2031 response->SetObject();
2032 if (engine_->Restart(std::move(configuration))) {
2033 response->AddMember(
"type",
"Success",
allocator);
2034 auto new_description = GetServiceProtocolDescription();
2035 rapidjson::Value
view(rapidjson::kObjectType);
2036 new_description.Write(
this, view,
allocator);
2037 response->AddMember(
"view", view,
allocator);
2040 FML_DLOG(ERROR) <<
"Could not run configuration in engine.";
2042 "Could not run configuration in engine.");
2051bool Shell::OnServiceProtocolFlushUIThreadTasks(
2053 rapidjson::Document* response) {
2061 response->SetObject();
2062 response->AddMember(
"type",
"Success", response->GetAllocator());
2066bool Shell::OnServiceProtocolGetDisplayRefreshRate(
2068 rapidjson::Document* response) {
2070 response->SetObject();
2071 response->AddMember(
"type",
"DisplayRefreshRate", response->GetAllocator());
2072 response->AddMember(
"fps", display_manager_->GetMainDisplayRefreshRate(),
2073 response->GetAllocator());
2078 return display_manager_->GetMainDisplayRefreshRate();
2088 [
engine = engine_->GetWeakPtr(), factory = std::move(factory),
2091 engine->GetImageGeneratorRegistry()->AddFactory(factory, priority);
2096bool Shell::OnServiceProtocolGetSkSLs(
2098 rapidjson::Document* response) {
2100 response->SetObject();
2101 response->AddMember(
"type",
"GetSkSLs", response->GetAllocator());
2103 rapidjson::Value shaders_json(rapidjson::kObjectType);
2106 std::vector<PersistentCache::SkSLCache> sksls = persistent_cache->LoadSkSLs();
2107 for (
const auto& sksl : sksls) {
2109 sk_sp<SkData> b64_data = SkData::MakeUninitialized(b64_size + 1);
2110 char* b64_char =
static_cast<char*
>(b64_data->writable_data());
2111 Base64::Encode(sksl.value->data(), sksl.value->size(), b64_char);
2112 b64_char[b64_size] = 0;
2113 rapidjson::Value shader_value(b64_char, response->GetAllocator());
2114 std::string_view key_view(
reinterpret_cast<const char*
>(sksl.key->data()),
2117 if (!encode_result.first) {
2120 rapidjson::Value shader_key(encode_result.second, response->GetAllocator());
2121 shaders_json.AddMember(shader_key, shader_value, response->GetAllocator());
2124 response->AddMember(
"SkSLs", shaders_json, response->GetAllocator());
2128bool Shell::OnServiceProtocolEstimateRasterCacheMemory(
2130 rapidjson::Document* response) {
2133 uint64_t layer_cache_byte_size = 0u;
2134 uint64_t picture_cache_byte_size = 0u;
2137 const auto& raster_cache = rasterizer_->compositor_context()->raster_cache();
2138 layer_cache_byte_size = raster_cache.EstimateLayerCacheByteSize();
2139 picture_cache_byte_size = raster_cache.EstimatePictureCacheByteSize();
2142 response->SetObject();
2143 response->AddMember(
"type",
"EstimateRasterCacheMemory",
2144 response->GetAllocator());
2145 response->AddMember<uint64_t>(
"layerBytes", layer_cache_byte_size,
2146 response->GetAllocator());
2147 response->AddMember<uint64_t>(
"pictureBytes", picture_cache_byte_size,
2148 response->GetAllocator());
2153bool Shell::OnServiceProtocolSetAssetBundlePath(
2155 rapidjson::Document* response) {
2158 if (
params.count(
"assetDirectory") == 0) {
2160 "'assetDirectory' parameter is missing.");
2164 auto&
allocator = response->GetAllocator();
2165 response->SetObject();
2167 auto asset_manager = std::make_shared<AssetManager>();
2169 if (!asset_manager->PushFront(std::make_unique<DirectoryAssetBundle>(
2174 FML_DLOG(ERROR) <<
"Could not update asset directory.";
2181 auto old_asset_manager = engine_->GetAssetManager();
2182 if (old_asset_manager !=
nullptr) {
2183 for (
auto& old_resolver : old_asset_manager->TakeResolvers()) {
2184 if (old_resolver->IsValidAfterAssetManagerChange()) {
2185 asset_manager->PushBack(std::move(old_resolver));
2190 if (engine_->UpdateAssetManager(asset_manager)) {
2191 response->AddMember(
"type",
"Success",
allocator);
2192 auto new_description = GetServiceProtocolDescription();
2193 rapidjson::Value
view(rapidjson::kObjectType);
2194 new_description.Write(
this, view,
allocator);
2195 response->AddMember(
"view", view,
allocator);
2198 FML_DLOG(ERROR) <<
"Could not update asset directory.";
2207bool Shell::OnServiceProtocolGetPipelineUsage(
2209 rapidjson::Document* response) {
2212 response->SetObject();
2214 auto context = io_manager_->GetImpellerContext();
2217 FML_DLOG(ERROR) <<
"Pipeline usage profiling only available in Impeller";
2219 response,
"Pipeline usage profiling only available in Impeller");
2223 auto use_counts =
context->GetPipelineLibrary()->GetPipelineUseCounts();
2225 rapidjson::Value pipelines_json(rapidjson::kObjectType);
2227 for (
const auto& pipelineCount : use_counts) {
2228 std::string_view pipeline_name = pipelineCount.first.GetLabel();
2229 rapidjson::Value pipeline_key(pipeline_name.data(), pipeline_name.length(),
2230 response->GetAllocator());
2232 pipelines_json.AddMember(pipeline_key, pipelineCount.second,
2233 response->GetAllocator());
2236 response->AddMember(
"Usages", pipelines_json, response->GetAllocator());
2240void Shell::SendFontChangeNotification() {
2243 rapidjson::Document document;
2244 document.SetObject();
2245 auto&
allocator = document.GetAllocator();
2246 rapidjson::Value message_value;
2250 rapidjson::StringBuffer
buffer;
2251 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
2252 document.Accept(writer);
2254 std::unique_ptr<PlatformMessage> fontsChangeMessage =
2255 std::make_unique<flutter::PlatformMessage>(
2258 OnPlatformViewDispatchPlatformMessage(std::move(fontsChangeMessage));
2261bool Shell::OnServiceProtocolReloadAssetFonts(
2263 rapidjson::Document* response) {
2268 engine_->GetFontCollection().RegisterFonts(engine_->GetAssetManager());
2269 engine_->GetFontCollection().GetFontCollection()->ClearFontFamilyCache();
2270 SendFontChangeNotification();
2272 auto&
allocator = response->GetAllocator();
2273 response->SetObject();
2274 response->AddMember(
"type",
"Success",
allocator);
2279void Shell::OnPlatformViewAddView(int64_t
view_id,
2280 const ViewportMetrics& viewport_metrics,
2286 <<
"Unexpected request to add the implicit view #"
2296 engine->AddView(view_id, viewport_metrics, callback);
2301void Shell::OnPlatformViewRemoveView(int64_t
view_id,
2307 <<
"Unexpected request to remove the implicit view #"
2310 std::scoped_lock<std::mutex> lock(resize_mutex_);
2311 expected_frame_constraints_.erase(
view_id);
2315 [&task_runners = task_runners_,
2316 engine = engine_->GetWeakPtr(),
2317 rasterizer = rasterizer_->GetWeakPtr(),
2321 bool removed = false;
2323 removed = engine->RemoveView(view_id);
2325 task_runners.GetRasterTaskRunner()->
PostTask(
2328 rasterizer->CollectView(view_id);
2338void Shell::OnPlatformViewSendViewFocusEvent(
const ViewFocusEvent& event) {
2339 TRACE_EVENT0(
"flutter",
"Shell:: OnPlatformViewSendViewFocusEvent");
2345 [
engine = engine_->GetWeakPtr(), event = event] {
2347 engine->SendViewFocusEvent(event);
2354 bool base64_encode) {
2356 switch (screenshot_type) {
2359 <<
"Impeller backend cannot produce ScreenshotType::SkiaPicture.";
2369 Rasterizer::Screenshot screenshot;
2378 screenshot = rasterizer->ScreenshotLastLayerTree(screenshot_type,
2392 "WaitForFirstFrame called from thread that can't wait "
2393 "because it is responsible for generating the frame.");
2397 auto now = std::chrono::steady_clock::now();
2398 auto max_duration = std::chrono::steady_clock::time_point::max() - now;
2399 auto desired_duration = std::chrono::milliseconds(timeout.
ToMilliseconds());
2401 now + (desired_duration > max_duration ? max_duration : desired_duration);
2403 std::unique_lock<std::mutex> lock(waiting_for_first_frame_mutex_);
2404 bool success = waiting_for_first_frame_condition_.wait_until(
2405 lock, duration, [&waiting_for_first_frame = waiting_for_first_frame_] {
2406 return !waiting_for_first_frame.load();
2422 engine_->SetupDefaultFontManager();
2423 engine_->GetFontCollection().GetFontCollection()->ClearFontFamilyCache();
2426 SendFontChangeNotification();
2432 return is_gpu_disabled_sync_switch_;
2437 switch (availability) {
2439 is_gpu_disabled_sync_switch_->SetSwitch(
false);
2445 [io_manager = io_manager_.get(), &latch]() {
2446 io_manager->GetSkiaUnrefQueue()->Drain();
2453 is_gpu_disabled_sync_switch_->SetSwitch(
true);
2464 std::vector<DisplayData> display_data;
2465 display_data.reserve(
displays.size());
2466 for (
const auto& display :
displays) {
2467 display_data.push_back(display->GetDisplayData());
2470 [
engine = engine_->GetWeakPtr(),
2471 display_data = std::move(display_data)]() {
2473 engine->SetDisplays(display_data);
2477 display_manager_->HandleDisplayUpdates(std::move(
displays));
2484const std::shared_ptr<PlatformMessageHandler>&
2486 return platform_message_handler_;
2493 return engine_->GetVsyncWaiter();
2496const std::shared_ptr<fml::ConcurrentTaskRunner>
2505BoxConstraints Shell::ExpectedFrameConstraints(int64_t
view_id) {
2506 auto found = expected_frame_constraints_.find(
view_id);
2508 if (found == expected_frame_constraints_.end()) {
2512 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.
std::shared_ptr< fml::BasicTaskRunner > GetShutdownSafeIOTaskRunner()
The IO thread can be used for background tasks, including tasks that perform graphics operations usin...
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)
std::shared_ptr< ContextGLES > context
std::shared_ptr< PipelineGLES > pipeline
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)