From fc5766639a020d160bb751a1fd8acf58c8803a32 Mon Sep 17 00:00:00 2001 From: ColdPaleLight <31977171+ColdPaleLight@users.noreply.github.com> Date: Fri, 11 Mar 2022 09:45:05 +0800 Subject: [PATCH] Make sure the secondary vsync callback is called after the vsync callback (flutter/engine#31513) --- .../shell/common/fixtures/shell_test.dart | 2 +- .../flutter/shell/common/shell_unittests.cc | 46 ++++++++++++++++++- .../src/flutter/shell/common/vsync_waiter.cc | 3 +- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/engine/src/flutter/shell/common/fixtures/shell_test.dart b/engine/src/flutter/shell/common/fixtures/shell_test.dart index 337c771a00..85c406291c 100644 --- a/engine/src/flutter/shell/common/fixtures/shell_test.dart +++ b/engine/src/flutter/shell/common/fixtures/shell_test.dart @@ -264,7 +264,7 @@ void canReceiveArgumentsWhenEngineSpawn(List args) { } @pragma('vm:entry-point') -void canScheduleFrameFromPlatform() { +void onBeginFrameWithNotifyNativeMain() { PlatformDispatcher.instance.onBeginFrame = (Duration beginTime) { nativeOnBeginFrame(beginTime.inMicroseconds); }; diff --git a/engine/src/flutter/shell/common/shell_unittests.cc b/engine/src/flutter/shell/common/shell_unittests.cc index 42fd64b5d9..7221c47592 100644 --- a/engine/src/flutter/shell/common/shell_unittests.cc +++ b/engine/src/flutter/shell/common/shell_unittests.cc @@ -1848,7 +1848,7 @@ TEST_F(ShellTest, CanScheduleFrameFromPlatform) { ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); - configuration.SetEntrypoint("canScheduleFrameFromPlatform"); + configuration.SetEntrypoint("onBeginFrameWithNotifyNativeMain"); RunEngine(shell.get(), std::move(configuration)); // Wait for the application to attach the listener. @@ -1861,6 +1861,50 @@ TEST_F(ShellTest, CanScheduleFrameFromPlatform) { DestroyShell(std::move(shell), std::move(task_runners)); } +TEST_F(ShellTest, SecondaryVsyncCallbackShouldBeCalledAfterVsyncCallback) { + bool is_on_begin_frame_called = false; + bool is_secondary_callback_called = false; + Settings settings = CreateSettingsForFixture(); + TaskRunners task_runners = GetTaskRunnersForFixture(); + fml::AutoResetWaitableEvent latch; + AddNativeCallback( + "NotifyNative", + CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { latch.Signal(); })); + fml::CountDownLatch count_down_latch(2); + AddNativeCallback("NativeOnBeginFrame", + CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { + EXPECT_FALSE(is_on_begin_frame_called); + EXPECT_FALSE(is_secondary_callback_called); + is_on_begin_frame_called = true; + count_down_latch.CountDown(); + })); + std::unique_ptr shell = + CreateShell(std::move(settings), std::move(task_runners)); + ASSERT_TRUE(shell->IsSetup()); + + auto configuration = RunConfiguration::InferFromSettings(settings); + configuration.SetEntrypoint("onBeginFrameWithNotifyNativeMain"); + RunEngine(shell.get(), std::move(configuration)); + + // Wait for the application to attach the listener. + latch.Wait(); + + fml::TaskRunner::RunNowOrPostTask( + shell->GetTaskRunners().GetUITaskRunner(), [&]() { + shell->GetEngine()->ScheduleSecondaryVsyncCallback(0, [&]() { + EXPECT_TRUE(is_on_begin_frame_called); + EXPECT_FALSE(is_secondary_callback_called); + is_secondary_callback_called = true; + count_down_latch.CountDown(); + }); + shell->GetEngine()->ScheduleFrame(); + }); + count_down_latch.Wait(); + EXPECT_TRUE(is_on_begin_frame_called); + EXPECT_TRUE(is_secondary_callback_called); + DestroyShell(std::move(shell), std::move(task_runners)); +} + static void LogSkData(sk_sp data, const char* title) { FML_LOG(ERROR) << "---------- " << title; std::ostringstream ostr; diff --git a/engine/src/flutter/shell/common/vsync_waiter.cc b/engine/src/flutter/shell/common/vsync_waiter.cc index 1755755182..1a545368f1 100644 --- a/engine/src/flutter/shell/common/vsync_waiter.cc +++ b/engine/src/flutter/shell/common/vsync_waiter.cc @@ -154,8 +154,7 @@ void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time, } for (auto& secondary_callback : secondary_callbacks) { - task_runners_.GetUITaskRunner()->PostTaskForTime( - std::move(secondary_callback), frame_start_time); + task_runners_.GetUITaskRunner()->PostTask(std::move(secondary_callback)); } }