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

Commit 3bd61066 authored by rnlee's avatar rnlee Committed by Rachel Lee
Browse files

Add sysprop for refresh rate threshold.

When the sysprop is enabled, layers asking for heuristic or multiple
will not vote for multiples >= $threshold amount. For example, 24 fps
would normally vote 120 hz because it is a multiple. Instead, it should
use the scoring calculation to determine a refresh rate < 120 Hz.

This addresses 24 fps videos for 60Hz and 120 Hz displays. The request
wants the refresh rate vote to be 60 Hz. (see bug)

BUG: 190815773
Test: atest libsurfaceflinger_tests
Change-Id: If2619258b93fb9c30e09253266d3d65e1a732047
parent a8f9cdbc
Loading
Loading
Loading
Loading
+36 −6
Original line number Diff line number Diff line
@@ -107,9 +107,39 @@ std::pair<nsecs_t, nsecs_t> RefreshRateConfigs::getDisplayFrames(nsecs_t layerPe
    return {quotient, remainder};
}

bool RefreshRateConfigs::isVoteAllowed(const LayerRequirement& layer,
                                       const RefreshRate& refreshRate) const {
    switch (layer.vote) {
        case LayerVoteType::ExplicitExactOrMultiple:
        case LayerVoteType::Heuristic:
            if (mConfig.frameRateMultipleThreshold != 0 &&
                refreshRate.fps.greaterThanOrEqualWithMargin(
                        Fps(mConfig.frameRateMultipleThreshold)) &&
                layer.desiredRefreshRate.lessThanWithMargin(
                        Fps(mConfig.frameRateMultipleThreshold / 2))) {
                // Don't vote high refresh rates past the threshold for layers with a low desired
                // refresh rate. For example, desired 24 fps with 120 Hz threshold means no vote for
                // 120 Hz, but desired 60 fps should have a vote.
                return false;
            }
            break;
        case LayerVoteType::ExplicitDefault:
        case LayerVoteType::ExplicitExact:
        case LayerVoteType::Max:
        case LayerVoteType::Min:
        case LayerVoteType::NoVote:
            break;
    }
    return true;
}

