Do not call Dart_NotifyIdle when in Dart_PerformanceMode_Latency (flutter/engine#37499)

This commit is contained in:
Kaushik Iska 2022-11-10 21:28:38 -05:00 committed by GitHub
parent a56e2b774e
commit ca224262c5
5 changed files with 73 additions and 1 deletions

View File

@ -371,9 +371,17 @@ void PlatformConfigurationNativeApi::SetIsolateDebugName(
UIDartState::Current()->SetDebugName(name);
}
Dart_PerformanceMode PlatformConfigurationNativeApi::current_performace_mode_ =
Dart_PerformanceMode_Default;
Dart_PerformanceMode PlatformConfigurationNativeApi::GetDartPerformanceMode() {
return current_performace_mode_;
}
int PlatformConfigurationNativeApi::RequestDartPerformanceMode(int mode) {
UIDartState::ThrowIfUIOperationsProhibited();
return Dart_SetPerformanceMode(static_cast<Dart_PerformanceMode>(mode));
current_performace_mode_ = static_cast<Dart_PerformanceMode>(mode);
return Dart_SetPerformanceMode(current_performace_mode_);
}
Dart_Handle PlatformConfigurationNativeApi::GetPersistentIsolateData() {

View File

@ -515,9 +515,18 @@ class PlatformConfigurationNativeApi {
///
static int RequestDartPerformanceMode(int mode);
//--------------------------------------------------------------------------
/// @brief Returns the current performance mode of the Dart VM. Defaults
/// to `Dart_PerformanceMode_Default` if no prior requests to change the
/// performance mode have been made.
static Dart_PerformanceMode GetDartPerformanceMode();
static int64_t GetRootIsolateToken();
static void RegisterBackgroundIsolate(int64_t root_isolate_token);
private:
static Dart_PerformanceMode current_performace_mode_;
};
} // namespace flutter

View File

@ -219,6 +219,12 @@ bool RuntimeController::NotifyIdle(fml::TimePoint deadline) {
tonic::DartState::Scope scope(root_isolate);
Dart_PerformanceMode performance_mode =
PlatformConfigurationNativeApi::GetDartPerformanceMode();
if (performance_mode == Dart_PerformanceMode::Dart_PerformanceMode_Latency) {
return false;
}
Dart_NotifyIdle(deadline.ToEpochDelta().ToMicroseconds());
// Idle notifications being in isolate scope are part of the contract.

View File

@ -204,6 +204,14 @@ void canAccessIsolateLaunchData() {
);
}
@pragma('vm:entry-point')
void performanceModeImpactsNotifyIdle() {
notifyNativeBool(false);
PlatformDispatcher.instance.requestDartPerformanceMode(DartPerformanceMode.latency);
notifyNativeBool(true);
PlatformDispatcher.instance.requestDartPerformanceMode(DartPerformanceMode.balanced);
}
@pragma('vm:external-name', 'NotifyMessage')
external void notifyMessage(String string);

View File

@ -3891,6 +3891,47 @@ TEST_F(ShellTest, PluginUtilitiesCallbackHandleErrorHandling) {
DestroyShell(std::move(shell));
}
TEST_F(ShellTest, NotifyIdleNotCalledInLatencyMode) {
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
Settings settings = CreateSettingsForFixture();
ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
ThreadHost::Type::Platform | ThreadHost::UI |
ThreadHost::IO | ThreadHost::RASTER);
auto platform_task_runner = thread_host.platform_thread->GetTaskRunner();
TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(),
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
auto shell = CreateShell(settings, task_runners);
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
ASSERT_TRUE(ValidateShell(shell.get()));
// we start off in balanced mode, where we expect idle notifications to
// succeed. After the first `NotifyNativeBool` we expect to be in latency
// mode, where we expect idle notifications to fail.
fml::CountDownLatch latch(2);
AddNativeCallback(
"NotifyNativeBool", CREATE_NATIVE_ENTRY([&](auto args) {
Dart_Handle exception = nullptr;
bool is_in_latency_mode =
tonic::DartConverter<bool>::FromArguments(args, 0, exception);
auto runtime_controller = const_cast<RuntimeController*>(
shell->GetEngine()->GetRuntimeController());
bool success = runtime_controller->NotifyIdle(fml::TimePoint::Now());
EXPECT_EQ(success, !is_in_latency_mode);
latch.CountDown();
}));
auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("performanceModeImpactsNotifyIdle");
RunEngine(shell.get(), std::move(configuration));
latch.Wait();
DestroyShell(std::move(shell), task_runners);
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
} // namespace testing
} // namespace flutter