diff --git a/engine/src/flutter/lib/ui/dart_ui.cc b/engine/src/flutter/lib/ui/dart_ui.cc index be820520db2..bf3e190deab 100644 --- a/engine/src/flutter/lib/ui/dart_ui.cc +++ b/engine/src/flutter/lib/ui/dart_ui.cc @@ -4,6 +4,7 @@ #include "flutter/lib/ui/dart_ui.h" +#include "flutter/common/settings.h" #include "flutter/fml/build_config.h" #include "flutter/lib/ui/compositing/scene.h" #include "flutter/lib/ui/compositing/scene_builder.h" @@ -87,13 +88,26 @@ void DartUI::InitForGlobal() { } } -void DartUI::InitForIsolate() { +void DartUI::InitForIsolate(const Settings& settings) { FML_DCHECK(g_natives); - Dart_Handle result = Dart_SetNativeResolver( - Dart_LookupLibrary(ToDart("dart:ui")), GetNativeFunction, GetSymbol); + + Dart_Handle dart_ui = Dart_LookupLibrary(ToDart("dart:ui")); + if (Dart_IsError(dart_ui)) { + Dart_PropagateError(dart_ui); + } + + Dart_Handle result = + Dart_SetNativeResolver(dart_ui, GetNativeFunction, GetSymbol); if (Dart_IsError(result)) { Dart_PropagateError(result); } + + if (settings.enable_impeller) { + result = Dart_SetField(dart_ui, ToDart("_impellerEnabled"), Dart_True()); + if (Dart_IsError(result)) { + Dart_PropagateError(result); + } + } } } // namespace flutter diff --git a/engine/src/flutter/lib/ui/dart_ui.h b/engine/src/flutter/lib/ui/dart_ui.h index 3cfbc9ac469..9b6bfe0926b 100644 --- a/engine/src/flutter/lib/ui/dart_ui.h +++ b/engine/src/flutter/lib/ui/dart_ui.h @@ -5,6 +5,7 @@ #ifndef FLUTTER_LIB_UI_DART_UI_H_ #define FLUTTER_LIB_UI_DART_UI_H_ +#include "flutter/common/settings.h" #include "flutter/fml/macros.h" namespace flutter { @@ -12,7 +13,7 @@ namespace flutter { class DartUI { public: static void InitForGlobal(); - static void InitForIsolate(); + static void InitForIsolate(const Settings& settings); private: FML_DISALLOW_IMPLICIT_CONSTRUCTORS(DartUI); diff --git a/engine/src/flutter/lib/ui/natives.dart b/engine/src/flutter/lib/ui/natives.dart index 1f9a8c33d0f..b7830fe23a7 100644 --- a/engine/src/flutter/lib/ui/natives.dart +++ b/engine/src/flutter/lib/ui/natives.dart @@ -106,3 +106,8 @@ typedef _ScheduleImmediateClosure = void Function(void Function()); // See also https://github.com/dart-lang/sdk/blob/main/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart @pragma('vm:entry-point') _ScheduleImmediateClosure _getScheduleMicrotaskClosure() => _scheduleMicrotask; + +// Used internally to indicate whether the Engine is using Impeller for +// rendering +@pragma('vm:entry-point') +bool _impellerEnabled = false; diff --git a/engine/src/flutter/runtime/dart_isolate.cc b/engine/src/flutter/runtime/dart_isolate.cc index dd415f64c5f..4bdae5a7019 100644 --- a/engine/src/flutter/runtime/dart_isolate.cc +++ b/engine/src/flutter/runtime/dart_isolate.cc @@ -462,7 +462,7 @@ bool DartIsolate::LoadLibraries() { DartIO::InitForIsolate(may_insecurely_connect_to_all_domains_, domain_network_policy_); - DartUI::InitForIsolate(); + DartUI::InitForIsolate(GetIsolateGroupData().GetSettings()); const bool is_service_isolate = Dart_IsServiceIsolate(isolate()); diff --git a/engine/src/flutter/runtime/dart_isolate_unittests.cc b/engine/src/flutter/runtime/dart_isolate_unittests.cc index 698eb4324e3..0bb56a542b3 100644 --- a/engine/src/flutter/runtime/dart_isolate_unittests.cc +++ b/engine/src/flutter/runtime/dart_isolate_unittests.cc @@ -178,6 +178,76 @@ TEST_F(DartIsolateTest, CanRunDartCodeCodeSynchronously) { })); } +TEST_F(DartIsolateTest, ImpellerFlagIsCorrectWhenTrue) { + ASSERT_FALSE(DartVMRef::IsInstanceRunning()); + auto settings = CreateSettingsForFixture(); + settings.enable_impeller = true; + auto vm_ref = DartVMRef::Create(settings); + TaskRunners task_runners(GetCurrentTestName(), // + GetCurrentTaskRunner(), // + GetCurrentTaskRunner(), // + GetCurrentTaskRunner(), // + GetCurrentTaskRunner() // + ); + auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners, "main", + {}, GetDefaultKernelFilePath()); + + ASSERT_TRUE(isolate); + ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running); + ASSERT_TRUE(isolate->RunInIsolateScope([settings]() -> bool { + Dart_Handle dart_ui = ::Dart_LookupLibrary(tonic::ToDart("dart:ui")); + if (tonic::CheckAndHandleError(dart_ui)) { + return false; + } + Dart_Handle impeller_enabled = + ::Dart_GetField(dart_ui, tonic::ToDart("_impellerEnabled")); + if (tonic::CheckAndHandleError(impeller_enabled)) { + return false; + } + bool result; + if (tonic::CheckAndHandleError( + Dart_BooleanValue(impeller_enabled, &result))) { + return false; + } + return result == settings.enable_impeller; + })); +} + +TEST_F(DartIsolateTest, ImpellerFlagIsCorrectWhenFalse) { + ASSERT_FALSE(DartVMRef::IsInstanceRunning()); + auto settings = CreateSettingsForFixture(); + settings.enable_impeller = false; + auto vm_ref = DartVMRef::Create(settings); + TaskRunners task_runners(GetCurrentTestName(), // + GetCurrentTaskRunner(), // + GetCurrentTaskRunner(), // + GetCurrentTaskRunner(), // + GetCurrentTaskRunner() // + ); + auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners, "main", + {}, GetDefaultKernelFilePath()); + + ASSERT_TRUE(isolate); + ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running); + ASSERT_TRUE(isolate->RunInIsolateScope([settings]() -> bool { + Dart_Handle dart_ui = ::Dart_LookupLibrary(tonic::ToDart("dart:ui")); + if (tonic::CheckAndHandleError(dart_ui)) { + return false; + } + Dart_Handle impeller_enabled = + ::Dart_GetField(dart_ui, tonic::ToDart("_impellerEnabled")); + if (tonic::CheckAndHandleError(impeller_enabled)) { + return false; + } + bool result; + if (tonic::CheckAndHandleError( + Dart_BooleanValue(impeller_enabled, &result))) { + return false; + } + return result == settings.enable_impeller; + })); +} + TEST_F(DartIsolateTest, CanRegisterNativeCallback) { ASSERT_FALSE(DartVMRef::IsInstanceRunning()); AddNativeCallback(