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

Commit c14d1a9f authored by Rachel Lee's avatar Rachel Lee Committed by Android (Google) Code Review
Browse files

Merge "Add sysprop for refresh rate threshold." into sc-dev

parents 504a4d8f 3bd61066
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},