From 2db5060505c39549e31e14fba82d5f7797f36a5a Mon Sep 17 00:00:00 2001 From: Kaushik Iska Date: Thu, 23 Sep 2021 10:34:09 -0700 Subject: [PATCH 1/3] vsync_waiter_fallback should schedule firecallback for future This makes the impl consistent with how other platforms implement vsyncs. This also ensures that we always pause the microtasks for the minimal time possible. Fixes: https://github.com/flutter/flutter/issues/89786 --- shell/common/vsync_waiter.cc | 10 +++++++--- shell/common/vsync_waiter_fallback.cc | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/shell/common/vsync_waiter.cc b/shell/common/vsync_waiter.cc index bfbd64c1338d5..b8d43c3a7f5ae 100644 --- a/shell/common/vsync_waiter.cc +++ b/shell/common/vsync_waiter.cc @@ -7,8 +7,10 @@ #include "flow/frame_timings.h" #include "flutter/fml/task_runner.h" #include "flutter/fml/trace_event.h" +#include "fml/logging.h" #include "fml/message_loop_task_queues.h" #include "fml/task_queue_id.h" +#include "fml/time/time_point.h" namespace flutter { @@ -95,6 +97,9 @@ void VsyncWaiter::ScheduleSecondaryCallback(uintptr_t id, void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time, fml::TimePoint frame_target_time, bool pause_secondary_tasks) { + FML_DCHECK(fml::TimePoint::Now() >= frame_start_time); + FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); + Callback callback; std::vector secondary_callbacks; @@ -137,7 +142,7 @@ void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time, ui_task_queue_id = task_runners_.GetUITaskRunner()->GetTaskQueueId(); } - task_runners_.GetUITaskRunner()->PostTaskForTime( + task_runners_.GetUITaskRunner()->PostTask( [ui_task_queue_id, callback, flow_identifier, frame_start_time, frame_target_time, pause_secondary_tasks]() { FML_TRACE_EVENT("flutter", kVsyncTraceName, "StartTime", @@ -151,8 +156,7 @@ void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time, if (pause_secondary_tasks) { ResumeDartMicroTasks(ui_task_queue_id); } - }, - frame_start_time); + }); } for (auto& secondary_callback : secondary_callbacks) { diff --git a/shell/common/vsync_waiter_fallback.cc b/shell/common/vsync_waiter_fallback.cc index 8bf51c5ce2f4e..6d9110ace3b77 100644 --- a/shell/common/vsync_waiter_fallback.cc +++ b/shell/common/vsync_waiter_fallback.cc @@ -35,11 +35,15 @@ void VsyncWaiterFallback::AwaitVSync() { constexpr fml::TimeDelta kSingleFrameInterval = fml::TimeDelta::FromSecondsF(1.0 / 60.0); - - auto next = + auto frame_start_time = SnapToNextTick(fml::TimePoint::Now(), phase_, kSingleFrameInterval); + auto frame_target_time = frame_start_time + kSingleFrameInterval; - FireCallback(next, next + kSingleFrameInterval, !for_testing_); + task_runners_.GetPlatformTaskRunner()->PostTaskForTime( + [frame_start_time, frame_target_time, this]() { + FireCallback(frame_start_time, frame_target_time, !for_testing_); + }, + frame_start_time); } } // namespace flutter From 83dfdbdeb0fb585da7103b3481fc0a6829447c30 Mon Sep 17 00:00:00 2001 From: Kaushik Iska Date: Mon, 27 Sep 2021 13:19:33 -0700 Subject: [PATCH 2/3] Post at a later time from the same task runner --- shell/common/vsync_waiter.cc | 1 - shell/common/vsync_waiter_fallback.cc | 19 +++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/shell/common/vsync_waiter.cc b/shell/common/vsync_waiter.cc index b8d43c3a7f5ae..c2806d5b7d338 100644 --- a/shell/common/vsync_waiter.cc +++ b/shell/common/vsync_waiter.cc @@ -98,7 +98,6 @@ void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time, fml::TimePoint frame_target_time, bool pause_secondary_tasks) { FML_DCHECK(fml::TimePoint::Now() >= frame_start_time); - FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); Callback callback; std::vector secondary_callbacks; diff --git a/shell/common/vsync_waiter_fallback.cc b/shell/common/vsync_waiter_fallback.cc index 6d9110ace3b77..05bbcd71d5e61 100644 --- a/shell/common/vsync_waiter_fallback.cc +++ b/shell/common/vsync_waiter_fallback.cc @@ -2,9 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#define FML_USED_ON_EMBEDDER + #include "flutter/shell/common/vsync_waiter_fallback.h" +#include + #include "flutter/fml/logging.h" +#include "flutter/fml/message_loop.h" #include "flutter/fml/trace_event.h" namespace flutter { @@ -38,10 +43,16 @@ void VsyncWaiterFallback::AwaitVSync() { auto frame_start_time = SnapToNextTick(fml::TimePoint::Now(), phase_, kSingleFrameInterval); auto frame_target_time = frame_start_time + kSingleFrameInterval; - - task_runners_.GetPlatformTaskRunner()->PostTaskForTime( - [frame_start_time, frame_target_time, this]() { - FireCallback(frame_start_time, frame_target_time, !for_testing_); + std::weak_ptr weak_this = + std::static_pointer_cast(shared_from_this()); + + auto current_task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner(); + current_task_runner->PostTaskForTime( + [frame_start_time, frame_target_time, weak_this]() { + if (auto vsync_waiter = weak_this.lock()) { + vsync_waiter->FireCallback(frame_start_time, frame_target_time, + !vsync_waiter->for_testing_); + } }, frame_start_time); } From 3d8bffa82ce9fa0724b1fbe4ccfbf3a06ebdcd1f Mon Sep 17 00:00:00 2001 From: Kaushik Iska Date: Wed, 29 Sep 2021 09:31:29 -0700 Subject: [PATCH 3/3] address CR comments --- shell/common/vsync_waiter.h | 2 ++ shell/common/vsync_waiter_fallback.cc | 5 +---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/shell/common/vsync_waiter.h b/shell/common/vsync_waiter.h index 998789ef5ca3d..b381f432a9bca 100644 --- a/shell/common/vsync_waiter.h +++ b/shell/common/vsync_waiter.h @@ -65,6 +65,8 @@ class VsyncWaiter : public std::enable_shared_from_this { // as AwaitVSync(). virtual void AwaitVSyncForSecondaryCallback() { AwaitVSync(); } + // Schedules the callback on the UI task runner. Needs to be invoked as close + // to the `frame_start_time` as possible. void FireCallback(fml::TimePoint frame_start_time, fml::TimePoint frame_target_time, bool pause_secondary_tasks = true); diff --git a/shell/common/vsync_waiter_fallback.cc b/shell/common/vsync_waiter_fallback.cc index 05bbcd71d5e61..120e9a78551de 100644 --- a/shell/common/vsync_waiter_fallback.cc +++ b/shell/common/vsync_waiter_fallback.cc @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#define FML_USED_ON_EMBEDDER - #include "flutter/shell/common/vsync_waiter_fallback.h" #include @@ -46,8 +44,7 @@ void VsyncWaiterFallback::AwaitVSync() { std::weak_ptr weak_this = std::static_pointer_cast(shared_from_this()); - auto current_task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner(); - current_task_runner->PostTaskForTime( + task_runners_.GetUITaskRunner()->PostTaskForTime( [frame_start_time, frame_target_time, weak_this]() { if (auto vsync_waiter = weak_this.lock()) { vsync_waiter->FireCallback(frame_start_time, frame_target_time,