Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ae0b5356 authored by Marin Shalamanov's avatar Marin Shalamanov
Browse files

RefreshRateConfigs: Fix for default seamlessness and seamed layers

When there's a focused layer with has requested a seamless change
a layer with default seamlessness is not supposed to be able to
change the refresh rate group. This behaviour is covered by the test
groupSwitchingWithTwoLayersDefaultFocusedAndSeamed.

However if the seamed layer is not focused a default layer is
allowed to switch back to the group of the default mode.

Test: atest RefreshRateConfigsTest
Bug: 183128900
Change-Id: I1a7da19fbfda3b221bda6f2d2dbb9fa65de23cf5
parent bb65d055
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -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());
+42 −5
Original line number Diff line number Diff line
@@ -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,