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_++;
1230void Shell::OnPlatformViewDispatchSemanticsAction(int64_t
view_id,
1242 engine->DispatchSemanticsAction(view_id, node_id, action,
1249void Shell::OnPlatformViewSetSemanticsEnabled(
bool enabled) {
1255 [
engine = engine_->GetWeakPtr(), enabled] {
1257 engine->SetSemanticsEnabled(enabled);
1263void Shell::OnPlatformViewSetAccessibilityFeatures(int32_t flags) {
1270 engine->SetAccessibilityFeatures(flags);
1276void Shell::OnPlatformViewRegisterTexture(
1277 std::shared_ptr<flutter::Texture>
texture) {
1282 [rasterizer = rasterizer_->GetWeakPtr(),
texture] {
1284 if (auto registry = rasterizer->GetTextureRegistry()) {
1285 registry->RegisterTexture(texture);
1292void Shell::OnPlatformViewUnregisterTexture(int64_t
texture_id) {
1297 [rasterizer = rasterizer_->GetWeakPtr(),
texture_id]() {
1299 if (auto registry = rasterizer->GetTextureRegistry()) {
1300 registry->UnregisterTexture(texture_id);
1307void Shell::OnPlatformViewMarkTextureFrameAvailable(int64_t
texture_id) {
1313 [rasterizer = rasterizer_->GetWeakPtr(),
texture_id]() {
1317 auto registry = rasterizer->GetTextureRegistry();
1329 texture->MarkNewFrameAvailable();
1334 [
engine = engine_->GetWeakPtr()]() {
1336 engine->ScheduleFrame(false);
1342void Shell::OnPlatformViewSetNextFrameCallback(
const fml::closure& closure) {
1347 [rasterizer = rasterizer_->GetWeakPtr(), closure = closure]() {
1349 rasterizer->SetNextFrameCallback(closure);
1355const Settings& Shell::OnPlatformViewGetSettings()
const {
1360void Shell::OnAnimatorBeginFrame(
fml::TimePoint frame_target_time,
1361 uint64_t frame_number) {
1367 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1368 latest_frame_target_time_.emplace(frame_target_time);
1371 engine_->BeginFrame(frame_target_time, frame_number);
1381 engine_->NotifyIdle(deadline);
1385void Shell::OnAnimatorUpdateLatestFrameTargetTime(
1391 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1392 if (!latest_frame_target_time_) {
1393 latest_frame_target_time_ = frame_target_time;
1394 }
else if (latest_frame_target_time_ < frame_target_time) {
1395 latest_frame_target_time_ = frame_target_time;
1401void Shell::OnAnimatorDraw(std::shared_ptr<FramePipeline> pipeline) {
1405 [&waiting_for_first_frame = waiting_for_first_frame_,
1406 &waiting_for_first_frame_condition = waiting_for_first_frame_condition_,
1407 rasterizer = rasterizer_->GetWeakPtr(),
1408 weak_pipeline = std::weak_ptr<FramePipeline>(pipeline)]()
mutable {
1410 std::shared_ptr<FramePipeline> pipeline = weak_pipeline.lock();
1412 rasterizer->Draw(pipeline);
1415 if (waiting_for_first_frame.load()) {
1416 waiting_for_first_frame.store(false);
1417 waiting_for_first_frame_condition.notify_all();
1424void Shell::OnAnimatorDrawLastLayerTrees(
1425 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) {
1429 [rasterizer = rasterizer_->GetWeakPtr(),
1430 frame_timings_recorder = std::move(frame_timings_recorder)]()
mutable {
1432 rasterizer->DrawLastLayerTrees(std::move(frame_timings_recorder));
1440void Shell::OnEngineUpdateSemantics(int64_t
view_id,
1448 [
view = platform_view_->GetWeakPtr(), update = std::move(update),
1451 view->UpdateSemantics(view_id, update, actions);
1457void Shell::OnEngineSetApplicationLocale(std::string locale) {
1463 [
view = platform_view_->GetWeakPtr(), locale_holder = std::move(locale)] {
1465 view->SetApplicationLocale(locale_holder);
1471void Shell::OnEngineSetSemanticsTreeEnabled(
bool enabled) {
1477 [
view = platform_view_->GetWeakPtr(), enabled] {
1479 view->SetSemanticsTreeEnabled(enabled);
1485void Shell::OnEngineHandlePlatformMessage(
1486 std::unique_ptr<PlatformMessage>
message) {
1491 HandleEngineSkiaMessage(std::move(
message));
1495 if (platform_message_handler_) {
1496 if (route_messages_through_platform_thread_ &&
1497 !platform_message_handler_
1498 ->DoesHandlePlatformMessageOnPlatformThread()) {
1516 [weak_platform_message_handler =
1517 std::weak_ptr<PlatformMessageHandler>(platform_message_handler_),
1519 ui_task_runner->PostTask(
1522 auto platform_message_handler =
1523 weak_platform_message_handler.lock();
1524 if (platform_message_handler) {
1525 platform_message_handler->HandlePlatformMessage(
1531 platform_message_handler_->HandlePlatformMessage(std::move(
message));
1538 view->HandlePlatformMessage(std::move(message));
1544void Shell::OnEngineChannelUpdate(std::string
name,
bool listening) {
1548 [
view = platform_view_->GetWeakPtr(),
name = std::move(
name), listening] {
1550 view->SendChannelUpdate(name, listening);
1555void Shell::HandleEngineSkiaMessage(std::unique_ptr<PlatformMessage>
message) {
1558 rapidjson::Document document;
1559 document.Parse(
reinterpret_cast<const char*
>(
data.GetMapping()),
1561 if (document.HasParseError() || !document.IsObject()) {
1564 auto root = document.GetObject();
1565 auto method = root.FindMember(
"method");
1566 if (method->value !=
"Skia.setResourceCacheMaxBytes") {
1569 auto args = root.FindMember(
"args");
1570 if (
args == root.MemberEnd() || !
args->value.IsInt()) {
1575 [rasterizer = rasterizer_->GetWeakPtr(), max_bytes =
args->value.GetInt(),
1576 response =
message->response()] {
1578 rasterizer->SetResourceCacheMaxBytes(static_cast<size_t>(max_bytes),
1584 std::vector<uint8_t>
data = {
'[',
't',
'r',
'u',
'e',
']'};
1586 std::make_unique<fml::DataMapping>(std::move(
data)));
1592void Shell::OnPreEngineRestart() {
1599 [
view = platform_view_->GetWeakPtr(), &latch]() {
1601 view->OnPreEngineRestart();
1611void Shell::OnRootIsolateCreated() {
1612 if (is_added_to_service_protocol_) {
1615 auto description = GetServiceProtocolDescription();
1618 [
self = weak_factory_.GetWeakPtr(),
1619 description = std::move(description)]() {
1621 self->vm_->GetServiceProtocol()->AddHandler(self.get(), description);
1624 is_added_to_service_protocol_ =
true;
1628void Shell::UpdateIsolateDescription(
const std::string isolate_name,
1629 int64_t isolate_port) {
1630 Handler::Description description(isolate_port, isolate_name);
1634void Shell::SetNeedsReportTimings(
bool value) {
1635 needs_report_timings_ =
value;
1639std::unique_ptr<std::vector<std::string>> Shell::ComputePlatformResolvedLocale(
1640 const std::vector<std::string>& supported_locale_data) {
1641 return platform_view_->ComputePlatformResolvedLocales(supported_locale_data);
1644void Shell::LoadDartDeferredLibrary(
1645 intptr_t loading_unit_id,
1646 std::unique_ptr<const fml::Mapping> snapshot_data,
1647 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
1649 [
engine = engine_->GetWeakPtr(), loading_unit_id,
1650 data = std::move(snapshot_data),
1651 instructions = std::move(snapshot_instructions)]()
mutable {
1653 engine->LoadDartDeferredLibrary(loading_unit_id, std::move(data),
1654 std::move(instructions));
1659void Shell::LoadDartDeferredLibraryError(intptr_t loading_unit_id,
1660 const std::string error_message,
1664 [
engine = weak_engine_, loading_unit_id, error_message, transient] {
1666 engine->LoadDartDeferredLibraryError(loading_unit_id, error_message,
1672void Shell::UpdateAssetResolverByType(
1673 std::unique_ptr<AssetResolver> updated_asset_resolver,
1679 asset_resolver = std::move(updated_asset_resolver)]()
mutable {
1681 engine->GetAssetManager()->UpdateResolverByType(
1682 std::move(asset_resolver), type);
1688void Shell::RequestDartDeferredLibrary(intptr_t loading_unit_id) {
1690 [
view = platform_view_->GetWeakPtr(), loading_unit_id] {
1692 view->RequestDartDeferredLibrary(loading_unit_id);
1698double Shell::GetScaledFontSize(
double unscaled_font_size,
1699 int configuration_id)
const {
1700 return platform_view_->GetScaledFontSize(unscaled_font_size,
1704void Shell::RequestViewFocusChange(
const ViewFocusChangeRequest& request) {
1709 [
view = platform_view_->GetWeakPtr(), request] {
1711 view->RequestViewFocusChange(request);
1716void Shell::ReportTimings() {
1720 auto timings = std::move(unreported_timings_);
1721 unreported_timings_ = {};
1724 engine->ReportTimings(timings);
1729size_t Shell::UnreportedFramesCount()
const {
1736void Shell::OnFrameRasterized(
const FrameTiming& timing) {
1746 if (!needs_report_timings_) {
1750 size_t old_count = unreported_timings_.size();
1752 for (
auto phase : FrameTiming::kPhases) {
1753 unreported_timings_.push_back(
1754 timing.Get(phase).ToEpochDelta().ToMicroseconds());
1756 unreported_timings_.push_back(timing.GetLayerCacheCount());
1757 unreported_timings_.push_back(timing.GetLayerCacheBytes());
1758 unreported_timings_.push_back(timing.GetPictureCacheCount());
1759 unreported_timings_.push_back(timing.GetPictureCacheBytes());
1760 unreported_timings_.push_back(timing.GetFrameNumber());
1776 if (!first_frame_rasterized_ || UnreportedFramesCount() >= 100) {
1777 first_frame_rasterized_ =
true;
1779 }
else if (!frame_timings_report_scheduled_) {
1781 constexpr int kBatchTimeInMilliseconds = 1000;
1783 constexpr int kBatchTimeInMilliseconds = 100;
1789 frame_timings_report_scheduled_ =
true;
1791 [
self = weak_factory_gpu_->GetWeakPtr()]() {
1795 self->frame_timings_report_scheduled_ =
false;
1796 if (
self->UnreportedFramesCount() > 0) {
1797 self->ReportTimings();
1805 if (cached_display_refresh_rate_.has_value()) {
1806 return cached_display_refresh_rate_.value();
1808 double display_refresh_rate = display_manager_->GetMainDisplayRefreshRate();
1809 if (display_refresh_rate > 0) {
1810 cached_display_refresh_rate_ =
1819 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1820 FML_CHECK(latest_frame_target_time_.has_value())
1821 <<
"GetLatestFrameTargetTime called before OnAnimatorBeginFrame";
1824 return latest_frame_target_time_.value();
1828bool Shell::ShouldDiscardLayerTree(int64_t
view_id,
1830 std::scoped_lock<std::mutex> lock(resize_mutex_);
1831 auto expected_frame_constraints = ExpectedFrameConstraints(
view_id);
1832 return !expected_frame_constraints.IsSatisfiedBy(
1838 std::string_view method)
const {
1840 auto found = service_protocol_handlers_.find(method);
1841 if (found != service_protocol_handlers_.end()) {
1842 return found->second.first;
1848bool Shell::HandleServiceProtocolMessage(
1849 std::string_view method,
1850 const ServiceProtocolMap&
params,
1851 rapidjson::Document* response) {
1852 auto found = service_protocol_handlers_.find(method);
1853 if (found != service_protocol_handlers_.end()) {
1854 return found->second.second(
params, response);
1860ServiceProtocol::Handler::Description Shell::GetServiceProtocolDescription()
1864 if (!weak_engine_) {
1869 weak_engine_->GetUIIsolateMainPort(),
1870 weak_engine_->GetUIIsolateName(),
1875 std::string error_details) {
1876 auto&
allocator = response->GetAllocator();
1877 response->SetObject();
1878 const int64_t kInvalidParams = -32602;
1880 response->AddMember(
"message",
"Invalid params",
allocator);
1882 rapidjson::Value details(rapidjson::kObjectType);
1883 details.AddMember(
"details", std::move(error_details),
allocator);
1884 response->AddMember(
"data", details,
allocator);
1890 auto&
allocator = response->GetAllocator();
1891 response->SetObject();
1892 const int64_t kJsonServerError = -32000;
1893 response->AddMember(
"code", kJsonServerError,
allocator);
1898bool Shell::OnServiceProtocolScreenshot(
1900 rapidjson::Document* response) {
1902 auto screenshot = rasterizer_->ScreenshotLastLayerTree(
1904 if (screenshot.data) {
1905 response->SetObject();
1906 auto&
allocator = response->GetAllocator();
1907 response->AddMember(
"type",
"Screenshot",
allocator);
1908 rapidjson::Value
image;
1909 image.SetString(
static_cast<const char*
>(screenshot.data->data()),
1919bool Shell::OnServiceProtocolScreenshotSKP(
1921 rapidjson::Document* response) {
1925 response,
"Cannot capture SKP screenshot with Impeller enabled.");
1928 auto screenshot = rasterizer_->ScreenshotLastLayerTree(
1930 if (screenshot.data) {
1931 response->SetObject();
1932 auto&
allocator = response->GetAllocator();
1933 response->AddMember(
"type",
"ScreenshotSkp",
allocator);
1934 rapidjson::Value skp;
1935 skp.SetString(
static_cast<const char*
>(screenshot.data->data()),
1937 response->AddMember(
"skp", skp,
allocator);
1945bool Shell::OnServiceProtocolRunInView(
1947 rapidjson::Document* response) {
1950 if (
params.count(
"mainScript") == 0) {
1952 "'mainScript' parameter is missing.");
1956 if (
params.count(
"assetDirectory") == 0) {
1958 "'assetDirectory' parameter is missing.");
1962 std::string main_script_path =
1964 std::string asset_directory_path =
1967 auto main_script_file_mapping =
1972 std::move(main_script_file_mapping));
1974 RunConfiguration configuration(std::move(isolate_configuration));
1976 configuration.SetEntrypointAndLibrary(engine_->GetLastEntrypoint(),
1977 engine_->GetLastEntrypointLibrary());
1978 configuration.SetEntrypointArgs(engine_->GetLastEntrypointArgs());
1980 configuration.SetEngineId(engine_->GetLastEngineId());
1982 configuration.AddAssetResolver(std::make_unique<DirectoryAssetBundle>(
1989 auto old_asset_manager = engine_->GetAssetManager();
1990 if (old_asset_manager !=
nullptr) {
1991 for (
auto& old_resolver : old_asset_manager->TakeResolvers()) {
1992 if (old_resolver->IsValidAfterAssetManagerChange()) {
1993 configuration.AddAssetResolver(std::move(old_resolver));
1998 auto&
allocator = response->GetAllocator();
1999 response->SetObject();
2000 if (engine_->Restart(std::move(configuration))) {
2001 response->AddMember(
"type",
"Success",
allocator);
2002 auto new_description = GetServiceProtocolDescription();
2003 rapidjson::Value
view(rapidjson::kObjectType);
2008 FML_DLOG(ERROR) <<
"Could not run configuration in engine.";
2010 "Could not run configuration in engine.");
2019bool Shell::OnServiceProtocolFlushUIThreadTasks(
2021 rapidjson::Document* response) {
2029 response->SetObject();
2030 response->AddMember(
"type",
"Success", response->GetAllocator());
2034bool Shell::OnServiceProtocolGetDisplayRefreshRate(
2036 rapidjson::Document* response) {
2038 response->SetObject();
2039 response->AddMember(
"type",
"DisplayRefreshRate", response->GetAllocator());
2040 response->AddMember(
"fps", display_manager_->GetMainDisplayRefreshRate(),
2041 response->GetAllocator());
2046 return display_manager_->GetMainDisplayRefreshRate();
2056 [
engine = engine_->GetWeakPtr(), factory = std::move(factory),
2059 engine->GetImageGeneratorRegistry()->AddFactory(factory, priority);
2064bool Shell::OnServiceProtocolGetSkSLs(
2066 rapidjson::Document* response) {
2068 response->SetObject();
2069 response->AddMember(
"type",
"GetSkSLs", response->GetAllocator());
2071 rapidjson::Value shaders_json(rapidjson::kObjectType);
2074 std::vector<PersistentCache::SkSLCache> sksls = persistent_cache->LoadSkSLs();
2075 for (
const auto& sksl : sksls) {
2077 sk_sp<SkData> b64_data = SkData::MakeUninitialized(b64_size + 1);
2078 char* b64_char =
static_cast<char*
>(b64_data->writable_data());
2079 Base64::Encode(sksl.value->data(), sksl.value->size(), b64_char);
2080 b64_char[b64_size] = 0;
2081 rapidjson::Value shader_value(b64_char, response->GetAllocator());
2082 std::string_view key_view(
reinterpret_cast<const char*
>(sksl.key->data()),
2085 if (!encode_result.first) {
2088 rapidjson::Value shader_key(encode_result.second, response->GetAllocator());
2089 shaders_json.AddMember(shader_key, shader_value, response->GetAllocator());
2092 response->AddMember(
"SkSLs", shaders_json, response->GetAllocator());
2096bool Shell::OnServiceProtocolEstimateRasterCacheMemory(
2098 rapidjson::Document* response) {
2101 uint64_t layer_cache_byte_size = 0u;
2102 uint64_t picture_cache_byte_size = 0u;
2105 const auto& raster_cache = rasterizer_->compositor_context()->raster_cache();
2106 layer_cache_byte_size = raster_cache.EstimateLayerCacheByteSize();
2107 picture_cache_byte_size = raster_cache.EstimatePictureCacheByteSize();
2110 response->SetObject();
2111 response->AddMember(
"type",
"EstimateRasterCacheMemory",
2112 response->GetAllocator());
2113 response->AddMember<uint64_t>(
"layerBytes", layer_cache_byte_size,
2114 response->GetAllocator());
2115 response->AddMember<uint64_t>(
"pictureBytes", picture_cache_byte_size,
2116 response->GetAllocator());
2121bool Shell::OnServiceProtocolSetAssetBundlePath(
2123 rapidjson::Document* response) {
2126 if (
params.count(
"assetDirectory") == 0) {
2128 "'assetDirectory' parameter is missing.");
2132 auto&
allocator = response->GetAllocator();
2133 response->SetObject();
2135 auto asset_manager = std::make_shared<AssetManager>();
2137 if (!asset_manager->PushFront(std::make_unique<DirectoryAssetBundle>(
2142 FML_DLOG(ERROR) <<
"Could not update asset directory.";
2149 auto old_asset_manager = engine_->GetAssetManager();
2150 if (old_asset_manager !=
nullptr) {
2151 for (
auto& old_resolver : old_asset_manager->TakeResolvers()) {
2152 if (old_resolver->IsValidAfterAssetManagerChange()) {
2153 asset_manager->PushBack(std::move(old_resolver));
2158 if (engine_->UpdateAssetManager(asset_manager)) {
2159 response->AddMember(
"type",
"Success",
allocator);
2160 auto new_description = GetServiceProtocolDescription();
2161 rapidjson::Value
view(rapidjson::kObjectType);
2166 FML_DLOG(ERROR) <<
"Could not update asset directory.";
2175bool Shell::OnServiceProtocolGetPipelineUsage(
2177 rapidjson::Document* response) {
2180 response->SetObject();
2182 auto context = io_manager_->GetImpellerContext();
2185 FML_DLOG(ERROR) <<
"Pipeline usage profiling only available in Impeller";
2187 response,
"Pipeline usage profiling only available in Impeller");
2191 auto use_counts = context->GetPipelineLibrary()->GetPipelineUseCounts();
2193 rapidjson::Value pipelines_json(rapidjson::kObjectType);
2195 for (
const auto& pipelineCount : use_counts) {
2196 std::string_view pipeline_name = pipelineCount.first.GetLabel();
2197 rapidjson::Value pipeline_key(pipeline_name.data(), pipeline_name.length(),
2198 response->GetAllocator());
2200 pipelines_json.AddMember(pipeline_key, pipelineCount.second,
2201 response->GetAllocator());
2204 response->AddMember(
"Usages", pipelines_json, response->GetAllocator());
2208void Shell::SendFontChangeNotification() {
2211 rapidjson::Document document;
2212 document.SetObject();
2213 auto&
allocator = document.GetAllocator();
2214 rapidjson::Value message_value;
2218 rapidjson::StringBuffer
buffer;
2219 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
2220 document.Accept(writer);
2222 std::unique_ptr<PlatformMessage> fontsChangeMessage =
2223 std::make_unique<flutter::PlatformMessage>(
2226 OnPlatformViewDispatchPlatformMessage(std::move(fontsChangeMessage));
2229bool Shell::OnServiceProtocolReloadAssetFonts(
2231 rapidjson::Document* response) {
2236 engine_->GetFontCollection().RegisterFonts(engine_->GetAssetManager());
2237 engine_->GetFontCollection().GetFontCollection()->ClearFontFamilyCache();
2238 SendFontChangeNotification();
2240 auto&
allocator = response->GetAllocator();
2241 response->SetObject();
2242 response->AddMember(
"type",
"Success",
allocator);
2247void Shell::OnPlatformViewAddView(int64_t
view_id,
2248 const ViewportMetrics& viewport_metrics,
2254 <<
"Unexpected request to add the implicit view #"
2264 engine->AddView(view_id, viewport_metrics, callback);
2269void Shell::OnPlatformViewRemoveView(int64_t
view_id,
2275 <<
"Unexpected request to remove the implicit view #"
2278 std::scoped_lock<std::mutex> lock(resize_mutex_);
2279 expected_frame_constraints_.erase(
view_id);
2283 [&task_runners = task_runners_,
2284 engine = engine_->GetWeakPtr(),
2285 rasterizer = rasterizer_->GetWeakPtr(),
2289 bool removed = false;
2291 removed = engine->RemoveView(view_id);
2293 task_runners.GetRasterTaskRunner()->
PostTask(
2296 rasterizer->CollectView(view_id);
2306void Shell::OnPlatformViewSendViewFocusEvent(
const ViewFocusEvent& event) {
2307 TRACE_EVENT0(
"flutter",
"Shell:: OnPlatformViewSendViewFocusEvent");
2313 [
engine = engine_->GetWeakPtr(), event = event] {
2315 engine->SendViewFocusEvent(event);
2322 bool base64_encode) {
2324 switch (screenshot_type) {
2327 <<
"Impeller backend cannot produce ScreenshotType::SkiaPicture.";
2337 Rasterizer::Screenshot screenshot;
2346 screenshot = rasterizer->ScreenshotLastLayerTree(screenshot_type,
2360 "WaitForFirstFrame called from thread that can't wait "
2361 "because it is responsible for generating the frame.");
2365 auto now = std::chrono::steady_clock::now();
2366 auto max_duration = std::chrono::steady_clock::time_point::max() - now;
2367 auto desired_duration = std::chrono::milliseconds(timeout.
ToMilliseconds());
2369 now + (desired_duration > max_duration ? max_duration : desired_duration);
2371 std::unique_lock<std::mutex> lock(waiting_for_first_frame_mutex_);
2372 bool success = waiting_for_first_frame_condition_.wait_until(
2373 lock, duration, [&waiting_for_first_frame = waiting_for_first_frame_] {
2374 return !waiting_for_first_frame.load();
2390 engine_->SetupDefaultFontManager();
2391 engine_->GetFontCollection().GetFontCollection()->ClearFontFamilyCache();
2394 SendFontChangeNotification();
2400 return is_gpu_disabled_sync_switch_;
2405 switch (availability) {
2407 is_gpu_disabled_sync_switch_->SetSwitch(
false);
2413 [io_manager = io_manager_.get(), &latch]() {
2414 io_manager->GetSkiaUnrefQueue()->Drain();
2421 is_gpu_disabled_sync_switch_->SetSwitch(
true);
2432 std::vector<DisplayData> display_data;
2433 display_data.reserve(
displays.size());
2434 for (
const auto& display :
displays) {
2435 display_data.push_back(display->GetDisplayData());
2438 [
engine = engine_->GetWeakPtr(),
2439 display_data = std::move(display_data)]() {
2441 engine->SetDisplays(display_data);
2445 display_manager_->HandleDisplayUpdates(std::move(
displays));
2452const std::shared_ptr<PlatformMessageHandler>&
2454 return platform_message_handler_;
2461 return engine_->GetVsyncWaiter();
2464const std::shared_ptr<fml::ConcurrentTaskRunner>
2473BoxConstraints Shell::ExpectedFrameConstraints(int64_t
view_id) {
2474 auto found = expected_frame_constraints_.find(
view_id);
2476 if (found == expected_frame_constraints_.end()) {
2480 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)
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)