diff options
| author | 2020-05-27 21:55:30 +0000 | |
|---|---|---|
| committer | 2020-05-27 21:55:30 +0000 | |
| commit | a9e0d8a9e348fa9c494cd38fe9a3c84d95c8ea83 (patch) | |
| tree | 3074ff9c7d40ef14f99966672b832c4022d718e3 | |
| parent | c7f9e4eea2c97ed653df990a38a92feca55c5db8 (diff) | |
| parent | 11232a26ad736ccdee6f5e164836412e5ef2288e (diff) | |
Merge "Lock display refresh rate when primary range is a single rate." into rvc-dev
| -rw-r--r-- | services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp | 30 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp | 121 |
2 files changed, 143 insertions, 8 deletions
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp index 4a4f9c8111..e181c1253c 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp @@ -128,15 +128,24 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate( } } + const bool hasExplicitVoteLayers = + explicitDefaultVoteLayers > 0 || explicitExactOrMultipleVoteLayers > 0; + // Consider the touch event if there are no Explicit* layers. Otherwise wait until after we've // selected a refresh rate to see if we should apply touch boost. - if (touchActive && explicitDefaultVoteLayers == 0 && explicitExactOrMultipleVoteLayers == 0) { + if (touchActive && !hasExplicitVoteLayers) { ALOGV("TouchBoost - choose %s", getMaxRefreshRateByPolicyLocked().getName().c_str()); if (touchConsidered) *touchConsidered = true; return getMaxRefreshRateByPolicyLocked(); } - if (!touchActive && idle) { + // If the primary range consists of a single refresh rate then we can only + // move out the of range if layers explicitly request a different refresh + // rate. + const Policy* policy = getCurrentPolicyLocked(); + const bool primaryRangeIsSingleRate = policy->primaryRange.min == policy->primaryRange.max; + + if (!touchActive && idle && !(primaryRangeIsSingleRate && hasExplicitVoteLayers)) { return getMinRefreshRateByPolicyLocked(); } @@ -150,8 +159,6 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate( return getMinRefreshRateByPolicyLocked(); } - const Policy* policy = getCurrentPolicyLocked(); - // Find the best refresh rate based on score std::vector<std::pair<const RefreshRate*, float>> scores; scores.reserve(mAppRequestRefreshRates.size()); @@ -171,7 +178,8 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate( for (auto i = 0u; i < scores.size(); i++) { bool inPrimaryRange = scores[i].first->inPolicy(policy->primaryRange.min, policy->primaryRange.max); - if (!inPrimaryRange && layer.vote != LayerVoteType::ExplicitDefault && + if ((primaryRangeIsSingleRate || !inPrimaryRange) && + layer.vote != LayerVoteType::ExplicitDefault && layer.vote != LayerVoteType::ExplicitExactOrMultiple) { // Only layers with explicit frame rate settings are allowed to score refresh rates // outside the primary range. @@ -263,11 +271,23 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate( ? getBestRefreshRate(scores.rbegin(), scores.rend()) : getBestRefreshRate(scores.begin(), scores.end()); + if (primaryRangeIsSingleRate) { + // If we never scored any layers, then choose the rate from the primary + // range instead of picking a random score from the app range. + if (std::all_of(scores.begin(), scores.end(), + [](std::pair<const RefreshRate*, float> p) { return p.second == 0; })) { + return getMaxRefreshRateByPolicyLocked(); + } else { + return *bestRefreshRate; + } + } + // Consider the touch event if there are no ExplicitDefault layers. ExplicitDefault are mostly // interactive (as opposed to ExplicitExactOrMultiple) and therefore if those posted an explicit // vote we should not change it if we get a touch event. Only apply touch boost if it will // actually increase the refresh rate over the normal selection. const RefreshRate& touchRefreshRate = getMaxRefreshRateByPolicyLocked(); + if (touchActive && explicitDefaultVoteLayers == 0 && bestRefreshRate->fps < touchRefreshRate.fps) { if (touchConsidered) *touchConsidered = true; diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp index 692f71f8d3..c919e93795 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp @@ -1205,6 +1205,121 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitDefault) { } } +TEST_F(RefreshRateConfigsTest, + getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresTouchFlag) { + auto refreshRateConfigs = + std::make_unique<RefreshRateConfigs>(m60_90Device, + /*currentConfigId=*/HWC_CONFIG_ID_90); + + ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( + {HWC_CONFIG_ID_90, {90.f, 90.f}, {60.f, 90.f}}), + 0); + + auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; + auto& lr = layers[0]; + + bool touchConsidered = false; + lr.vote = LayerVoteType::ExplicitExactOrMultiple; + lr.desiredRefreshRate = 60.0f; + lr.name = "60Hz ExplicitExactOrMultiple"; + EXPECT_EQ(mExpected60Config, + refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ true, /*idle*/ false, + &touchConsidered)); + EXPECT_EQ(false, touchConsidered); + + lr.vote = LayerVoteType::ExplicitDefault; + lr.desiredRefreshRate = 60.0f; + lr.name = "60Hz ExplicitDefault"; + EXPECT_EQ(mExpected60Config, + refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ true, /*idle*/ false, + &touchConsidered)); + EXPECT_EQ(false, touchConsidered); +} + +TEST_F(RefreshRateConfigsTest, + getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresIdleFlag) { + auto refreshRateConfigs = + std::make_unique<RefreshRateConfigs>(m60_90Device, + /*currentConfigId=*/HWC_CONFIG_ID_60); + + ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( + {HWC_CONFIG_ID_60, {60.f, 60.f}, {60.f, 90.f}}), + 0); + + auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; + auto& lr = layers[0]; + + bool touchConsidered = false; + lr.vote = LayerVoteType::ExplicitExactOrMultiple; + lr.desiredRefreshRate = 90.0f; + lr.name = "90Hz ExplicitExactOrMultiple"; + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ true, + &touchConsidered)); + + lr.vote = LayerVoteType::ExplicitDefault; + lr.desiredRefreshRate = 90.0f; + lr.name = "90Hz ExplicitDefault"; + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ true, + &touchConsidered)); +} + +TEST_F(RefreshRateConfigsTest, + getBestRefreshRate_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitLayers) { + auto refreshRateConfigs = + std::make_unique<RefreshRateConfigs>(m60_90Device, + /*currentConfigId=*/HWC_CONFIG_ID_90); + + ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( + {HWC_CONFIG_ID_90, {90.f, 90.f}, {60.f, 90.f}}), + 0); + + bool touchConsidered = false; + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate({}, /*touchActive*/ false, /*idle*/ false, + &touchConsidered)); + EXPECT_EQ(false, touchConsidered); + + auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; + auto& lr = layers[0]; + + lr.vote = LayerVoteType::ExplicitExactOrMultiple; + lr.desiredRefreshRate = 60.0f; + lr.name = "60Hz ExplicitExactOrMultiple"; + EXPECT_EQ(mExpected60Config, + refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false, + &touchConsidered)); + + lr.vote = LayerVoteType::ExplicitDefault; + lr.desiredRefreshRate = 60.0f; + lr.name = "60Hz ExplicitDefault"; + EXPECT_EQ(mExpected60Config, + refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false, + &touchConsidered)); + + lr.vote = LayerVoteType::Heuristic; + lr.desiredRefreshRate = 60.0f; + lr.name = "60Hz Heuristic"; + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false, + &touchConsidered)); + + lr.vote = LayerVoteType::Max; + lr.desiredRefreshRate = 60.0f; + lr.name = "60Hz Max"; + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false, + &touchConsidered)); + + lr.vote = LayerVoteType::Min; + lr.desiredRefreshRate = 60.0f; + lr.name = "60Hz Min"; + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false, + &touchConsidered)); +} + TEST_F(RefreshRateConfigsTest, groupSwitching) { auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups, @@ -1234,7 +1349,7 @@ TEST_F(RefreshRateConfigsTest, groupSwitching) { TEST_F(RefreshRateConfigsTest, primaryVsAppRequestPolicy) { auto refreshRateConfigs = - std::make_unique<RefreshRateConfigs>(m60_90Device, + std::make_unique<RefreshRateConfigs>(m30_60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; @@ -1253,7 +1368,7 @@ TEST_F(RefreshRateConfigsTest, primaryVsAppRequestPolicy) { }; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( - {HWC_CONFIG_ID_60, {60.f, 60.f}, {60.f, 90.f}}), + {HWC_CONFIG_ID_60, {30.f, 60.f}, {30.f, 90.f}}), 0); bool touchConsidered; EXPECT_EQ(HWC_CONFIG_ID_60, @@ -1262,7 +1377,7 @@ TEST_F(RefreshRateConfigsTest, primaryVsAppRequestPolicy) { &touchConsidered) .getConfigId()); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::NoVote, 90.f)); - EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Min, 90.f)); + EXPECT_EQ(HWC_CONFIG_ID_30, getFrameRate(LayerVoteType::Min, 90.f)); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Max, 90.f)); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Heuristic, 90.f)); EXPECT_EQ(HWC_CONFIG_ID_90, getFrameRate(LayerVoteType::ExplicitDefault, 90.f)); |