diff options
author | 2023-09-21 16:01:40 +0000 | |
---|---|---|
committer | 2023-09-21 16:01:40 +0000 | |
commit | 2a405b58abad6d0d1b9a9a82be2bc5c678ceb17b (patch) | |
tree | 22ccd2ed677e9987436028871558865222749674 | |
parent | cbe4538eece1d0b58dbbc5724a9db82229901d0b (diff) | |
parent | d646eff9b57a517a7932ee0fcbad0512faded7f7 (diff) |
Merge "Prevent the refresh rate changed frequently when small dirty" into udc-qpr-dev am: cb6209fcc6 am: d646eff9b5
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/24703073
Change-Id: Ic942bfc48a1dfe86f4a10b270e9f1e05a20ce9e6
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-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, |