SurfaceFlinger: tune infrequent detection logic more

A layer will be considered frequent unless proven otherwise, in order
to make sure animations will change the refresh rate as soon as possible.
In addition, if a layer is classified infrequent, then we will keep it
infrequent until we get a burst of frames. These two policies combined
allow us to differentiate between an animating layer and a layer that
usually doesn't animate.

Bug: 157096772
Test: Play 24fps video in YouTube PIP mode and rotate the device - no jank
Test: Chrome playing video - no refresh rate switching
Test: Cursor blinking on Messages - switch to lowest refresh rate quickly
Change-Id: I3629b6e4786cd43919f51465e347f2abb52234d9
diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
index c16387a..78f4433 100644
--- a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
@@ -50,23 +50,28 @@
     }
 }
 
-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::isFrequent(nsecs_t now) {
+    mLastReportedIsFrequent = [&] {
+        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;
+            }
+
+            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;
+            }
         }
 
-        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;
-        }
-    }
+        ALOGV("%s %sfrequent (not enough frames %zu)", mName.c_str(),
+              mLastReportedIsFrequent ? "" : "in", mFrameTimes.size());
+        return mLastReportedIsFrequent;
+    }();
 
-    ALOGV("%s infrequent (not enough frames %zu)", mName.c_str(), mFrameTimes.size());
-    return false;
+    return mLastReportedIsFrequent;
 }
 
 bool LayerInfoV2::hasEnoughDataForHeuristic() const {