Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 3c2fb4d

Browse files
committed
Do not call Dart_NotifyIdle when in Dart_PerformanceMode_Latency
This is to ensure that smoother animations take precedence over idle notifications that trigger GC work.
1 parent 30e2ced commit 3c2fb4d

File tree

6 files changed

+78
-1
lines changed

6 files changed

+78
-1
lines changed

lib/ui/window/platform_configuration.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,17 @@ void PlatformConfigurationNativeApi::SetIsolateDebugName(
371371
UIDartState::Current()->SetDebugName(name);
372372
}
373373

374+
Dart_PerformanceMode PlatformConfigurationNativeApi::current_performace_mode_ =
375+
Dart_PerformanceMode_Default;
376+
377+
Dart_PerformanceMode PlatformConfigurationNativeApi::GetDartPerformanceMode() {
378+
return current_performace_mode_;
379+
}
380+
374381
int PlatformConfigurationNativeApi::RequestDartPerformanceMode(int mode) {
375382
UIDartState::ThrowIfUIOperationsProhibited();
376-
return Dart_SetPerformanceMode(static_cast<Dart_PerformanceMode>(mode));
383+
current_performace_mode_ = static_cast<Dart_PerformanceMode>(mode);
384+
return Dart_SetPerformanceMode(current_performace_mode_);
377385
}
378386

379387
Dart_Handle PlatformConfigurationNativeApi::GetPersistentIsolateData() {

lib/ui/window/platform_configuration.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,9 +515,18 @@ class PlatformConfigurationNativeApi {
515515
///
516516
static int RequestDartPerformanceMode(int mode);
517517

518+
//--------------------------------------------------------------------------
519+
/// @brief Returns the current performance mode of the Dart VM. Defaults
520+
/// to `Dart_PerformanceMode_Default` if no prior requests to change the
521+
/// performance mode have been made.
522+
static Dart_PerformanceMode GetDartPerformanceMode();
523+
518524
static int64_t GetRootIsolateToken();
519525

520526
static void RegisterBackgroundIsolate(int64_t root_isolate_token);
527+
528+
private:
529+
static Dart_PerformanceMode current_performace_mode_;
521530
};
522531

523532
} // namespace flutter

lib/ui/window/platform_configuration_unittests.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,11 @@ TEST_F(ShellTest, PlatformConfigurationSetDartPerformanceMode) {
273273
Dart_PerformanceMode prev =
274274
Dart_SetPerformanceMode(Dart_PerformanceMode_Default);
275275
ASSERT_EQ(Dart_PerformanceMode_Latency, prev);
276+
277+
auto current_mode =
278+
PlatformConfigurationNativeApi::GetDartPerformanceMode();
279+
ASSERT_EQ(Dart_PerformanceMode_Default, current_mode);
280+
276281
message_latch->Signal();
277282
};
278283
AddNativeCallback("Finish", CREATE_NATIVE_ENTRY(finish));

runtime/runtime_controller.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,12 @@ bool RuntimeController::NotifyIdle(fml::TimePoint deadline) {
219219

220220
tonic::DartState::Scope scope(root_isolate);
221221

222+
Dart_PerformanceMode performance_mode =
223+
PlatformConfigurationNativeApi::GetDartPerformanceMode();
224+
if (performance_mode == Dart_PerformanceMode::Dart_PerformanceMode_Latency) {
225+
return false;
226+
}
227+
222228
Dart_NotifyIdle(deadline.ToEpochDelta().ToMicroseconds());
223229

224230
// Idle notifications being in isolate scope are part of the contract.

shell/common/fixtures/shell_test.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,14 @@ void canAccessIsolateLaunchData() {
204204
);
205205
}
206206

207+
@pragma('vm:entry-point')
208+
void performanceModeImpactsNotifyIdle() {
209+
notifyNativeBool(false);
210+
PlatformDispatcher.instance.requestDartPerformanceMode(DartPerformanceMode.latency);
211+
notifyNativeBool(true);
212+
PlatformDispatcher.instance.requestDartPerformanceMode(DartPerformanceMode.balanced);
213+
}
214+
207215
@pragma('vm:external-name', 'NotifyMessage')
208216
external void notifyMessage(String string);
209217

shell/common/shell_unittests.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3891,6 +3891,47 @@ TEST_F(ShellTest, PluginUtilitiesCallbackHandleErrorHandling) {
38913891
DestroyShell(std::move(shell));
38923892
}
38933893

3894+
TEST_F(ShellTest, NotifyIdleNotCalledInLatencyMode) {
3895+
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3896+
Settings settings = CreateSettingsForFixture();
3897+
ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
3898+
ThreadHost::Type::Platform | ThreadHost::UI |
3899+
ThreadHost::IO | ThreadHost::RASTER);
3900+
auto platform_task_runner = thread_host.platform_thread->GetTaskRunner();
3901+
TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(),
3902+
thread_host.raster_thread->GetTaskRunner(),
3903+
thread_host.ui_thread->GetTaskRunner(),
3904+
thread_host.io_thread->GetTaskRunner());
3905+
auto shell = CreateShell(settings, task_runners);
3906+
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3907+
ASSERT_TRUE(ValidateShell(shell.get()));
3908+
3909+
// we start off in balanced mode, where we expect idle notifications to
3910+
// succeed. After the first `NotifyNativeBool` we expect to be in latency
3911+
// mode, where we expect idle notifications to fail.
3912+
fml::CountDownLatch latch(2);
3913+
AddNativeCallback(
3914+
"NotifyNativeBool", CREATE_NATIVE_ENTRY([&](auto args) {
3915+
Dart_Handle exception = nullptr;
3916+
bool is_in_latency_mode =
3917+
tonic::DartConverter<bool>::FromArguments(args, 0, exception);
3918+
auto runtime_controller = const_cast<RuntimeController*>(
3919+
shell->GetEngine()->GetRuntimeController());
3920+
bool success = runtime_controller->NotifyIdle(fml::TimePoint::Now());
3921+
EXPECT_EQ(success, !is_in_latency_mode);
3922+
latch.CountDown();
3923+
}));
3924+
3925+
auto configuration = RunConfiguration::InferFromSettings(settings);
3926+
configuration.SetEntrypoint("performanceModeImpactsNotifyIdle");
3927+
RunEngine(shell.get(), std::move(configuration));
3928+
3929+
latch.Wait();
3930+
3931+
DestroyShell(std::move(shell), task_runners);
3932+
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3933+
}
3934+
38943935
} // namespace testing
38953936
} // namespace flutter
38963937

0 commit comments

Comments
 (0)