From 22377e7431f4d482a4d6498885bb00d39ab8e3f1 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 29 Nov 2021 14:58:36 -0800 Subject: [PATCH 1/8] refresh frame rate reporting --- shell/common/animator.cc | 8 +++++--- shell/common/animator.h | 3 ++- shell/common/animator_unittests.cc | 3 ++- shell/common/display_manager.cc | 7 +++++++ shell/common/display_manager.h | 6 +++++- shell/common/shell.cc | 18 +++++++++++++++++- shell/common/shell.h | 8 +++++++- shell/common/vsync_waiter.h | 1 + 8 files changed, 46 insertions(+), 8 deletions(-) diff --git a/shell/common/animator.cc b/shell/common/animator.cc index 32403f1c2e70a..a63ad5cf8455a 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -133,9 +133,10 @@ void Animator::BeginFrame( // We have acquired a valid continuation from the pipeline and are ready // to service potential frame. FML_DCHECK(producer_continuation_); + const fml::TimePoint vsync_start_time = + frame_timings_recorder_->GetVsyncStartTime(); fml::tracing::TraceEventAsyncComplete( - "flutter", "VsyncSchedulingOverhead", - frame_timings_recorder_->GetVsyncStartTime(), + "flutter", "VsyncSchedulingOverhead", vsync_start_time, frame_timings_recorder_->GetBuildStartTime()); const fml::TimePoint frame_target_time = frame_timings_recorder_->GetVsyncTargetTime(); @@ -144,7 +145,8 @@ void Animator::BeginFrame( TRACE_EVENT2("flutter", "Framework Workload", "mode", "basic", "frame", FrameParity()); uint64_t frame_number = frame_timings_recorder_->GetFrameNumber(); - delegate_.OnAnimatorBeginFrame(frame_target_time, frame_number); + delegate_.OnAnimatorBeginFrame(vsync_start_time, frame_target_time, + frame_number); } if (!frame_scheduled_ && has_rendered_) { diff --git a/shell/common/animator.h b/shell/common/animator.h index 85f940700dbc6..e7c51d43a4a42 100644 --- a/shell/common/animator.h +++ b/shell/common/animator.h @@ -31,7 +31,8 @@ class Animator final { public: class Delegate { public: - virtual void OnAnimatorBeginFrame(fml::TimePoint frame_target_time, + virtual void OnAnimatorBeginFrame(fml::TimePoint vsync_start_time, + fml::TimePoint frame_target_time, uint64_t frame_number) = 0; virtual void OnAnimatorNotifyIdle(int64_t deadline) = 0; diff --git a/shell/common/animator_unittests.cc b/shell/common/animator_unittests.cc index 0b11d06c8929f..5b5c34f5e2242 100644 --- a/shell/common/animator_unittests.cc +++ b/shell/common/animator_unittests.cc @@ -20,7 +20,8 @@ namespace testing { class FakeAnimatorDelegate : public Animator::Delegate { public: - void OnAnimatorBeginFrame(fml::TimePoint frame_target_time, + void OnAnimatorBeginFrame(fml::TimePoint vsync_start_time, + fml::TimePoint frame_target_time, uint64_t frame_number) override {} void OnAnimatorNotifyIdle(int64_t deadline) override { diff --git a/shell/common/display_manager.cc b/shell/common/display_manager.cc index 75211308de727..303d9cef2e8ef 100644 --- a/shell/common/display_manager.cc +++ b/shell/common/display_manager.cc @@ -32,6 +32,13 @@ void DisplayManager::HandleDisplayUpdates( FML_CHECK(displays_.empty()); displays_ = std::move(displays); return; + case DisplayUpdateType::kNewFrame: + displays_.insert(displays_.end(), + std::make_move_iterator(displays.begin()), + std::make_move_iterator(displays.end())); + FML_DLOG(ERROR) << "display updated " + << displays_.back()->GetRefreshRate(); + break; default: FML_CHECK(false) << "Unknown DisplayUpdateType."; } diff --git a/shell/common/display_manager.h b/shell/common/display_manager.h index 774373d54e70b..40683e01f8693 100644 --- a/shell/common/display_manager.h +++ b/shell/common/display_manager.h @@ -20,7 +20,11 @@ enum class DisplayUpdateType { /// 1. The frame buffer hardware is connected. /// 2. The display is drawable, e.g. it isn't being mirrored from another /// connected display or sleeping. - kStartup + kStartup, + + /// The `flutter::Display` that were active and a new frame requests an + /// update. + kNewFrame, }; /// Manages lifecycle of the connected displays. This class is thread-safe. diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 4e23e6b67153c..25e0403bd5551 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1059,11 +1059,27 @@ void Shell::OnPlatformViewSetNextFrameCallback(const fml::closure& closure) { } // |Animator::Delegate| -void Shell::OnAnimatorBeginFrame(fml::TimePoint frame_target_time, +void Shell::OnAnimatorBeginFrame(fml::TimePoint vsync_start_time, + fml::TimePoint frame_target_time, uint64_t frame_number) { FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread()); + auto is_frame_rate_same = [](double fr1, double fr2) { + const double kRefreshRateCompareEpsilon = 1; + return fabs(fr1 - fr2) < kRefreshRateCompareEpsilon; + }; + + double new_frame_rate = + round((1 / (frame_target_time - vsync_start_time).ToSecondsF())); + if (!is_frame_rate_same(frame_rate_, new_frame_rate)) { + frame_rate_ = new_frame_rate; + std::vector> displays; + displays.push_back(std::make_unique(frame_rate_)); + OnDisplayUpdates(flutter::DisplayUpdateType::kNewFrame, + std::move(displays)); + } + // record the target time for use by rasterizer. { std::scoped_lock time_recorder_lock(time_recorder_mutex_); diff --git a/shell/common/shell.h b/shell/common/shell.h index 87ba86cb83ac5..8c01f69eb334d 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -565,7 +565,8 @@ class Shell final : public PlatformView::Delegate, AssetResolver::AssetResolverType type) override; // |Animator::Delegate| - void OnAnimatorBeginFrame(fml::TimePoint frame_target_time, + void OnAnimatorBeginFrame(fml::TimePoint vsync_start_time, + fml::TimePoint frame_target_time, uint64_t frame_number) override; // |Animator::Delegate| @@ -690,6 +691,11 @@ class Shell final : public PlatformView::Delegate, fml::WeakPtrFactory weak_factory_; friend class testing::ShellTest; + // Indicates the current frame_rate_. + // + // Every new frame may update this value if necessary. + double frame_rate_ = -1; + FML_DISALLOW_COPY_AND_ASSIGN(Shell); }; diff --git a/shell/common/vsync_waiter.h b/shell/common/vsync_waiter.h index b381f432a9bca..0aef602cff437 100644 --- a/shell/common/vsync_waiter.h +++ b/shell/common/vsync_waiter.h @@ -75,6 +75,7 @@ class VsyncWaiter : public std::enable_shared_from_this { std::mutex callback_mutex_; Callback callback_; std::unordered_map secondary_callbacks_; + double frame_rate_ = -1; void PauseDartMicroTasks(); static void ResumeDartMicroTasks(fml::TaskQueueId ui_task_queue_id); From 390cc4ebf451c6c3b236bbdd86baaf4528bc30bc Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 3 Dec 2021 09:21:26 -0800 Subject: [PATCH 2/8] draft --- shell/common/display_manager.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shell/common/display_manager.h b/shell/common/display_manager.h index 40683e01f8693..1068bb6aea8d6 100644 --- a/shell/common/display_manager.h +++ b/shell/common/display_manager.h @@ -46,6 +46,9 @@ class DisplayManager { void HandleDisplayUpdates(DisplayUpdateType update_type, std::vector> displays); + /// Report the current frame timing. + void UpdateTimings(); + private: /// Guards `displays_` vector. mutable std::mutex displays_mutex_; From 1a8c4d084a583958549c2db0518722bd69d40912 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 3 Dec 2021 10:08:41 -0800 Subject: [PATCH 3/8] use display_manager to update displays --- shell/common/display_manager.cc | 22 +++++++++++++++++++--- shell/common/display_manager.h | 6 ++++-- shell/common/shell.cc | 16 ++-------------- shell/common/shell.h | 5 ----- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/shell/common/display_manager.cc b/shell/common/display_manager.cc index 303d9cef2e8ef..cd0d1063a807d 100644 --- a/shell/common/display_manager.cc +++ b/shell/common/display_manager.cc @@ -33,11 +33,10 @@ void DisplayManager::HandleDisplayUpdates( displays_ = std::move(displays); return; case DisplayUpdateType::kNewFrame: - displays_.insert(displays_.end(), + displays_.insert(displays_.begin(), std::make_move_iterator(displays.begin()), std::make_move_iterator(displays.end())); - FML_DLOG(ERROR) << "display updated " - << displays_.back()->GetRefreshRate(); + FML_DLOG(ERROR) << "display updated " << displays_[0]->GetRefreshRate(); break; default: FML_CHECK(false) << "Unknown DisplayUpdateType."; @@ -54,4 +53,21 @@ void DisplayManager::CheckDisplayConfiguration( } } +void DisplayManager::ReportFrameTimings(DisplayUpdateType update_type, + fml::TimePoint vsync_start_time, + fml::TimePoint frame_target_time) { + auto is_frame_rate_same = [](double fr1, double fr2) { + const double kRefreshRateCompareEpsilon = 1; + return fabs(fr1 - fr2) < kRefreshRateCompareEpsilon; + }; + + double new_frame_rate = + round((1 / (frame_target_time - vsync_start_time).ToSecondsF())); + if (!is_frame_rate_same(GetMainDisplayRefreshRate(), new_frame_rate)) { + std::vector> displays; + displays.push_back(std::make_unique(new_frame_rate)); + HandleDisplayUpdates(update_type, std::move(displays)); + } +} + } // namespace flutter diff --git a/shell/common/display_manager.h b/shell/common/display_manager.h index 1068bb6aea8d6..3bd6181174b9f 100644 --- a/shell/common/display_manager.h +++ b/shell/common/display_manager.h @@ -46,8 +46,10 @@ class DisplayManager { void HandleDisplayUpdates(DisplayUpdateType update_type, std::vector> displays); - /// Report the current frame timing. - void UpdateTimings(); + /// Reports the current frame timing to the |DisplayManager| + void ReportFrameTimings(DisplayUpdateType update_type, + fml::TimePoint vsync_start_time, + fml::TimePoint frame_target_time); private: /// Guards `displays_` vector. diff --git a/shell/common/shell.cc b/shell/common/shell.cc index fed768603d87c..454ee36014648 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1074,20 +1074,8 @@ void Shell::OnAnimatorBeginFrame(fml::TimePoint vsync_start_time, FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread()); - auto is_frame_rate_same = [](double fr1, double fr2) { - const double kRefreshRateCompareEpsilon = 1; - return fabs(fr1 - fr2) < kRefreshRateCompareEpsilon; - }; - - double new_frame_rate = - round((1 / (frame_target_time - vsync_start_time).ToSecondsF())); - if (!is_frame_rate_same(frame_rate_, new_frame_rate)) { - frame_rate_ = new_frame_rate; - std::vector> displays; - displays.push_back(std::make_unique(frame_rate_)); - OnDisplayUpdates(flutter::DisplayUpdateType::kNewFrame, - std::move(displays)); - } + display_manager_->ReportFrameTimings(flutter::DisplayUpdateType::kNewFrame, + vsync_start_time, frame_target_time); // record the target time for use by rasterizer. { diff --git a/shell/common/shell.h b/shell/common/shell.h index d077ec5f2253d..2101bc08c1b7c 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -693,11 +693,6 @@ class Shell final : public PlatformView::Delegate, fml::WeakPtrFactory weak_factory_; friend class testing::ShellTest; - // Indicates the current frame_rate_. - // - // Every new frame may update this value if necessary. - double frame_rate_ = -1; - FML_DISALLOW_COPY_AND_ASSIGN(Shell); }; From 0b09ae4bf8c5cfeb86f376c85f902e4f9abf42df Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 3 Dec 2021 10:10:49 -0800 Subject: [PATCH 4/8] cleanup --- shell/common/vsync_waiter.h | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/common/vsync_waiter.h b/shell/common/vsync_waiter.h index 0aef602cff437..b381f432a9bca 100644 --- a/shell/common/vsync_waiter.h +++ b/shell/common/vsync_waiter.h @@ -75,7 +75,6 @@ class VsyncWaiter : public std::enable_shared_from_this { std::mutex callback_mutex_; Callback callback_; std::unordered_map secondary_callbacks_; - double frame_rate_ = -1; void PauseDartMicroTasks(); static void ResumeDartMicroTasks(fml::TaskQueueId ui_task_queue_id); From 87a4dc84f37424212d62ee0a7596b5afc3f37541 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 3 Dec 2021 10:31:15 -0800 Subject: [PATCH 5/8] add import --- shell/common/display_manager.h | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/common/display_manager.h b/shell/common/display_manager.h index 3bd6181174b9f..4a78d79332237 100644 --- a/shell/common/display_manager.h +++ b/shell/common/display_manager.h @@ -8,6 +8,7 @@ #include #include +#include "flutter/fml/time/time_point.h" #include "flutter/shell/common/display.h" namespace flutter { From 15489359e739a63f51e93ff3f253e4abe5523481 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 3 Dec 2021 11:04:15 -0800 Subject: [PATCH 6/8] test --- ci/licenses_golden/licenses_flutter | 1 + shell/common/BUILD.gn | 1 + shell/common/display_manager.cc | 4 ++-- shell/common/display_manager.h | 13 +++++++------ shell/common/display_manager_unittests.cc | 18 ++++++++++++++++++ shell/common/shell.cc | 2 +- 6 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 shell/common/display_manager_unittests.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 4308d1df37ab4..ed8e8fe932c72 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -699,6 +699,7 @@ FILE: ../../../flutter/shell/common/display.cc FILE: ../../../flutter/shell/common/display.h FILE: ../../../flutter/shell/common/display_manager.cc FILE: ../../../flutter/shell/common/display_manager.h +FILE: ../../../flutter/shell/common/display_manager_unittests.cc FILE: ../../../flutter/shell/common/engine.cc FILE: ../../../flutter/shell/common/engine.h FILE: ../../../flutter/shell/common/engine_unittests.cc diff --git a/shell/common/BUILD.gn b/shell/common/BUILD.gn index 62112b4b9d917..6e975a91a54bd 100644 --- a/shell/common/BUILD.gn +++ b/shell/common/BUILD.gn @@ -258,6 +258,7 @@ if (enable_unittests) { sources = [ "animator_unittests.cc", "canvas_spy_unittests.cc", + "display_manager_unittests", "engine_unittests.cc", "input_events_unittests.cc", "persistent_cache_unittests.cc", diff --git a/shell/common/display_manager.cc b/shell/common/display_manager.cc index cd0d1063a807d..6e550455885a9 100644 --- a/shell/common/display_manager.cc +++ b/shell/common/display_manager.cc @@ -32,7 +32,7 @@ void DisplayManager::HandleDisplayUpdates( FML_CHECK(displays_.empty()); displays_ = std::move(displays); return; - case DisplayUpdateType::kNewFrame: + case DisplayUpdateType::kUpdateRefreshRate: displays_.insert(displays_.begin(), std::make_move_iterator(displays.begin()), std::make_move_iterator(displays.end())); @@ -53,7 +53,7 @@ void DisplayManager::CheckDisplayConfiguration( } } -void DisplayManager::ReportFrameTimings(DisplayUpdateType update_type, +void DisplayManager::UpdateRefreshRate(DisplayUpdateType update_type, fml::TimePoint vsync_start_time, fml::TimePoint frame_target_time) { auto is_frame_rate_same = [](double fr1, double fr2) { diff --git a/shell/common/display_manager.h b/shell/common/display_manager.h index 4a78d79332237..1c2006b35d523 100644 --- a/shell/common/display_manager.h +++ b/shell/common/display_manager.h @@ -5,6 +5,7 @@ #ifndef FLUTTER_SHELL_COMMON_DISPLAY_MANAGER_H_ #define FLUTTER_SHELL_COMMON_DISPLAY_MANAGER_H_ +#include #include #include @@ -23,9 +24,9 @@ enum class DisplayUpdateType { /// connected display or sleeping. kStartup, - /// The `flutter::Display` that were active and a new frame requests an - /// update. - kNewFrame, + /// The `flutter::Display` that were active and a new frame indicates that the + /// refresh rate might be updated. + kUpdateRefreshRate, }; /// Manages lifecycle of the connected displays. This class is thread-safe. @@ -48,9 +49,9 @@ class DisplayManager { std::vector> displays); /// Reports the current frame timing to the |DisplayManager| - void ReportFrameTimings(DisplayUpdateType update_type, - fml::TimePoint vsync_start_time, - fml::TimePoint frame_target_time); + void UpdateRefreshRate(DisplayUpdateType update_type, + fml::TimePoint vsync_start_time, + fml::TimePoint frame_target_time); private: /// Guards `displays_` vector. diff --git a/shell/common/display_manager_unittests.cc b/shell/common/display_manager_unittests.cc new file mode 100644 index 0000000000000..70b9c797f8e0d --- /dev/null +++ b/shell/common/display_manager_unittests.cc @@ -0,0 +1,18 @@ +#include "display.h" +#include "display_manager.h" + +#include "gtest/gtest.h" + +namespace flutter { +namespace testing { + +TEST(DisplayManagerTest, SetsDisplayOnStartup) { + DisplayManager manager; + const double refresh_rate = 60; + std::vector> displays; + displays.push_back(std::make_unique(refresh_rate)); + ASSERT_TRUE(manager.GetMainDisplayRefreshRate(), refresh_rate); +} + +} +} \ No newline at end of file diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 454ee36014648..b21ecde71f9b3 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1074,7 +1074,7 @@ void Shell::OnAnimatorBeginFrame(fml::TimePoint vsync_start_time, FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread()); - display_manager_->ReportFrameTimings(flutter::DisplayUpdateType::kNewFrame, + display_manager_->UpdateRefreshRate(flutter::DisplayUpdateType::kUpdateRefreshRate, vsync_start_time, frame_target_time); // record the target time for use by rasterizer. From cad7e7d789b1ce8c10f299d110a5e105268ceeac Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 3 Dec 2021 13:55:29 -0800 Subject: [PATCH 7/8] tests --- shell/common/BUILD.gn | 2 +- shell/common/display_manager.cc | 8 ++-- shell/common/display_manager.h | 11 ++++-- shell/common/display_manager_unittests.cc | 46 ++++++++++++++++++++++- shell/common/shell.cc | 5 ++- 5 files changed, 59 insertions(+), 13 deletions(-) diff --git a/shell/common/BUILD.gn b/shell/common/BUILD.gn index 6e975a91a54bd..269d08f7fa251 100644 --- a/shell/common/BUILD.gn +++ b/shell/common/BUILD.gn @@ -258,7 +258,7 @@ if (enable_unittests) { sources = [ "animator_unittests.cc", "canvas_spy_unittests.cc", - "display_manager_unittests", + "display_manager_unittests.cc", "engine_unittests.cc", "input_events_unittests.cc", "persistent_cache_unittests.cc", diff --git a/shell/common/display_manager.cc b/shell/common/display_manager.cc index 6e550455885a9..e89f44a9f3cab 100644 --- a/shell/common/display_manager.cc +++ b/shell/common/display_manager.cc @@ -36,7 +36,6 @@ void DisplayManager::HandleDisplayUpdates( displays_.insert(displays_.begin(), std::make_move_iterator(displays.begin()), std::make_move_iterator(displays.end())); - FML_DLOG(ERROR) << "display updated " << displays_[0]->GetRefreshRate(); break; default: FML_CHECK(false) << "Unknown DisplayUpdateType."; @@ -53,9 +52,10 @@ void DisplayManager::CheckDisplayConfiguration( } } -void DisplayManager::UpdateRefreshRate(DisplayUpdateType update_type, - fml::TimePoint vsync_start_time, - fml::TimePoint frame_target_time) { +void DisplayManager::UpdateRefreshRateIfNecessary( + DisplayUpdateType update_type, + fml::TimePoint vsync_start_time, + fml::TimePoint frame_target_time) { auto is_frame_rate_same = [](double fr1, double fr2) { const double kRefreshRateCompareEpsilon = 1; return fabs(fr1 - fr2) < kRefreshRateCompareEpsilon; diff --git a/shell/common/display_manager.h b/shell/common/display_manager.h index 1c2006b35d523..6ffea962fcdc6 100644 --- a/shell/common/display_manager.h +++ b/shell/common/display_manager.h @@ -48,10 +48,13 @@ class DisplayManager { void HandleDisplayUpdates(DisplayUpdateType update_type, std::vector> displays); - /// Reports the current frame timing to the |DisplayManager| - void UpdateRefreshRate(DisplayUpdateType update_type, - fml::TimePoint vsync_start_time, - fml::TimePoint frame_target_time); + /// Updates the frame rate indicated in the |DisplayManager| if necessary. + /// + /// If the |DisplayManager| decides an update is required, + /// |GetMainDisplayRefreshRate| will return the updated value. + void UpdateRefreshRateIfNecessary(DisplayUpdateType update_type, + fml::TimePoint vsync_start_time, + fml::TimePoint frame_target_time); private: /// Guards `displays_` vector. diff --git a/shell/common/display_manager_unittests.cc b/shell/common/display_manager_unittests.cc index 70b9c797f8e0d..7c9502851f24c 100644 --- a/shell/common/display_manager_unittests.cc +++ b/shell/common/display_manager_unittests.cc @@ -1,6 +1,8 @@ #include "display.h" #include "display_manager.h" +#include "flutter/fml/time/time_point.h" + #include "gtest/gtest.h" namespace flutter { @@ -11,8 +13,48 @@ TEST(DisplayManagerTest, SetsDisplayOnStartup) { const double refresh_rate = 60; std::vector> displays; displays.push_back(std::make_unique(refresh_rate)); - ASSERT_TRUE(manager.GetMainDisplayRefreshRate(), refresh_rate); + manager.HandleDisplayUpdates(flutter::DisplayUpdateType::kStartup, + std::move(displays)); + ASSERT_EQ(manager.GetMainDisplayRefreshRate(), refresh_rate); } +TEST(DisplayManagerTest, UpdatesDisplayIfTypeIsUpdateRefreshRate) { + DisplayManager manager; + const double refresh_rate = 60; + std::vector> displays1; + displays1.push_back(std::make_unique(refresh_rate)); + manager.HandleDisplayUpdates(flutter::DisplayUpdateType::kStartup, + std::move(displays1)); + + const double new_refresh_rate = 120; + std::vector> displays2; + displays2.push_back(std::make_unique(new_refresh_rate)); + manager.HandleDisplayUpdates(flutter::DisplayUpdateType::kUpdateRefreshRate, + std::move(displays2)); + ASSERT_EQ(manager.GetMainDisplayRefreshRate(), new_refresh_rate); } -} \ No newline at end of file + +TEST(DisplayManagerTest, UpdatesDisplayIfNewlyCalculatedRefreshRateChanged) { + DisplayManager manager; + const double refresh_rate = 60; + std::vector> displays; + displays.push_back(std::make_unique(refresh_rate)); + manager.HandleDisplayUpdates(flutter::DisplayUpdateType::kStartup, + std::move(displays)); + fml::TimePoint vsync_start = + fml::TimePoint::FromEpochDelta(fml::TimeDelta::FromMilliseconds(0)); + fml::TimePoint vsync_target = + fml::TimePoint::FromEpochDelta(fml::TimeDelta::FromMilliseconds(8)); + + manager.UpdateRefreshRateIfNecessary( + flutter::DisplayUpdateType::kUpdateRefreshRate, vsync_start, + vsync_target); + + const double kRefreshRateCompareEpsilon = 0.1; + ASSERT_NEAR(manager.GetMainDisplayRefreshRate(), + round(1 / (vsync_target - vsync_start).ToSecondsF()), + kRefreshRateCompareEpsilon); +} + +} // namespace testing +} // namespace flutter diff --git a/shell/common/shell.cc b/shell/common/shell.cc index b21ecde71f9b3..64570e76d74ed 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1074,8 +1074,9 @@ void Shell::OnAnimatorBeginFrame(fml::TimePoint vsync_start_time, FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread()); - display_manager_->UpdateRefreshRate(flutter::DisplayUpdateType::kUpdateRefreshRate, - vsync_start_time, frame_target_time); + display_manager_->UpdateRefreshRateIfNecessary( + flutter::DisplayUpdateType::kUpdateRefreshRate, vsync_start_time, + frame_target_time); // record the target time for use by rasterizer. { From d39b74e30f18972cb9bf283103678c474a59956e Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 6 Dec 2021 10:09:01 -0800 Subject: [PATCH 8/8] return early --- shell/common/display_manager.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/shell/common/display_manager.cc b/shell/common/display_manager.cc index e89f44a9f3cab..8d90f97b12214 100644 --- a/shell/common/display_manager.cc +++ b/shell/common/display_manager.cc @@ -63,11 +63,13 @@ void DisplayManager::UpdateRefreshRateIfNecessary( double new_frame_rate = round((1 / (frame_target_time - vsync_start_time).ToSecondsF())); - if (!is_frame_rate_same(GetMainDisplayRefreshRate(), new_frame_rate)) { - std::vector> displays; - displays.push_back(std::make_unique(new_frame_rate)); - HandleDisplayUpdates(update_type, std::move(displays)); + if (is_frame_rate_same(GetMainDisplayRefreshRate(), new_frame_rate)) { + return; } + + std::vector> displays; + displays.push_back(std::make_unique(new_frame_rate)); + HandleDisplayUpdates(update_type, std::move(displays)); } } // namespace flutter