Revert "SurfaceFlinger: more aggressive infrequent layer detection"
This reverts commit 1adbb727595c6da51bb088e4ce3f8070d9b32808.
Reason for revert: Causing regression with b/157096772
Change-Id: Ib2009f7a4ecbd268ea69304853a91bd22674ec1e
Test: Play 24fps video in YouTube PIP mode and rotate the device - no jank
Test: Chrome playing video - no refresh rate switching
Test: Hide/Show keyboard when inputting text
Test: Running Hay Day and observing refresh rate
Bug: 157096772
Bug: 155062712
Bug: 156654519
diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
index c16387a..8a6d52a 100644
--- a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
@@ -27,10 +27,8 @@
namespace android::scheduler {
-LayerInfoV2::LayerInfoV2(const std::string& name, nsecs_t highRefreshRatePeriod,
- LayerHistory::LayerVoteType defaultVote)
- : mName(name),
- mHighRefreshRatePeriod(highRefreshRatePeriod),
+LayerInfoV2::LayerInfoV2(nsecs_t highRefreshRatePeriod, LayerHistory::LayerVoteType defaultVote)
+ : mHighRefreshRatePeriod(highRefreshRatePeriod),
mDefaultVote(defaultVote),
mLayerVote({defaultVote, 0.0f}) {}
@@ -50,23 +48,42 @@
}
}
-bool LayerInfoV2::isFrequent(nsecs_t now) const {
- for (auto it = mFrameTimes.crbegin(); it != mFrameTimes.crend(); ++it) {
- if (now - it->queueTime >= MAX_FREQUENT_LAYER_PERIOD_NS.count()) {
- ALOGV("%s infrequent (last frame is %.2fms ago", mName.c_str(),
- (now - mFrameTimes.back().queueTime) / 1e6f);
- return false;
- }
+bool LayerInfoV2::isFrameTimeValid(const FrameTimeData& frameTime) const {
+ return frameTime.queueTime >= std::chrono::duration_cast<std::chrono::nanoseconds>(
+ mFrameTimeValidSince.time_since_epoch())
+ .count();
+}
- const auto numFrames = std::distance(mFrameTimes.crbegin(), it + 1);
- if (numFrames >= FREQUENT_LAYER_WINDOW_SIZE) {
- ALOGV("%s frequent (burst of %zu frames", mName.c_str(), numFrames);
- return true;
+bool LayerInfoV2::isFrequent(nsecs_t now) const {
+ // Find the first valid frame time
+ auto it = mFrameTimes.begin();
+ for (; it != mFrameTimes.end(); ++it) {
+ if (isFrameTimeValid(*it)) {
+ break;
}
}
- ALOGV("%s infrequent (not enough frames %zu)", mName.c_str(), mFrameTimes.size());
- return false;
+ // If we know nothing about this layer we consider it as frequent as it might be the start
+ // of an animation.
+ if (std::distance(it, mFrameTimes.end()) < FREQUENT_LAYER_WINDOW_SIZE) {
+ return true;
+ }
+
+ // Find the first active frame
+ for (; it != mFrameTimes.end(); ++it) {
+ if (it->queueTime >= getActiveLayerThreshold(now)) {
+ break;
+ }
+ }
+
+ const auto numFrames = std::distance(it, mFrameTimes.end());
+ if (numFrames < FREQUENT_LAYER_WINDOW_SIZE) {
+ return false;
+ }
+
+ // Layer is considered frequent if the average frame rate is higher than the threshold
+ const auto totalTime = mFrameTimes.back().queueTime - it->queueTime;
+ return (1e9f * (numFrames - 1)) / totalTime >= MIN_FPS_FOR_FREQUENT_LAYER;
}
bool LayerInfoV2::hasEnoughDataForHeuristic() const {
@@ -75,6 +92,10 @@
return false;
}
+ if (!isFrameTimeValid(mFrameTimes.front())) {
+ return false;
+ }
+
if (mFrameTimes.size() < HISTORY_SIZE &&
mFrameTimes.back().queueTime - mFrameTimes.front().queueTime < HISTORY_TIME.count()) {
return false;
@@ -170,22 +191,18 @@
std::pair<LayerHistory::LayerVoteType, float> LayerInfoV2::getRefreshRate(nsecs_t now) {
if (mLayerVote.type != LayerHistory::LayerVoteType::Heuristic) {
- ALOGV("%s voted %d ", mName.c_str(), static_cast<int>(mLayerVote.type));
return {mLayerVote.type, mLayerVote.fps};
}
if (!isFrequent(now)) {
- ALOGV("%s is infrequent", mName.c_str());
return {LayerHistory::LayerVoteType::Min, 0};
}
auto refreshRate = calculateRefreshRateIfPossible();
if (refreshRate.has_value()) {
- ALOGV("%s calculated refresh rate: %.2f", mName.c_str(), refreshRate.value());
return {LayerHistory::LayerVoteType::Heuristic, refreshRate.value()};
}
- ALOGV("%s Max (can't resolve refresh rate", mName.c_str());
return {LayerHistory::LayerVoteType::Max, 0};
}