diff options
| -rw-r--r-- | services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp | 11 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp | 47 |
2 files changed, 47 insertions, 11 deletions
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp index 91e80432a4..0e4256b396 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp @@ -215,7 +215,7 @@ RefreshRate RefreshRateConfigs::getBestRefreshRate(const std::vector<LayerRequir int explicitExactOrMultipleVoteLayers = 0; int explicitExact = 0; float maxExplicitWeight = 0; - int seamedLayers = 0; + int seamedFocusedLayers = 0; for (const auto& layer : layers) { switch (layer.vote) { case LayerVoteType::NoVote: @@ -243,8 +243,8 @@ RefreshRate RefreshRateConfigs::getBestRefreshRate(const std::vector<LayerRequir break; } - if (layer.seamlessness == Seamlessness::SeamedAndSeamless) { - seamedLayers++; + if (layer.seamlessness == Seamlessness::SeamedAndSeamless && layer.focused) { + seamedFocusedLayers++; } } @@ -329,12 +329,11 @@ RefreshRate RefreshRateConfigs::getBestRefreshRate(const std::vector<LayerRequir // mode group otherwise. In second case, if the current mode group is different // from the default, this means a layer with seamlessness=SeamedAndSeamless has just // disappeared. - const bool isInPolicyForDefault = seamedLayers > 0 + const bool isInPolicyForDefault = seamedFocusedLayers > 0 ? scores[i].refreshRate->getModeGroup() == mCurrentRefreshRate->getModeGroup() : scores[i].refreshRate->getModeGroup() == defaultMode->getModeGroup(); - if (layer.seamlessness == Seamlessness::Default && !isInPolicyForDefault && - !layer.focused) { + if (layer.seamlessness == Seamlessness::Default && !isInPolicyForDefault) { ALOGV("%s ignores %s. Current mode = %s", formatLayerInfo(layer, weight).c_str(), scores[i].refreshRate->toString().c_str(), mCurrentRefreshRate->toString().c_str()); diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp index b0c0b6d602..eb54eb8c4a 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp @@ -1328,7 +1328,7 @@ TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersOnlySeamlessAndSeamed) .getModeId()); } -TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultAndSeamed) { +TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultFocusedAndSeamed) { auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups, /*currentConfigId=*/HWC_CONFIG_ID_60); @@ -1339,8 +1339,12 @@ TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultAndSeamed) { refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); - // If there's a layer with seamlessness=SeamedAndSeamless, another layer with - // seamlessness=Default can't change the mode group. + // If there's a focused layer with seamlessness=SeamedAndSeamless, another layer with + // seamlessness=Default can't change the mode group back to the group of the default + // mode. + // For example, this may happen when a video playback requests and gets a seamed switch, + // but another layer (with default seamlessness) starts animating. The animating layer + // should not cause a seamed switch. auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; layers[0].seamlessness = Seamlessness::Default; layers[0].desiredRefreshRate = Fps(60.0f); @@ -1348,10 +1352,10 @@ TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultAndSeamed) { layers[0].vote = LayerVoteType::ExplicitDefault; layers[0].name = "60Hz ExplicitDefault"; - layers.push_back(LayerRequirement{.weight = 0.5f}); + layers.push_back(LayerRequirement{.weight = 0.1f}); layers[1].seamlessness = Seamlessness::SeamedAndSeamless; layers[1].desiredRefreshRate = Fps(90.0f); - layers[1].focused = false; + layers[1].focused = true; layers[1].vote = LayerVoteType::ExplicitDefault; layers[1].name = "90Hz ExplicitDefault"; @@ -1360,6 +1364,39 @@ TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultAndSeamed) { .getModeId()); } +TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultNotFocusedAndSeamed) { + auto refreshRateConfigs = + std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups, + /*currentConfigId=*/HWC_CONFIG_ID_60); + RefreshRateConfigs::Policy policy; + policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode; + policy.allowGroupSwitching = true; + ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); + + refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); + + // Layer with seamlessness=Default can change the mode group if there's a not + // focused layer with seamlessness=SeamedAndSeamless. This happens for example, + // when in split screen mode the user switches between the two visible applications. + auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; + layers[0].seamlessness = Seamlessness::Default; + layers[0].desiredRefreshRate = Fps(60.0f); + layers[0].focused = true; + layers[0].vote = LayerVoteType::ExplicitDefault; + layers[0].name = "60Hz ExplicitDefault"; + + layers.push_back(LayerRequirement{.weight = 0.7f}); + layers[1].seamlessness = Seamlessness::SeamedAndSeamless; + layers[1].desiredRefreshRate = Fps(90.0f); + layers[1].focused = false; + layers[1].vote = LayerVoteType::ExplicitDefault; + layers[1].name = "90Hz ExplicitDefault"; + + ASSERT_EQ(HWC_CONFIG_ID_60, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) + .getModeId()); +} + TEST_F(RefreshRateConfigsTest, nonSeamlessVotePrefersSeamlessSwitches) { auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60Device, |