diff options
-rw-r--r-- | services/surfaceflinger/Scheduler/LayerInfo.cpp | 17 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/LayerInfo.h | 4 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp | 4 |
3 files changed, 21 insertions, 4 deletions
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp index 03844ef183..875bdc84f5 100644 --- a/services/surfaceflinger/Scheduler/LayerInfo.cpp +++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp @@ -116,12 +116,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 @@ -324,6 +336,7 @@ LayerInfo::RefreshRateVotes LayerInfo::getRefreshRateVote(const RefreshRateSelec 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. votes.push_back({LayerHistory::LayerVoteType::Min, Fps()}); @@ -334,7 +347,7 @@ LayerInfo::RefreshRateVotes LayerInfo::getRefreshRateVote(const RefreshRateSelec 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()); diff --git a/services/surfaceflinger/Scheduler/LayerInfo.h b/services/surfaceflinger/Scheduler/LayerInfo.h index 3b4d8239d2..129b4c44d4 100644 --- a/services/surfaceflinger/Scheduler/LayerInfo.h +++ b/services/surfaceflinger/Scheduler/LayerInfo.h @@ -357,6 +357,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 diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp index c432ad0a24..7e3e61f6fb 100644 --- a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp @@ -1124,8 +1124,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, |