float RefreshRateConfigs::calculateLayerScoreLocked(const LayerRequirement& layer,
                                                    const RefreshRate& refreshRate,
                                                    bool isSeamlessSwitch) const {
    if (!isVoteAllowed(layer, refreshRate)) {
        return 0;
    }

    // Slightly prefer seamless switches.
    constexpr float kSeamedSwitchPenalty = 0.95f;
    const float seamlessness = isSeamlessSwitch ? 1.0f : kSeamedSwitchPenalty;
@@ -331,8 +361,9 @@ RefreshRate RefreshRateConfigs::getBestRefreshRateLocked(
    const auto& defaultMode = mRefreshRates.at(policy->defaultMode);

    for (const auto& layer : layers) {
        ALOGV("Calculating score for %s (%s, weight %.2f)", layer.name.c_str(),
              layerVoteTypeString(layer.vote).c_str(), layer.weight);
        ALOGV("Calculating score for %s (%s, weight %.2f, desired %.2f) ", layer.name.c_str(),
              layerVoteTypeString(layer.vote).c_str(), layer.weight,
              layer.desiredRefreshRate.getValue());
        if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min) {
            continue;
        }
@@ -646,9 +677,8 @@ void RefreshRateConfigs::setCurrentModeId(DisplayModeId modeId) {
}

RefreshRateConfigs::RefreshRateConfigs(const DisplayModes& modes, DisplayModeId currentModeId,
                                       bool enableFrameRateOverride)
      : mKnownFrameRates(constructKnownFrameRates(modes)),
        mEnableFrameRateOverride(enableFrameRateOverride) {
                                       Config config)
      : mKnownFrameRates(constructKnownFrameRates(modes)), mConfig(config) {
    updateDisplayModes(modes, currentModeId);
}

@@ -685,7 +715,7 @@ void RefreshRateConfigs::updateDisplayModes(const DisplayModes& modes,
    mMaxSupportedRefreshRate = sortedModes.back();

    mSupportsFrameRateOverride = false;
    if (mEnableFrameRateOverride) {
    if (mConfig.enableFrameRateOverride) {
        for (const auto& mode1 : sortedModes) {
            for (const auto& mode2 : sortedModes) {
                if (getFrameRateDivider(mode1->getFps(), mode2->getFps()) >= 2) {
+17 −3
Original line number Diff line number Diff line
@@ -302,8 +302,19 @@ public:
    // Returns a known frame rate that is the closest to frameRate
    Fps findClosestKnownFrameRate(Fps frameRate) const;

    // Configuration flags.
    struct Config {
        bool enableFrameRateOverride = false;

        // Specifies the upper refresh rate threshold (inclusive) for layer vote types of multiple
        // or heuristic, such that refresh rates higher than this value will not be voted for. 0 if
        // no threshold is set.
        int frameRateMultipleThreshold = 0;
    };

    RefreshRateConfigs(const DisplayModes& modes, DisplayModeId currentModeId,
                       bool enableFrameRateOverride = false);
                       Config config = {.enableFrameRateOverride = false,
                                        .frameRateMultipleThreshold = 0});

    void updateDisplayModes(const DisplayModes& mode, DisplayModeId currentModeId) EXCLUDES(mLock);

@@ -387,6 +398,9 @@ private:
    const Policy* getCurrentPolicyLocked() const REQUIRES(mLock);
    bool isPolicyValidLocked(const Policy& policy) const REQUIRES(mLock);

    // Returns whether the layer is allowed to vote for the given refresh rate.
    bool isVoteAllowed(const LayerRequirement&, const RefreshRate&) const;

    // calculates a score for a layer. Used to determine the display refresh rate
    // and the frame rate override for certains applications.
    float calculateLayerScoreLocked(const LayerRequirement&, const RefreshRate&,
@@ -424,7 +438,7 @@ private:
    // from based on the closest value.
    const std::vector<Fps> mKnownFrameRates;

    const bool mEnableFrameRateOverride;
    const Config mConfig;
    bool mSupportsFrameRateOverride;

    struct GetBestRefreshRateInvocation {
+9 −4
Original line number Diff line number Diff line
@@ -3118,10 +3118,15 @@ void SurfaceFlinger::initScheduler(const DisplayDeviceState& displayState) {
        return;
    }
    const auto displayId = displayState.physical->id;
    mRefreshRateConfigs = std::make_unique<
            scheduler::RefreshRateConfigs>(displayState.physical->supportedModes,
                                           displayState.physical->activeMode->getId(),
                                           android::sysprop::enable_frame_rate_override(false));
    scheduler::RefreshRateConfigs::Config config =
            {.enableFrameRateOverride = android::sysprop::enable_frame_rate_override(false),
             .frameRateMultipleThreshold =
                     base::GetIntProperty("debug.sf.frame_rate_multiple_threshold", 0)};
    mRefreshRateConfigs =
            std::make_unique<scheduler::RefreshRateConfigs>(displayState.physical->supportedModes,
                                                            displayState.physical->activeMode
                                                                    ->getId(),
                                                            config);
    const auto currRefreshRate = displayState.physical->activeMode->getFps();
    mRefreshRateStats = std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate,
                                                                      hal::PowerMode::OFF);
+168 −10
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@ protected:
                                     RefreshRate::ConstructorTag(0)};
    RefreshRate mExpected120Config = {HWC_CONFIG_ID_120, mConfig120, Fps(120),
                                      RefreshRate::ConstructorTag(0)};

private:
    DisplayModePtr createDisplayMode(DisplayModeId modeId, int32_t group, int64_t vsyncPeriod,
                                     ui::Size resolution = ui::Size());
@@ -487,6 +488,52 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_90) {
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}

TEST_F(RefreshRateConfigsTest, getBestRefreshRate_multipleThreshold_60_90) {
    RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 90};
    auto refreshRateConfigs =
            std::make_unique<RefreshRateConfigs>(m60_90Device,
                                                 /*currentConfigId=*/HWC_CONFIG_ID_60, config);

    auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
    auto& lr = layers[0];

    lr.vote = LayerVoteType::Min;
    lr.name = "Min";
    EXPECT_EQ(mExpected60Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr.vote = LayerVoteType::Max;
    lr.name = "Max";
    EXPECT_EQ(mExpected90Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr.desiredRefreshRate = Fps(90.0f);
    lr.vote = LayerVoteType::Heuristic;
    lr.name = "90Hz Heuristic";
    EXPECT_EQ(mExpected90Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr.desiredRefreshRate = Fps(60.0f);
    lr.name = "60Hz Heuristic";
    EXPECT_EQ(mExpected60Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr.desiredRefreshRate = Fps(45.0f);
    lr.name = "45Hz Heuristic";
    EXPECT_EQ(mExpected90Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr.desiredRefreshRate = Fps(30.0f);
    lr.name = "30Hz Heuristic";
    EXPECT_EQ(mExpected60Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr.desiredRefreshRate = Fps(24.0f);
    lr.name = "24Hz Heuristic";
    EXPECT_EQ(mExpected60Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}

TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_72_90) {
    auto refreshRateConfigs =
            std::make_unique<RefreshRateConfigs>(m60_72_90Device,
@@ -649,6 +696,99 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes) {
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}

TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes_multipleThreshold) {
    RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 120};
    auto refreshRateConfigs =
            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
                                                 /*currentConfigId=*/HWC_CONFIG_ID_60, config);

    auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                LayerRequirement{.weight = 1.0f}};
    auto& lr1 = layers[0];
    auto& lr2 = layers[1];

    lr1.desiredRefreshRate = Fps(24.0f);
    lr1.vote = LayerVoteType::ExplicitDefault;
    lr1.name = "24Hz ExplicitDefault";
    lr2.desiredRefreshRate = Fps(60.0f);
    lr2.vote = LayerVoteType::Heuristic;
    lr2.name = "60Hz Heuristic";
    EXPECT_EQ(mExpected120Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr1.desiredRefreshRate = Fps(24.0f);
    lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
    lr1.name = "24Hz ExplicitExactOrMultiple";
    lr2.desiredRefreshRate = Fps(60.0f);
    lr2.vote = LayerVoteType::Heuristic;
    lr2.name = "60Hz Heuristic";
    EXPECT_EQ(mExpected60Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr1.desiredRefreshRate = Fps(24.0f);
    lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
    lr1.name = "24Hz ExplicitExactOrMultiple";
    lr2.desiredRefreshRate = Fps(60.0f);
    lr2.vote = LayerVoteType::ExplicitDefault;
    lr2.name = "60Hz ExplicitDefault";
    EXPECT_EQ(mExpected72Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr1.desiredRefreshRate = Fps(24.0f);
    lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
    lr1.name = "24Hz ExplicitExactOrMultiple";
    lr2.desiredRefreshRate = Fps(90.0f);
    lr2.vote = LayerVoteType::Heuristic;
    lr2.name = "90Hz Heuristic";
    EXPECT_EQ(mExpected90Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr1.desiredRefreshRate = Fps(24.0f);
    lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
    lr1.name = "24Hz ExplicitExactOrMultiple";
    lr2.desiredRefreshRate = Fps(90.0f);
    lr2.vote = LayerVoteType::ExplicitDefault;
    lr2.name = "90Hz Heuristic";
    EXPECT_EQ(mExpected72Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr1.desiredRefreshRate = Fps(24.0f);
    lr1.vote = LayerVoteType::ExplicitDefault;
    lr1.name = "24Hz ExplicitDefault";
    lr2.desiredRefreshRate = Fps(90.0f);
    lr2.vote = LayerVoteType::Heuristic;
    lr2.name = "90Hz Heuristic";
    EXPECT_EQ(mExpected90Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr1.desiredRefreshRate = Fps(24.0f);
    lr1.vote = LayerVoteType::Heuristic;
    lr1.name = "24Hz Heuristic";
    lr2.desiredRefreshRate = Fps(90.0f);
    lr2.vote = LayerVoteType::ExplicitDefault;
    lr2.name = "90Hz ExplicitDefault";
    EXPECT_EQ(mExpected72Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr1.desiredRefreshRate = Fps(24.0f);
    lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
    lr1.name = "24Hz ExplicitExactOrMultiple";
    lr2.desiredRefreshRate = Fps(90.0f);
    lr2.vote = LayerVoteType::ExplicitDefault;
    lr2.name = "90Hz ExplicitDefault";
    EXPECT_EQ(mExpected72Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));

    lr1.desiredRefreshRate = Fps(24.0f);
    lr1.vote = LayerVoteType::ExplicitDefault;
    lr1.name = "24Hz ExplicitDefault";
    lr2.desiredRefreshRate = Fps(90.0f);
    lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
    lr2.name = "90Hz ExplicitExactOrMultiple";
    EXPECT_EQ(mExpected90Config,
              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}

TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60) {
    auto refreshRateConfigs =
            std::make_unique<RefreshRateConfigs>(m30_60Device,
@@ -819,6 +959,24 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo) {
    }
}

TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo_multipleThreshold_60_120) {
    RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 120};
    auto refreshRateConfigs =
            std::make_unique<RefreshRateConfigs>(m60_120Device,
                                                 /*currentConfigId=*/HWC_CONFIG_ID_60, config);

    auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
    auto& lr = layers[0];

    lr.vote = LayerVoteType::ExplicitExactOrMultiple;
    for (float fps = 23.0f; fps < 25.0f; fps += 0.1f) {
        lr.desiredRefreshRate = Fps(fps);
        const auto& refreshRate =
                refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false});
        EXPECT_EQ(mExpected60Config, refreshRate) << fps << "Hz chooses " << refreshRate.getName();
    }
}

TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getBestRefreshRate_Explicit) {
    auto refreshRateConfigs =
            std::make_unique<RefreshRateConfigs>(m60_90Device,
@@ -1732,10 +1890,10 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExact) {
}

TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactEnableFrameRateOverride) {
    RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
    auto refreshRateConfigs =
            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
                                                 /*currentConfigId=*/HWC_CONFIG_ID_60,
                                                 /*enableFrameRateOverride=*/true);
                                                 /*currentConfigId=*/HWC_CONFIG_ID_60, config);

    auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                LayerRequirement{.weight = 0.5f}};
@@ -1846,10 +2004,10 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_WritesCache) {
}

TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactTouchBoost) {
    RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
    auto refreshRateConfigs =
            std::make_unique<RefreshRateConfigs>(m60_120Device,
                                                 /*currentConfigId=*/HWC_CONFIG_ID_60,
                                                 /*enableFrameRateOverride=*/true);
                                                 /*currentConfigId=*/HWC_CONFIG_ID_60, config);

    auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                LayerRequirement{.weight = 0.5f}};
@@ -1950,10 +2108,10 @@ TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_noLayers) {
}

TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) {
    RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
    auto refreshRateConfigs =
            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
                                                 HWC_CONFIG_ID_120,
                                                 /*enableFrameRateOverride=*/true);
                                                 HWC_CONFIG_ID_120, config);

    auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
    layers[0].name = "Test layer";
@@ -1995,10 +2153,10 @@ TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) {
}

TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) {
    RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
    auto refreshRateConfigs =
            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
                                                 HWC_CONFIG_ID_120,
                                                 /*enableFrameRateOverride=*/true);
                                                 HWC_CONFIG_ID_120, config);

    auto layers = std::vector<LayerRequirement>{
            LayerRequirement{.ownerUid = 1234, .weight = 1.0f},
@@ -2035,10 +2193,10 @@ TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) {
}

TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_touch) {
    RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
    auto refreshRateConfigs =
            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
                                                 HWC_CONFIG_ID_120,
                                                 /*enableFrameRateOverride=*/true);
                                                 HWC_CONFIG_ID_120, config);

    auto layers = std::vector<LayerRequirement>{
            LayerRequirement{.ownerUid = 1234, .weight = 1.0f},