Loading services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +25 −5 Original line number Diff line number Diff line Loading @@ -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(); } Loading @@ -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()); Loading @@ -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. Loading Loading @@ -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; Loading services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +118 −3 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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}}; Loading @@ -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, Loading @@ -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)); Loading Loading
services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +25 −5 Original line number Diff line number Diff line Loading @@ -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(); } Loading @@ -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()); Loading @@ -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. Loading Loading @@ -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; Loading
services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +118 −3 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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}}; Loading @@ -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, Loading @@ -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)); Loading