Change swap chain stuffed detection logic

bug:29771461
bug:29413700
bug:30181577

Changes frame interval gap detection to look for wider gaps, as they
were incorrectly firing all the time.

Also adds a 500ms minimum gap between frames dropped because of stuffed
swap chain, to prevent dropping too often.

Change-Id: If16ed637d54bf37015704be102c5c2e3731a0824
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index bfcb0e5..4b9d7d5 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -217,9 +217,9 @@
     for (size_t i = 1; i < mSwapHistory.size(); i++) {
         auto& swapB = mSwapHistory[i];
 
-        // If there's a frameInterval gap we effectively already dropped a frame,
+        // If there's a multi-frameInterval gap we effectively already dropped a frame,
         // so consider the queue healthy.
-        if (swapA.swapCompletedTime - swapB.swapCompletedTime > frameInterval) {
+        if (swapA.swapCompletedTime - swapB.swapCompletedTime > frameInterval * 3) {
             return false;
         }
 
@@ -298,12 +298,17 @@
             // Already drew for this vsync pulse, UI draw request missed
             // the deadline for RT animations
             info.out.canDrawThisFrame = false;
-        } else if (vsyncDelta >= mRenderThread.timeLord().frameIntervalNanos()) {
-            // It's been at least an entire frame interval, assume
-            // the buffer queue is fine
+        } else if (vsyncDelta >= mRenderThread.timeLord().frameIntervalNanos() * 3
+                || (latestVsync - mLastDropVsync) < 500_ms) {
+            // It's been several frame intervals, assume the buffer queue is fine
+            // or the last drop was too recent
             info.out.canDrawThisFrame = true;
         } else {
             info.out.canDrawThisFrame = !isSwapChainStuffed();
+            if (!info.out.canDrawThisFrame) {
+                // dropping frame
+                mLastDropVsync = mRenderThread.timeLord().latestVsync();
+            }
         }
     } else {
         info.out.canDrawThisFrame = true;
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index b0d980b..3eef29b 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -208,6 +208,9 @@
     RingBuffer<SwapHistory, 3> mSwapHistory;
     int64_t mFrameNumber = -1;
 
+    // last vsync for a dropped frame due to stuffed queue
+    nsecs_t mLastDropVsync = 0;
+
     bool mOpaque;
 #if HWUI_NEW_OPS
     BakedOpRenderer::LightInfo mLightInfo;