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

Commit a9e0d8a9 authored by Alec Mouri's avatar Alec Mouri Committed by Android (Google) Code Review
Browse files

Merge "Lock display refresh rate when primary range is a single rate." into rvc-dev

parents c7f9e4ee 11232a26
Loading
Loading
Loading
Loading
+25 −5
Original line number Diff line number Diff line
@@ -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;
+118 −3
Original line number Diff line number Diff line
@@ -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));