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

Commit 8144e02e authored by Arthur Hung's avatar Arthur Hung
Browse files

Prevent the refresh rate changed frequently when small dirty

Count the small dirty to ensure the recent frames are consistently
in updating small dirty.

Bug: 283055450
Test: atest LayerHistoryTest
Change-Id: I5282821be1d1269475e2acbf040626607d3c5536
parent a67a1d9e
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -114,12 +114,24 @@ LayerInfo::Frequent LayerInfo::isFrequent(nsecs_t now) const {
        }
    }

    // Vote the small dirty when a layer contains at least HISTORY_SIZE of small dirty updates.
    bool isSmallDirty = false;
    if (smallDirtyCount >= kNumSmallDirtyThreshold) {
        if (mLastSmallDirtyCount >= HISTORY_SIZE) {
            isSmallDirty = true;
        } else {
            mLastSmallDirtyCount++;
        }
    } else {
        mLastSmallDirtyCount = 0;
    }

    if (isFrequent || isInfrequent) {
        // If the layer was previously inconclusive, we clear
        // the history as indeterminate layers changed to frequent,
        // and we should not look at the stale data.
        return {isFrequent, isFrequent && !mIsFrequencyConclusive, /* isConclusive */ true,
                /* isSmallDirty */ smallDirtyCount >= kNumSmallDirtyThreshold};
                isSmallDirty};
    }

    // If we can't determine whether the layer is frequent or not, we return
@@ -304,6 +316,7 @@ LayerInfo::LayerVote LayerInfo::getRefreshRateVote(const RefreshRateSelector& se
        ATRACE_FORMAT_INSTANT("infrequent");
        ALOGV("%s is infrequent", mName.c_str());
        mLastRefreshRate.infrequent = true;
        mLastSmallDirtyCount = 0;
        // Infrequent layers vote for minimal refresh rate for
        // battery saving purposes and also to prevent b/135718869.
        return {LayerHistory::LayerVoteType::Min, Fps()};
@@ -313,7 +326,7 @@ LayerInfo::LayerVote LayerInfo::getRefreshRateVote(const RefreshRateSelector& se
        clearHistory(now);
    }

    // Return no vote if the latest frames are small dirty.
    // Return no vote if the recent frames are small dirty.
    if (frequent.isSmallDirty && !mLastRefreshRate.reported.isValid()) {
        ATRACE_FORMAT_INSTANT("NoVote (small dirty)");
        ALOGV("%s is small dirty", mName.c_str());
+4 −0
Original line number Diff line number Diff line
@@ -306,6 +306,10 @@ private:

    RefreshRateHistory mRefreshRateHistory;

    // This will be accessed from only one thread when counting a layer is frequent or infrequent,
    // and to determine whether a layer is in small dirty updating.
    mutable int32_t mLastSmallDirtyCount = 0;

    mutable std::unordered_map<LayerHistory::LayerVoteType, std::string> mTraceTags;

    // Shared for all LayerInfo instances
+2 −2
Original line number Diff line number Diff line
@@ -1013,8 +1013,8 @@ TEST_F(LayerHistoryTest, smallDirtyInMultiLayer) {

    LayerHistory::Summary summary;

    // layer1 is active but infrequent.
    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
    // layer1 is updating small dirty.
    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE + FREQUENT_LAYER_WINDOW_SIZE + 1; i++) {
        auto props = layer1->getLayerProps();
        props.isSmallDirty = true;
        history().record(layer1->getSequence(), props, 0 /*presentTime*/, time,