SurfaceFlinger: tune FPS detection logic

Keep 200ms of history for layer instead of 100ms to accomodate
scenarios of YouTube playing music and renders at ~6Hz.
In addition, change the way layers are considered relevant for fps
detection to have a time based mechanism as well. Going by frame number
only makes slow layers to become relevant too late.

Fixes: 135009095
Test: YouTube playing music
Change-Id: Id38290e453111c5cfd4a23383b36b6862c2dd386
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp
index 95d7d31..3104724 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp
@@ -38,6 +38,12 @@
     mLastUpdatedTime = std::max(lastPresentTime, systemTime());
     mPresentTimeHistory.insertPresentTime(mLastUpdatedTime);
 
+    if (mLastPresentTime == 0) {
+        // First frame
+        mLastPresentTime = lastPresentTime;
+        return;
+    }
+
     const nsecs_t timeDiff = lastPresentTime - mLastPresentTime;
     mLastPresentTime = lastPresentTime;
     // Ignore time diff that are too high - those are stale values
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.h b/services/surfaceflinger/Scheduler/LayerInfo.h
index 02b6aef..90d4269 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.h
+++ b/services/surfaceflinger/Scheduler/LayerInfo.h
@@ -55,7 +55,7 @@
 
         float getRefreshRateAvg() const {
             nsecs_t refreshDuration = mMinRefreshDuration;
-            if (mElements.size() == HISTORY_SIZE) {
+            if (mElements.size() > 0) {
                 refreshDuration = scheduler::calculate_mean(mElements);
             }
 
@@ -86,14 +86,23 @@
         // Checks whether the present time that was inserted HISTORY_SIZE ago is within a
         // certain threshold: TIME_EPSILON_NS.
         bool isRelevant() const {
-            const int64_t obsoleteEpsilon = systemTime() - scheduler::TIME_EPSILON_NS.count();
-            // The layer had to publish at least HISTORY_SIZE of updates, and the first
-            // update should not be older than TIME_EPSILON_NS nanoseconds.
-            if (mElements.size() == HISTORY_SIZE &&
-                mElements.at(HISTORY_SIZE - 1) > obsoleteEpsilon) {
-                return true;
+            if (mElements.size() < 2) {
+                return false;
             }
-            return false;
+
+            // The layer had to publish at least HISTORY_SIZE or HISTORY_TIME of updates
+            if (mElements.size() != HISTORY_SIZE &&
+                mElements.at(mElements.size() - 1) - mElements.at(0) < HISTORY_TIME.count()) {
+                return false;
+            }
+
+            // The last update should not be older than TIME_EPSILON_NS nanoseconds.
+            const int64_t obsoleteEpsilon = systemTime() - scheduler::TIME_EPSILON_NS.count();
+            if (mElements.at(mElements.size() - 1) < obsoleteEpsilon) {
+                return false;
+            }
+
+            return true;
         }
 
         void clearHistory() { mElements.clear(); }
@@ -101,6 +110,7 @@
     private:
         std::deque<nsecs_t> mElements;
         static constexpr size_t HISTORY_SIZE = 10;
+        static constexpr std::chrono::nanoseconds HISTORY_TIME = 500ms;
     };
 
 public:
diff --git a/services/surfaceflinger/Scheduler/SchedulerUtils.h b/services/surfaceflinger/Scheduler/SchedulerUtils.h
index 3bf3922..d3b1bd0 100644
--- a/services/surfaceflinger/Scheduler/SchedulerUtils.h
+++ b/services/surfaceflinger/Scheduler/SchedulerUtils.h
@@ -37,12 +37,12 @@
 static constexpr uint32_t HWC2_SCREEN_OFF_CONFIG_ID = 0xffffffff;
 
 // This number is used when we try to determine how long does a given layer stay relevant.
-// Currently it is set to 100ms, because that would indicate 10Hz rendering.
-static constexpr std::chrono::nanoseconds TIME_EPSILON_NS = 100ms;
+// The value is set based on testing different scenarios.
+static constexpr std::chrono::nanoseconds TIME_EPSILON_NS = 200ms;
 
 // This number is used when we try to determine how long do we keep layer information around
-// before we remove it. Currently it is set to 100ms.
-static constexpr std::chrono::nanoseconds OBSOLETE_TIME_EPSILON_NS = 100ms;
+// before we remove it.
+static constexpr std::chrono::nanoseconds OBSOLETE_TIME_EPSILON_NS = 200ms;
 
 // Calculates the statistical mean (average) in the data structure (array, vector). The
 // function does not modify the contents of the array.