Loading services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +14 −3 Original line number Diff line number Diff line Loading @@ -1532,6 +1532,9 @@ void RefreshRateSelector::constructAvailableRefreshRates() { mPrimaryFrameRates = filterRefreshRates(policy->primaryRanges, "primary"); mAppRequestFrameRates = filterRefreshRates(policy->appRequestRanges, "app request"); mAllFrameRates = filterRefreshRates(FpsRanges(getSupportedFrameRateRangeLocked(), getSupportedFrameRateRangeLocked()), "full frame rates"); } bool RefreshRateSelector::isVrrDevice() const { Loading Loading @@ -1560,16 +1563,24 @@ Fps RefreshRateSelector::findClosestKnownFrameRate(Fps frameRate) const { std::vector<float> RefreshRateSelector::getSupportedFrameRates() const { std::scoped_lock lock(mLock); // TODO(b/356986687) Remove the limit once we have the anchor list implementation. const size_t frameRatesSize = std::min<size_t>(11, mPrimaryFrameRates.size()); const size_t frameRatesSize = std::min<size_t>(11, mAllFrameRates.size()); std::vector<float> supportedFrameRates; supportedFrameRates.reserve(frameRatesSize); std::transform(mPrimaryFrameRates.rbegin(), mPrimaryFrameRates.rbegin() + static_cast<int>(frameRatesSize), std::transform(mAllFrameRates.rbegin(), mAllFrameRates.rbegin() + static_cast<int>(frameRatesSize), std::back_inserter(supportedFrameRates), [](FrameRateMode mode) { return mode.fps.getValue(); }); return supportedFrameRates; } FpsRange RefreshRateSelector::getSupportedFrameRateRangeLocked() const { using fps_approx_ops::operator<; if (mMaxRefreshRateModeIt->second->getPeakFps() < kMinSupportedFrameRate) { return {mMaxRefreshRateModeIt->second->getPeakFps(), kMinSupportedFrameRate}; } return {kMinSupportedFrameRate, mMaxRefreshRateModeIt->second->getPeakFps()}; } auto RefreshRateSelector::getIdleTimerAction() const -> KernelIdleTimerAction { std::lock_guard lock(mLock); Loading services/surfaceflinger/Scheduler/RefreshRateSelector.h +4 −0 Original line number Diff line number Diff line Loading @@ -553,6 +553,7 @@ private: // Display modes that satisfy the Policy's ranges, filtered and sorted by refresh rate. std::vector<FrameRateMode> mPrimaryFrameRates GUARDED_BY(mLock); std::vector<FrameRateMode> mAppRequestFrameRates GUARDED_BY(mLock); std::vector<FrameRateMode> mAllFrameRates GUARDED_BY(mLock); // Caches whether the device is VRR-compatible based on the active display mode. std::atomic_bool mIsVrrDevice = false; Loading Loading @@ -597,6 +598,9 @@ private: // Used to detect (lack of) frame activity. ftl::Optional<scheduler::OneShotTimer> mIdleTimer; std::atomic<bool> mIdleTimerStarted = false; // Returns the range of supported frame rates. FpsRange getSupportedFrameRateRangeLocked() const REQUIRES(mLock); }; } // namespace android::scheduler services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp +42 −0 Original line number Diff line number Diff line Loading @@ -4667,5 +4667,47 @@ TEST_P(RefreshRateSelectorTest, renderFrameRatesForVrr) { EXPECT_EQ(120_Hz, primaryRefreshRates[i].modePtr->getPeakFps()); } } TEST_P(RefreshRateSelectorTest, getSupportedFrameRates) { if (GetParam() != Config::FrameRateOverride::Enabled) { return; } auto selector = createSelector(kModes_60_90, kModeId90); const FpsRange range60 = {0_Hz, 60_Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy( {kModeId60, {range60, range60}, {range60, range60}})); // Irrespective of the policy we get the full range of possible frame rates const std::vector<float> expected = {90.0f, 60.0f, 45.0f, 30.0f, 22.5f, 20.0f}; const auto allSupportedFrameRates = selector.getSupportedFrameRates(); ASSERT_EQ(expected.size(), allSupportedFrameRates.size()); for (size_t i = 0; i < expected.size(); i++) { EXPECT_EQ(expected[i], allSupportedFrameRates[i]) << "expected " << expected[i] << " received " << allSupportedFrameRates[i]; } } TEST_P(RefreshRateSelectorTest, getSupportedFrameRatesArr) { if (GetParam() != Config::FrameRateOverride::Enabled) { return; } SET_FLAG_FOR_TEST(flags::vrr_config, true); const auto selector = createSelector(kVrrMode_120, kModeId120); const std::vector<float> expected = {120.0f, 80.0f, 60.0f, 48.0f, 40.0f, 34.285f, 30.0f, 26.666f, 24.0f, 21.818f, 20.0f}; const auto allSupportedFrameRates = selector.getSupportedFrameRates(); ASSERT_EQ(expected.size(), allSupportedFrameRates.size()); constexpr float kEpsilon = 0.001f; for (size_t i = 0; i < expected.size(); i++) { EXPECT_TRUE(std::abs(expected[i] - allSupportedFrameRates[i]) <= kEpsilon) << "expected " << expected[i] << " received " << allSupportedFrameRates[i]; } } } // namespace } // namespace android::scheduler Loading
services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +14 −3 Original line number Diff line number Diff line Loading @@ -1532,6 +1532,9 @@ void RefreshRateSelector::constructAvailableRefreshRates() { mPrimaryFrameRates = filterRefreshRates(policy->primaryRanges, "primary"); mAppRequestFrameRates = filterRefreshRates(policy->appRequestRanges, "app request"); mAllFrameRates = filterRefreshRates(FpsRanges(getSupportedFrameRateRangeLocked(), getSupportedFrameRateRangeLocked()), "full frame rates"); } bool RefreshRateSelector::isVrrDevice() const { Loading Loading @@ -1560,16 +1563,24 @@ Fps RefreshRateSelector::findClosestKnownFrameRate(Fps frameRate) const { std::vector<float> RefreshRateSelector::getSupportedFrameRates() const { std::scoped_lock lock(mLock); // TODO(b/356986687) Remove the limit once we have the anchor list implementation. const size_t frameRatesSize = std::min<size_t>(11, mPrimaryFrameRates.size()); const size_t frameRatesSize = std::min<size_t>(11, mAllFrameRates.size()); std::vector<float> supportedFrameRates; supportedFrameRates.reserve(frameRatesSize); std::transform(mPrimaryFrameRates.rbegin(), mPrimaryFrameRates.rbegin() + static_cast<int>(frameRatesSize), std::transform(mAllFrameRates.rbegin(), mAllFrameRates.rbegin() + static_cast<int>(frameRatesSize), std::back_inserter(supportedFrameRates), [](FrameRateMode mode) { return mode.fps.getValue(); }); return supportedFrameRates; } FpsRange RefreshRateSelector::getSupportedFrameRateRangeLocked() const { using fps_approx_ops::operator<; if (mMaxRefreshRateModeIt->second->getPeakFps() < kMinSupportedFrameRate) { return {mMaxRefreshRateModeIt->second->getPeakFps(), kMinSupportedFrameRate}; } return {kMinSupportedFrameRate, mMaxRefreshRateModeIt->second->getPeakFps()}; } auto RefreshRateSelector::getIdleTimerAction() const -> KernelIdleTimerAction { std::lock_guard lock(mLock); Loading
services/surfaceflinger/Scheduler/RefreshRateSelector.h +4 −0 Original line number Diff line number Diff line Loading @@ -553,6 +553,7 @@ private: // Display modes that satisfy the Policy's ranges, filtered and sorted by refresh rate. std::vector<FrameRateMode> mPrimaryFrameRates GUARDED_BY(mLock); std::vector<FrameRateMode> mAppRequestFrameRates GUARDED_BY(mLock); std::vector<FrameRateMode> mAllFrameRates GUARDED_BY(mLock); // Caches whether the device is VRR-compatible based on the active display mode. std::atomic_bool mIsVrrDevice = false; Loading Loading @@ -597,6 +598,9 @@ private: // Used to detect (lack of) frame activity. ftl::Optional<scheduler::OneShotTimer> mIdleTimer; std::atomic<bool> mIdleTimerStarted = false; // Returns the range of supported frame rates. FpsRange getSupportedFrameRateRangeLocked() const REQUIRES(mLock); }; } // namespace android::scheduler
services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp +42 −0 Original line number Diff line number Diff line Loading @@ -4667,5 +4667,47 @@ TEST_P(RefreshRateSelectorTest, renderFrameRatesForVrr) { EXPECT_EQ(120_Hz, primaryRefreshRates[i].modePtr->getPeakFps()); } } TEST_P(RefreshRateSelectorTest, getSupportedFrameRates) { if (GetParam() != Config::FrameRateOverride::Enabled) { return; } auto selector = createSelector(kModes_60_90, kModeId90); const FpsRange range60 = {0_Hz, 60_Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy( {kModeId60, {range60, range60}, {range60, range60}})); // Irrespective of the policy we get the full range of possible frame rates const std::vector<float> expected = {90.0f, 60.0f, 45.0f, 30.0f, 22.5f, 20.0f}; const auto allSupportedFrameRates = selector.getSupportedFrameRates(); ASSERT_EQ(expected.size(), allSupportedFrameRates.size()); for (size_t i = 0; i < expected.size(); i++) { EXPECT_EQ(expected[i], allSupportedFrameRates[i]) << "expected " << expected[i] << " received " << allSupportedFrameRates[i]; } } TEST_P(RefreshRateSelectorTest, getSupportedFrameRatesArr) { if (GetParam() != Config::FrameRateOverride::Enabled) { return; } SET_FLAG_FOR_TEST(flags::vrr_config, true); const auto selector = createSelector(kVrrMode_120, kModeId120); const std::vector<float> expected = {120.0f, 80.0f, 60.0f, 48.0f, 40.0f, 34.285f, 30.0f, 26.666f, 24.0f, 21.818f, 20.0f}; const auto allSupportedFrameRates = selector.getSupportedFrameRates(); ASSERT_EQ(expected.size(), allSupportedFrameRates.size()); constexpr float kEpsilon = 0.001f; for (size_t i = 0; i < expected.size(); i++) { EXPECT_TRUE(std::abs(expected[i] - allSupportedFrameRates[i]) <= kEpsilon) << "expected " << expected[i] << " received " << allSupportedFrameRates[i]; } } } // namespace } // namespace android::scheduler