SurfaceFlinger: allow switching when layers vote to refresh rate

This CL is a refinement of the refresh rate switching algorithm
to allow refresh rate switching even if some of the layers voted
explicitly for a refresh rate.

Test: Run ExoPlayer demo app and scroll the list while playing a video
Bug: 147516364
Change-Id: Id01ff8477804bba9e859545e20b05eeb1ec0d319
diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
index 345b8f9..b755798 100644
--- a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
@@ -61,21 +61,35 @@
 }
 
 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;
+        }
+    }
+
     // If we know nothing about this layer we consider it as frequent as it might be the start
     // of an animation.
-    if (mFrameTimes.size() < FREQUENT_LAYER_WINDOW_SIZE) {
+    if (std::distance(it, mFrameTimes.end()) < FREQUENT_LAYER_WINDOW_SIZE) {
         return true;
     }
 
-    // Layer is frequent if the earliest value in the window of most recent present times is
-    // within threshold.
-    const auto it = mFrameTimes.end() - FREQUENT_LAYER_WINDOW_SIZE;
-    if (!isFrameTimeValid(*it)) {
-        return true;
+    // Find the first active frame
+    for (; it != mFrameTimes.end(); ++it) {
+        if (it->queueTime >= getActiveLayerThreshold(now)) {
+            break;
+        }
     }
 
-    const nsecs_t threshold = now - MAX_FREQUENT_LAYER_PERIOD_NS.count();
-    return it->queueTime >= threshold;
+    const auto numFrames = std::distance(it, mFrameTimes.end()) - 1;
+    if (numFrames <= 0) {
+        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) / totalTime >= MIN_FPS_FOR_FREQUENT_LAYER;
 }
 
 bool LayerInfoV2::hasEnoughDataForHeuristic() const {