diff options
author | Arthur Hung <arthurhung@google.com> | 2023-09-21 14:25:43 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2023-09-21 14:25:43 +0000 |
commit | cb6209fcc6e5424c4578ef02cf91ac0dbbd9e2cd (patch) | |
tree | ed2b11274a7083fe361a2aa6593f56489b1e0e39 | |
parent | 6d86aa2d2c0353ac959dedb1a920ea3cc828542b (diff) | |
parent | 8144e02e8d2b5fc31078cc39d8f51268535b468b (diff) | |
download | native-cb6209fcc6e5424c4578ef02cf91ac0dbbd9e2cd.tar.gz |
Merge "Prevent the refresh rate changed frequently when small dirty" into udc-qpr-dev
-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 348e2b9c72..875e87084f 100644 --- a/services/surfaceflinger/Scheduler/LayerInfo.cpp +++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp @@ -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()); diff --git a/services/surfaceflinger/Scheduler/LayerInfo.h b/services/surfaceflinger/Scheduler/LayerInfo.h index 6a8580630d..122796b3d5 100644 --- a/services/surfaceflinger/Scheduler/LayerInfo.h +++ b/services/surfaceflinger/Scheduler/LayerInfo.h @@ -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 diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp index be4b026b35..69128c02b6 100644 --- a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp @@ -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, |