diff options
3 files changed, 60 insertions, 3 deletions
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp index 8202515bec..d1de737a89 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp @@ -194,9 +194,22 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2( } } - float max = 0; + // Now that we scored all the refresh rates we need to pick the one that got the highest score. + // In case of a tie we will pick the higher refresh rate if any of the layers wanted Max, + // or the lower otherwise. + const RefreshRate* bestRefreshRate = maxVoteLayers > 0 + ? getBestRefreshRate(scores.rbegin(), scores.rend()) + : getBestRefreshRate(scores.begin(), scores.end()); + + return bestRefreshRate == nullptr ? *mCurrentRefreshRate : *bestRefreshRate; +} + +template <typename Iter> +const RefreshRate* RefreshRateConfigs::getBestRefreshRate(Iter begin, Iter end) const { const RefreshRate* bestRefreshRate = nullptr; - for (const auto [refreshRate, score] : scores) { + float max = 0; + for (auto i = begin; i != end; ++i) { + const auto [refreshRate, score] = *i; ALOGV("%s scores %.2f", refreshRate->name.c_str(), score); ATRACE_INT(refreshRate->name.c_str(), round<int>(score * 100)); @@ -207,7 +220,7 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2( } } - return bestRefreshRate == nullptr ? *mCurrentRefreshRate : *bestRefreshRate; + return bestRefreshRate; } const AllRefreshRatesMapType& RefreshRateConfigs::getAllRefreshRates() const { diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h index e5bb55710d..1132a8c58c 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h @@ -182,6 +182,12 @@ private: const std::function<bool(const RefreshRate&)>& shouldAddRefreshRate, std::vector<const RefreshRate*>* outRefreshRates); + // Returns the refresh rate with the highest score in the collection specified from begin + // to end. If there are more than one with the same highest refresh rate, the first one is + // returned. + template <typename Iter> + const RefreshRate* getBestRefreshRate(Iter begin, Iter end) const; + // The list of refresh rates, indexed by display config ID. This must not change after this // object is initialized. AllRefreshRatesMapType mRefreshRates; diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp index 841c624a3f..99c5f3d4cd 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp @@ -745,6 +745,44 @@ TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_75HzC } } +TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_Multiples) { + std::vector<RefreshRateConfigs::InputConfig> configs{ + {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60}, + {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}}; + auto refreshRateConfigs = + std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60); + + RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60}; + RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90}; + + auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, + LayerRequirement{.weight = 1.0f}}; + auto& lr1 = layers[0]; + auto& lr2 = layers[1]; + + lr1.vote = LayerVoteType::ExplicitExactOrMultiple; + lr1.desiredRefreshRate = 60.0f; + lr2.vote = LayerVoteType::Heuristic; + lr2.desiredRefreshRate = 90.0f; + EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers)); + + lr1.vote = LayerVoteType::ExplicitExactOrMultiple; + lr1.desiredRefreshRate = 60.0f; + lr2.vote = LayerVoteType::Max; + EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers)); + + lr1.vote = LayerVoteType::ExplicitExactOrMultiple; + lr1.desiredRefreshRate = 30.0f; + lr2.vote = LayerVoteType::Heuristic; + lr2.desiredRefreshRate = 90.0f; + EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers)); + + lr1.vote = LayerVoteType::ExplicitExactOrMultiple; + lr1.desiredRefreshRate = 30.0f; + lr2.vote = LayerVoteType::Max; + EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers)); +} + } // namespace } // namespace scheduler } // namespace android |