diff options
| -rw-r--r-- | services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp | 25 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp | 48 |
2 files changed, 63 insertions, 10 deletions
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp index ae4c3e5fd9..16be5e27b5 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp @@ -23,6 +23,9 @@ #include <chrono> #include <cmath> +#undef LOG_TAG +#define LOG_TAG "RefreshRateConfigs" + namespace android::scheduler { using AllRefreshRatesMapType = RefreshRateConfigs::AllRefreshRatesMapType; @@ -178,16 +181,17 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2( const auto layerPeriod = round<nsecs_t>(1e9f / layer.desiredRefreshRate); if (layer.vote == LayerVoteType::ExplicitDefault) { const auto layerScore = [&]() { - const auto [displayFramesQuot, displayFramesRem] = - getDisplayFrames(layerPeriod, displayPeriod); - if (displayFramesQuot == 0) { - // Layer desired refresh rate is higher the display rate. - return static_cast<float>(layerPeriod) / static_cast<float>(displayPeriod); + // Find the actual rate the layer will render, assuming + // that layerPeriod is the minimal time to render a frame + auto actualLayerPeriod = displayPeriod; + int multiplier = 1; + while (layerPeriod > actualLayerPeriod + MARGIN_FOR_PERIOD_CALCULATION) { + multiplier++; + actualLayerPeriod = displayPeriod * multiplier; } - - return 1.0f - - (static_cast<float>(displayFramesRem) / - static_cast<float>(layerPeriod)); + return std::min(1.0f, + static_cast<float>(layerPeriod) / + static_cast<float>(actualLayerPeriod)); }(); ALOGV("%s (ExplicitDefault, weight %.2f) %.2fHz gives %s score of %.2f", @@ -250,6 +254,7 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2( template <typename Iter> const RefreshRate* RefreshRateConfigs::getBestRefreshRate(Iter begin, Iter end) const { + constexpr auto EPSILON = 0.001f; const RefreshRate* bestRefreshRate = begin->first; float max = begin->second; for (auto i = begin; i != end; ++i) { @@ -258,7 +263,7 @@ const RefreshRate* RefreshRateConfigs::getBestRefreshRate(Iter begin, Iter end) ATRACE_INT(refreshRate->name.c_str(), round<int>(score * 100)); - if (score > max) { + if (score > max * (1 + EPSILON)) { max = score; bestRefreshRate = refreshRate; } diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp index 9d323962b9..7a11f58cad 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp @@ -1170,6 +1170,54 @@ TEST_F(RefreshRateConfigsTest, touchConsidered) { EXPECT_EQ(false, touchConsidered); } +TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_ExplicitDefault) { + bool ignored; + std::vector<RefreshRateConfigs::InputConfig> configs{ + {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60}, + {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72}, + {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}, + {HWC_CONFIG_ID_120, HWC_GROUP_ID_0, VSYNC_120}}}; + + auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/ + HWC_CONFIG_ID_60); + + auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; + auto& lr = layers[0]; + + // Prepare a table with the vote and the expected refresh rate + const std::vector<std::pair<float, float>> testCases = { + {130, 120}, {120, 120}, {119, 120}, {110, 120}, + + {100, 90}, {90, 90}, {89, 90}, + + {80, 72}, {73, 72}, {72, 72}, {71, 72}, {70, 72}, + + {65, 60}, {60, 60}, {59, 60}, {58, 60}, + + {55, 90}, {50, 90}, {45, 90}, + + {42, 120}, {40, 120}, {39, 120}, + + {37, 72}, {36, 72}, {35, 72}, + + {30, 60}, + }; + + for (const auto& test : testCases) { + lr.vote = LayerVoteType::ExplicitDefault; + lr.desiredRefreshRate = test.first; + + std::stringstream ss; + ss << "ExplicitDefault " << test.first << " fps"; + lr.name = ss.str(); + + const auto& refreshRate = + refreshRateConfigs->getRefreshRateForContentV2(layers, false, &ignored); + EXPECT_FLOAT_EQ(refreshRate.fps, test.second) + << "Expecting " << test.first << "fps => " << test.second << "Hz"; + } +} + } // namespace } // namespace scheduler } // namespace android |