7#include <fuchsia/accessibility/semantics/cpp/fidl.h>
8#include <fuchsia/media/cpp/fidl.h>
9#include <lib/async/cpp/task.h>
10#include <lib/zx/eventpair.h>
11#include <lib/zx/thread.h>
12#include <zircon/rights.h>
13#include <zircon/status.h>
14#include <zircon/types.h>
28#include "third_party/skia/include/core/SkPicture.h"
29#include "third_party/skia/include/core/SkSerialProcs.h"
30#include "third_party/skia/include/gpu/ganesh/GrTypes.h"
31#include "third_party/skia/include/ports/SkFontMgr_fuchsia.h"
33#include "../runtime/dart/utils/files.h"
34#include "../runtime/dart/utils/root_inspect_node.h"
47zx_koid_t GetKoid(
const fuchsia::ui::views::ViewRef& view_ref) {
48 zx_handle_t handle = view_ref.reference.get();
49 zx_info_handle_basic_t info;
50 zx_status_t status = zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &info,
51 sizeof(info),
nullptr,
nullptr);
52 return status == ZX_OK ? info.koid : ZX_KOID_INVALID;
55std::unique_ptr<flutter::PlatformMessage> MakeLocalizationPlatformMessage(
56 const fuchsia::intl::Profile& intl_profile) {
57 return std::make_unique<flutter::PlatformMessage>(
73 const fuchsia::media::ProfileProviderSyncPtr& profile_provider,
74 const std::string& role) {
75 ZX_ASSERT(profile_provider);
78 const zx_status_t dup_status =
79 zx::thread::self()->duplicate(ZX_RIGHT_SAME_RIGHTS, &dup);
80 if (dup_status != ZX_OK) {
82 <<
"Failed to duplicate thread handle when setting thread config: "
83 << zx_status_get_string(dup_status)
84 <<
". Thread will run at default priority.";
88 int64_t unused_period;
89 int64_t unused_capacity;
90 const zx_status_t status = profile_provider->RegisterHandlerWithCapacity(
91 std::move(dup), role, 0, 0.f, &unused_period, &unused_capacity);
92 if (status != ZX_OK) {
93 FML_LOG(WARNING) <<
"Failed to set thread role to \"" << role
94 <<
"\": " << zx_status_get_string(status)
95 <<
". Thread will run at default priority.";
101 const std::string& name_prefix,
102 const fuchsia::media::ProfileProviderSyncPtr& profile_provider,
104 ZX_ASSERT(profile_provider);
113 role = name_prefix +
".thread.background";
116 role = name_prefix +
".thread.display";
119 role = name_prefix +
".thread.raster";
122 role = name_prefix +
".thread.normal";
125 FML_LOG(WARNING) <<
"Unknown thread priority "
126 <<
static_cast<int>(config.
priority)
127 <<
". Thread will run at default priority.";
130 ZX_ASSERT(!role.empty());
132 SetThreadRole(profile_provider, role);
138 const std::string& name_prefix,
139 const std::shared_ptr<sys::ServiceDirectory>& services) {
158 std::shared_ptr<fuchsia::media::ProfileProviderSyncPtr>
159 media_profile_provider =
160 std::make_shared<fuchsia::media::ProfileProviderSyncPtr>();
162 const zx_status_t connect_status =
163 services->Connect(media_profile_provider->NewRequest());
164 if (connect_status != ZX_OK) {
166 <<
"Failed to connect to " << fuchsia::media::ProfileProvider::Name_
167 <<
": " << zx_status_get_string(connect_status)
168 <<
" This is not a fatal error, but threads created by the engine "
169 "will run at default priority, regardless of the requested "
174 SetThreadRole(*media_profile_provider, name_prefix +
".type.platform");
178 config_setter = [name_prefix, media_profile_provider](
180 SetThreadConfig(name_prefix, *media_profile_provider, config);
191 thread_host_config.SetUIConfig(
195 thread_host_config.SetIOConfig(
204 std::string thread_label,
205 std::shared_ptr<sys::ServiceDirectory> svc,
206 std::shared_ptr<sys::ServiceDirectory> runner_services,
208 fuchsia::ui::views::ViewCreationToken view_creation_token,
209 std::pair<fuchsia::ui::views::ViewRefControl,
210 fuchsia::ui::views::ViewRef> view_ref_pair,
212 fidl::InterfaceRequest<fuchsia::io::Directory> directory_request,
214 const std::vector<std::string>& dart_entrypoint_args)
216 thread_label_(
std::move(thread_label)),
217 thread_host_(CreateThreadHost(thread_label_, runner_services)),
218 view_creation_token_(
std::move(view_creation_token)),
219 memory_pressure_watcher_binding_(this),
220 latest_memory_pressure_level_(
fuchsia::memorypressure::Level::NORMAL),
221 intercept_all_input_(product_config.get_intercept_all_input()),
222 weak_factory_(this) {
223 Initialize(std::move(view_ref_pair), std::move(svc),
224 std::move(runner_services), std::move(settings),
225 std::move(fdio_ns), std::move(directory_request),
226 std::move(product_config), dart_entrypoint_args);
229void Engine::Initialize(
230 std::pair<fuchsia::ui::views::ViewRefControl, fuchsia::ui::views::ViewRef>
232 std::shared_ptr<sys::ServiceDirectory> svc,
233 std::shared_ptr<sys::ServiceDirectory> runner_services,
236 fidl::InterfaceRequest<fuchsia::io::Directory> directory_request,
238 const std::vector<std::string>& dart_entrypoint_args) {
240 FML_CHECK(view_creation_token_.value.is_valid());
249 platform_task_runner,
255 fuchsia::ui::views::FocuserHandle focuser;
256 fuchsia::ui::views::ViewRefFocusedHandle view_ref_focused;
257 fuchsia::ui::pointer::TouchSourceHandle touch_source;
258 fuchsia::ui::pointer::MouseSourceHandle mouse_source;
260 fuchsia::ui::composition::ViewBoundProtocols view_protocols;
261 view_protocols.set_view_focuser(focuser.NewRequest());
262 view_protocols.set_view_ref_focused(view_ref_focused.NewRequest());
263 view_protocols.set_touch_source(touch_source.NewRequest());
264 view_protocols.set_mouse_source(mouse_source.NewRequest());
267 fuchsia::ui::composition::FlatlandHandle flatland;
268 zx_status_t flatland_status =
269 runner_services->Connect<fuchsia::ui::composition::Flatland>(
270 flatland.NewRequest());
271 if (flatland_status != ZX_OK) {
272 FML_LOG(WARNING) <<
"fuchsia::ui::composition::Flatland connection failed: "
273 << zx_status_get_string(flatland_status);
277 fuchsia::accessibility::semantics::SemanticsManagerHandle semantics_manager;
278 zx_status_t semantics_status =
280 ->Connect<fuchsia::accessibility::semantics::SemanticsManager>(
281 semantics_manager.NewRequest());
282 if (semantics_status != ZX_OK) {
284 <<
"fuchsia::accessibility::semantics::SemanticsManager connection "
286 << zx_status_get_string(semantics_status);
290 fuchsia::ui::input::ImeServiceHandle ime_service;
291 zx_status_t ime_status =
292 runner_services->Connect<fuchsia::ui::input::ImeService>(
293 ime_service.NewRequest());
294 if (ime_status != ZX_OK) {
295 FML_LOG(WARNING) <<
"fuchsia::ui::input::ImeService connection failed: "
296 << zx_status_get_string(ime_status);
300 fuchsia::ui::input3::KeyboardHandle keyboard;
301 zx_status_t keyboard_status =
302 runner_services->Connect<fuchsia::ui::input3::Keyboard>(
303 keyboard.NewRequest());
305 <<
"fuchsia::ui::input3::Keyboard connection failed: "
306 << zx_status_get_string(keyboard_status);
309 fuchsia::ui::pointerinjector::RegistryHandle pointerinjector_registry;
310 zx_status_t pointerinjector_registry_status =
311 runner_services->Connect<fuchsia::ui::pointerinjector::Registry>(
312 pointerinjector_registry.NewRequest());
313 if (pointerinjector_registry_status != ZX_OK) {
315 <<
"fuchsia::ui::pointerinjector::Registry connection failed: "
316 << zx_status_get_string(pointerinjector_registry_status);
320 fuchsia::ui::views::ViewRef platform_view_ref;
321 view_ref_pair.second.Clone(&platform_view_ref);
322 fuchsia::ui::views::ViewRef accessibility_view_ref;
323 view_ref_pair.second.Clone(&accessibility_view_ref);
324 fuchsia::ui::views::ViewRef isolate_view_ref;
325 view_ref_pair.second.Clone(&isolate_view_ref);
333 fml::closure session_error_callback = [task_runner = platform_task_runner,
334 weak = weak_factory_.GetWeakPtr()]() {
335 task_runner->PostTask([weak]() {
337 FML_LOG(ERROR) <<
"Terminating from session_error_callback";
346 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
348 auto session_inspect_node =
351 [
this, &view_embedder_latch,
352 session_inspect_node = std::move(session_inspect_node),
353 flatland = std::move(flatland),
354 session_error_callback = std::move(session_error_callback),
355 view_creation_token = std::move(view_creation_token_),
356 view_protocols = std::move(view_protocols),
357 request = parent_viewport_watcher.NewRequest(),
358 view_ref_pair = std::move(view_ref_pair),
360 if (software_rendering) {
361 surface_producer_ = std::make_shared<SoftwareSurfaceProducer>();
363 surface_producer_ = std::make_shared<VulkanSurfaceProducer>();
366 flatland_connection_ = std::make_shared<FlatlandConnection>(
367 thread_label_, std::move(flatland),
368 std::move(session_error_callback), [](
auto) {});
370 fuchsia::ui::views::ViewIdentityOnCreation view_identity = {
371 .view_ref = std::move(view_ref_pair.second),
372 .view_ref_control = std::move(view_ref_pair.first)};
373 view_embedder_ = std::make_shared<ExternalViewEmbedder>(
374 std::move(view_creation_token), std::move(view_identity),
375 std::move(view_protocols), std::move(request), flatland_connection_,
376 surface_producer_, intercept_all_input_);
378 view_embedder_latch.
Signal();
380 view_embedder_latch.
Wait();
383 set_semantics_enabled_callback = [
this](
bool enabled) {
392 dispatch_semantics_action_callback =
404 const std::string accessibility_inspect_name =
405 std::to_string(GetKoid(accessibility_view_ref));
406 accessibility_bridge_ = std::make_unique<AccessibilityBridge>(
407 std::move(set_semantics_enabled_callback),
408 std::move(dispatch_semantics_action_callback),
409 std::move(semantics_manager), std::move(accessibility_view_ref),
411 std::move(accessibility_inspect_name)));
414 &Engine::DebugWireframeSettingsChanged,
this, std::placeholders::_1);
417 &Engine::CreateView,
this, std::placeholders::_1, std::placeholders::_2,
418 std::placeholders::_3, std::placeholders::_4, std::placeholders::_5);
421 &Engine::UpdateView,
this, std::placeholders::_1, std::placeholders::_2,
422 std::placeholders::_3, std::placeholders::_4);
425 &Engine::DestroyView,
this, std::placeholders::_1, std::placeholders::_2);
428 std::bind(&Engine::CreateSurface,
this);
433 fit::closure on_session_listener_error_callback =
434 [task_runner = platform_task_runner,
435 weak = weak_factory_.GetWeakPtr()]() {
436 task_runner->PostTask([weak]() {
438 FML_LOG(ERROR) <<
"Terminating from "
439 "on_session_listener_error_callback";
449 settings, task_runners.GetIOTaskRunner());
450 run_configuration.SetEntrypointArgs(std::move(dart_entrypoint_args));
454 accessibility_bridge_->AddSemanticsNodeUpdate(updates, pixel_ratio);
458 [
this](
const std::string&
message) {
459 accessibility_bridge_->RequestAnnounce(
message);
465 [
this, view_ref = std::move(platform_view_ref),
466 parent_viewport_watcher = std::move(parent_viewport_watcher),
467 ime_service = std::move(ime_service), keyboard = std::move(keyboard),
468 focuser = std::move(focuser),
469 view_ref_focused = std::move(view_ref_focused),
470 touch_source = std::move(touch_source),
471 mouse_source = std::move(mouse_source),
472 pointerinjector_registry = std::move(pointerinjector_registry),
473 on_session_listener_error_callback =
474 std::move(on_session_listener_error_callback),
475 on_enable_wireframe_callback =
476 std::move(on_enable_wireframe_callback),
477 on_create_view_callback = std::move(on_create_view_callback),
478 on_update_view_callback = std::move(on_update_view_callback),
479 on_destroy_view_callback = std::move(on_destroy_view_callback),
480 on_create_surface_callback = std::move(on_create_surface_callback),
481 on_semantics_node_update_callback =
482 std::move(on_semantics_node_update_callback),
483 on_request_announce_callback =
484 std::move(on_request_announce_callback),
485 external_view_embedder = GetExternalViewEmbedder(),
486 await_vsync_callback =
488 flatland_connection_->AwaitVsync(cb);
490 await_vsync_for_secondary_callback_callback =
492 flatland_connection_->AwaitVsyncForSecondaryCallback(cb);
499 on_shader_warmup_callback =
501 const std::vector<std::string>& skp_names,
502 std::function<void(uint32_t)> completion_callback,
506 ->GetConcurrentMessageLoop()
509 shell.GetTaskRunners().GetRasterTaskRunner().get(),
513 skp_names, completion_callback);
516 WarmupSkps(shell.GetDartVM()
517 ->GetConcurrentMessageLoop()
520 shell.GetTaskRunners().GetRasterTaskRunner().get(),
521 surface_producer_, SkISize::Make(1024, 600),
524 std::nullopt, std::nullopt);
528 return std::make_unique<flutter_runner::PlatformView>(
529 shell, shell.GetTaskRunners(), std::move(view_ref),
530 std::move(external_view_embedder), std::move(ime_service),
531 std::move(keyboard), std::move(touch_source),
532 std::move(mouse_source), std::move(focuser),
533 std::move(view_ref_focused), std::move(parent_viewport_watcher),
534 std::move(pointerinjector_registry),
535 std::move(on_enable_wireframe_callback),
536 std::move(on_create_view_callback),
537 std::move(on_update_view_callback),
538 std::move(on_destroy_view_callback),
539 std::move(on_create_surface_callback),
540 std::move(on_semantics_node_update_callback),
541 std::move(on_request_announce_callback),
542 std::move(on_shader_warmup_callback),
543 std::move(await_vsync_callback),
544 std::move(await_vsync_for_secondary_callback_callback),
551 return std::make_unique<flutter::Rasterizer>(shell);
555 std::bind(&Engine::OnMainIsolateStart,
this);
557 std::bind([weak = weak_factory_.GetWeakPtr(),
558 runner = task_runners.GetPlatformTaskRunner()]() {
559 runner->PostTask([weak = std::move(weak)] {
561 weak->OnMainIsolateShutdown();
567 fuchsia::fonts::ProviderSyncPtr sync_font_provider;
568 runner_services->Connect(sync_font_provider.NewRequest());
570 sync_font_provider.Unbind().TakeChannel().release();
576 std::move(task_runners),
578 std::move(on_create_platform_view),
579 std::move(on_create_rasterizer)
584 FML_LOG(ERROR) <<
"Could not launch the shell.";
590 isolate_configurator_ = std::make_unique<IsolateConfigurator>(
591 std::move(fdio_ns), directory_request.TakeChannel(),
592 std::move(isolate_view_ref.reference));
596 shell_->GetPlatformView()->NotifyCreated();
603 memory_pressure_provider_.set_error_handler([](zx_status_t status) {
605 <<
"Failed to connect to " << fuchsia::memorypressure::Provider::Name_
606 <<
": " << zx_status_get_string(status)
607 <<
" This is not a fatal error, but the heap will not be "
608 <<
" compacted when memory is low.";
615 ZX_ASSERT(runner_services->Connect(
616 memory_pressure_provider_.NewRequest()) == ZX_OK);
618 FML_VLOG(1) <<
"Registering memorypressure watcher";
622 memory_pressure_provider_->RegisterWatcher(
623 memory_pressure_watcher_binding_.NewBinding());
631 intl_property_provider_.set_error_handler([](zx_status_t status) {
632 FML_LOG(WARNING) <<
"Failed to connect to "
633 << fuchsia::intl::PropertyProvider::Name_ <<
": "
634 << zx_status_get_string(status)
635 <<
" This is not a fatal error, but the user locale "
636 <<
" preferences will not be forwarded to flutter apps";
642 ZX_ASSERT(runner_services->Connect(intl_property_provider_.NewRequest()) ==
645 auto get_profile_callback = [weak = weak_factory_.GetWeakPtr()](
646 const fuchsia::intl::Profile& profile) {
650 if (!profile.has_locales()) {
651 FML_LOG(WARNING) <<
"Got intl Profile without locales";
653 auto message = MakeLocalizationPlatformMessage(profile);
654 FML_VLOG(1) <<
"Sending LocalizationPlatformMessage";
655 weak->shell_->GetPlatformView()->DispatchPlatformMessage(
659 FML_VLOG(1) <<
"Requesting intl Profile";
662 intl_property_provider_->GetProfile(get_profile_callback);
665 intl_property_provider_.events().OnChange = [
this, runner_services,
666 get_profile_callback]() {
667 FML_VLOG(1) << fuchsia::intl::PropertyProvider::Name_ <<
": OnChange";
668 runner_services->Connect(intl_property_provider_.NewRequest());
669 intl_property_provider_->GetProfile(get_profile_callback);
673 auto on_run_failure = [weak = weak_factory_.GetWeakPtr()]() {
677 FML_LOG(ERROR) <<
"Terminating from on_run_failure";
682 shell_->GetTaskRunners().GetUITaskRunner()->PostTask(
684 run_configuration = std::move(run_configuration),
691 if (
engine->Run(std::move(run_configuration)) ==
705 view_embedder_.reset();
706 flatland_connection_.reset();
707 surface_producer_.reset();
708 view_embedder_latch.
Signal();
710 view_embedder_latch.
Wait();
713std::optional<uint32_t> Engine::GetEngineReturnCode()
const {
717 std::optional<uint32_t> code;
720 shell_->GetTaskRunners().GetUITaskRunner(),
721 [&latch, &code,
engine = shell_->GetEngine()]() {
723 code = engine->GetUIIsolateReturnCode();
731void Engine::OnMainIsolateStart() {
732 if (!isolate_configurator_ ||
733 !isolate_configurator_->ConfigureCurrentIsolate()) {
734 FML_LOG(ERROR) <<
"Could not configure some native embedder bindings for a "
739void Engine::OnMainIsolateShutdown() {
743void Engine::Terminate() {
749void Engine::DebugWireframeSettingsChanged(
bool enabled) {
752 shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask([]() {
758void Engine::CreateView(int64_t
view_id,
759 ViewCallback on_view_created,
760 ViewCreatedCallback on_view_bound,
764 shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask(
765 [
this,
view_id, hit_testable, focusable,
766 on_view_created = std::move(on_view_created),
767 on_view_bound = std::move(on_view_bound)]() {
769 view_embedder_->CreateView(
view_id, std::move(on_view_created),
770 std::move(on_view_bound));
771 view_embedder_->SetViewProperties(
view_id, SkRect::MakeEmpty(),
772 hit_testable, focusable);
776void Engine::UpdateView(int64_t
view_id,
777 SkRect occlusion_hint,
781 shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask(
782 [
this,
view_id, occlusion_hint, hit_testable, focusable]() {
784 view_embedder_->SetViewProperties(
view_id, occlusion_hint, hit_testable,
789void Engine::DestroyView(int64_t
view_id, ViewIdCallback on_view_unbound) {
792 shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask(
793 [
this,
view_id, on_view_unbound = std::move(on_view_unbound)]() {
795 view_embedder_->DestroyView(
view_id, std::move(on_view_unbound));
799std::unique_ptr<flutter::Surface> Engine::CreateSurface() {
800 return std::make_unique<Surface>(thread_label_, GetExternalViewEmbedder(),
801 surface_producer_->gr_context());
804std::shared_ptr<flutter::ExternalViewEmbedder>
805Engine::GetExternalViewEmbedder() {
807 return view_embedder_;
810#if !defined(DART_PRODUCT)
811void Engine::WriteProfileToTrace()
const {
812 Dart_Port main_port = shell_->GetEngine()->GetUIIsolateMainPort();
814 bool success = Dart_WriteProfileToTimeline(main_port, &
error);
816 FML_LOG(ERROR) <<
"Failed to write Dart profile to trace: " <<
error;
822void Engine::WarmupSkps(
825 std::shared_ptr<SurfaceProducer> surface_producer,
827 std::shared_ptr<flutter::AssetManager> asset_manager,
828 std::optional<
const std::vector<std::string>> skp_names,
829 std::optional<std::function<
void(uint32_t)>> maybe_completion_callback,
833 auto completion_callback = [maybe_completion_callback](uint32_t skp_count) {
834 if (maybe_completion_callback.has_value() &&
835 maybe_completion_callback.value()) {
836 maybe_completion_callback.value()(skp_count);
850 std::unique_ptr<SurfaceProducerSurface>* skp_warmup_surface =
851 new std::unique_ptr<SurfaceProducerSurface>(
nullptr);
855 concurrent_task_runner->
PostTask([raster_task_runner, size,
856 skp_warmup_surface, surface_producer,
857 asset_manager, skp_names,
858 completion_callback, synchronous]() {
859 TRACE_DURATION(
"flutter",
"DeserializeSkps");
860 std::vector<std::unique_ptr<fml::Mapping>> skp_mappings;
862 for (
auto& skp_name : skp_names.
value()) {
863 auto skp_mapping = asset_manager->GetAsMapping(skp_name);
865 skp_mappings.push_back(std::move(skp_mapping));
867 FML_LOG(ERROR) <<
"Failed to get mapping for " << skp_name;
871 skp_mappings = asset_manager->GetAsMappings(
".*\\.skp$",
"shaders");
874 if (skp_mappings.empty()) {
876 <<
"Engine::WarmupSkps got zero SKP mappings, returning early";
877 completion_callback(0);
881 size_t total_size = 0;
882 for (
auto& mapping : skp_mappings) {
883 total_size += mapping->GetSize();
886 FML_LOG(INFO) <<
"Shader warmup got " << skp_mappings.size()
887 <<
" skp's with a total size of " << total_size <<
" bytes";
889 std::vector<sk_sp<SkPicture>> pictures;
891 for (
auto& mapping : skp_mappings) {
892 std::unique_ptr<SkMemoryStream> stream =
893 SkMemoryStream::MakeDirect(mapping->GetMapping(), mapping->GetSize());
894 SkDeserialProcs procs = {0};
897 sk_sp<SkPicture> picture =
898 SkPicture::MakeFromStream(stream.get(), &procs);
900 FML_LOG(ERROR) <<
"Failed to deserialize picture " <<
i;
906 raster_task_runner->
PostTask([picture, skp_warmup_surface, size,
907 surface_producer, completion_callback,
i,
908 count = skp_mappings.size(), synchronous] {
909 TRACE_DURATION(
"flutter",
"WarmupSkp");
910 if (*skp_warmup_surface == nullptr) {
911 skp_warmup_surface->reset(
912 surface_producer->ProduceOffscreenSurface(size).release());
914 if (*skp_warmup_surface == nullptr) {
915 FML_LOG(ERROR) <<
"Failed to create offscreen warmup surface";
918 completion_callback(0);
924 (*skp_warmup_surface)
927 ->drawPicture(picture);
929 if (
i == count - 1) {
934 completion_callback(count);
937 if (surface_producer->gr_context()) {
940 surface_producer->gr_context()->flushAndSubmit();
944 struct GrFlushInfo flush_info;
945 flush_info.fFinishedContext = skp_warmup_surface;
946 flush_info.fFinishedProc = [](
void* skp_warmup_surface) {
947 delete static_cast<std::unique_ptr<SurfaceProducerSurface>*
>(
951 surface_producer->gr_context()->flush(flush_info);
952 surface_producer->gr_context()->submit(
953 synchronous ? GrSyncCpu::kYes : GrSyncCpu::kNo);
956 if (
i == count - 1) {
957 delete skp_warmup_surface;
966void Engine::OnLevelChanged(
967 fuchsia::memorypressure::Level level,
968 fuchsia::memorypressure::Watcher::OnLevelChangedCallback
callback) {
974 FML_LOG(WARNING) <<
"memorypressure watcher: OnLevelChanged from "
975 <<
static_cast<int>(latest_memory_pressure_level_) <<
" to "
976 <<
static_cast<int>(level);
978 if (latest_memory_pressure_level_ == fuchsia::memorypressure::Level::NORMAL &&
979 (level == fuchsia::memorypressure::Level::WARNING ||
980 level == fuchsia::memorypressure::Level::CRITICAL)) {
982 <<
"memorypressure watcher: notifying Flutter that memory is low";
983 shell_->NotifyLowMemoryWarning();
985 latest_memory_pressure_level_ = level;
static inspect::Node CreateRootChild(const std::string &name)
static std::shared_ptr< AssetManager > asset_manager()
static PersistentCache * GetCacheForProcess()
static RunConfiguration InferFromSettings(const Settings &settings, const fml::RefPtr< fml::TaskRunner > &io_worker=nullptr, IsolateLaunchType launch_type=IsolateLaunchType::kNewGroup)
Attempts to infer a run configuration from the settings object. This tries to create a run configurat...
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...
std::function< std::unique_ptr< T >(Shell &)> CreateCallback
std::function< void(bool)> SetSemanticsEnabledCallback
std::function< void(int32_t, flutter::SemanticsAction)> DispatchSemanticsActionCallback
static flutter::ThreadHost CreateThreadHost(const std::string &name_prefix, const std::shared_ptr< sys::ServiceDirectory > &runner_services=nullptr)
Engine(Delegate &delegate, std::string thread_label, std::shared_ptr< sys::ServiceDirectory > svc, std::shared_ptr< sys::ServiceDirectory > runner_services, flutter::Settings settings, fuchsia::ui::views::ViewCreationToken view_creation_token, std::pair< fuchsia::ui::views::ViewRefControl, fuchsia::ui::views::ViewRef > view_ref_pair, UniqueFDIONS fdio_ns, fidl::InterfaceRequest< fuchsia::io::Directory > directory_request, FlutterRunnerProductConfiguration product_config, const std::vector< std::string > &dart_entrypoint_args)
bool enable_shader_warmup_dart_hooks()
bool software_rendering()
bool enable_shader_warmup()
An interface over the ability to schedule tasks on a TaskRunner.
virtual void PostTask(const fml::closure &task)=0
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
@ kNormal
Default priority level.
@ kRaster
Suitable for thread which raster data.
@ kBackground
Suitable for threads that shouldn't disrupt high priority work.
@ kDisplay
Suitable for threads which generate data for the display.
static void SetCurrentThreadName(const ThreadConfig &config)
G_BEGIN_DECLS GBytes * message
const uint8_t uint32_t uint32_t GError ** error
G_BEGIN_DECLS FlutterViewId view_id
FlutterDesktopBinaryReply callback
#define FML_VLOG(verbose_level)
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
static constexpr FlutterViewId kImplicitViewId
std::function< void(const std::vector< std::string > &, std::function< void(uint32_t)>, uint64_t, uint64_t)> OnShaderWarmupCallback
fit::function< void(int64_t, ViewCallback, ViewCreatedCallback, bool, bool)> OnCreateViewCallback
fit::function< void(int64_t, ViewIdCallback)> OnDestroyViewCallback
std::function< void(fml::TimePoint, fml::TimePoint)> FireCallbackCallback
fit::function< void(int64_t, SkRect, bool, bool)> OnUpdateViewCallback
fit::function< std::unique_ptr< flutter::Surface >()> OnCreateSurfaceCallback
fit::function< void(flutter::SemanticsNodeUpdates, float)> OnSemanticsNodeUpdateCallback
fml::MallocMapping MakeLocalizationPlatformMessageData(const Profile &intl_profile)
fit::function< void(std::string)> OnRequestAnnounceCallback
fit::function< void(bool)> OnEnableWireframeCallback
sk_sp< SkImage > DeserializeImageWithoutData(const void *data, size_t length, void *ctx)
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
sk_sp< SkTypeface > DeserializeTypefaceWithoutData(const void *data, size_t length, void *ctx)
fml::Thread::ThreadConfigSetter ThreadConfigSetter
internal::CopyableLambda< T > MakeCopyable(T lambda)
std::function< void()> closure
std::function< void(const DartIsolate &)> root_isolate_create_callback
uint32_t font_initialization_data
fml::closure root_isolate_shutdown_callback
static std::string MakeThreadName(Type type, const std::string &prefix)
Use the prefix and thread type to generator a thread name.
void SetRasterConfig(const ThreadConfig &)
Specified the IO Thread Config, meanwhile set the mask.
The collection of all the threads used by the engine.
std::unique_ptr< fml::Thread > io_thread
std::unique_ptr< fml::Thread > raster_thread
std::unique_ptr< fml::Thread > ui_thread
The ThreadConfig is the thread info include thread name, thread priority.
#define TRACE_EVENT0(category_group, name)