Change hwui jank detection to use deadline & gpu completion (1/2)

- Use GPU finish time as well as actual deadline to determine jank
rate.
- Use dynamic interval to adjust for 60/90hz switching
- Move frame metrics reporting into JankTracker to adjust the
deadline communicated to the app when in stuffing scenario.
- Adjust double-stuffing detection to be a bit more readable.

Test: GraphicsStatsValidationTest.java
Test: adb shell dumpsys gfxinfo
Test: FrameMetricsListenerTest
Test: Log output of FrameMetricsObserver
Bug: 169858044
Change-Id: I3a6b8ed163e2cf9cf2b67667110340ebe35f98a1
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index aedb5c2..b2a9863 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -473,6 +473,9 @@
         return;
     }
 
+    mCurrentFrameInfo->set(FrameInfoIndex::FrameInterval) =
+            mRenderThread.timeLord().frameIntervalNanos();
+
     mCurrentFrameInfo->markIssueDrawCommandsStart();
 
     Frame frame = mRenderPipeline->getFrame();
@@ -591,25 +594,13 @@
             mCurrentFrameInfo->markFrameCompleted();
             mCurrentFrameInfo->set(FrameInfoIndex::GpuCompleted)
                     = mCurrentFrameInfo->get(FrameInfoIndex::FrameCompleted);
-            finishFrame(mCurrentFrameInfo);
+            mJankTracker.finishFrame(*mCurrentFrameInfo, mFrameMetricsReporter);
         }
     }
 
     mRenderThread.cacheManager().onFrameCompleted();
 }
 
-void CanvasContext::finishFrame(FrameInfo* frameInfo) {
-    // TODO (b/169858044): Consolidate this into a single call.
-    mJankTracker.finishFrame(*frameInfo);
-    mJankTracker.finishGpuDraw(*frameInfo);
-
-    // TODO (b/169858044): Move this into JankTracker to adjust deadline when queue is
-    // double-stuffed.
-    if (CC_UNLIKELY(mFrameMetricsReporter.get() != nullptr)) {
-        mFrameMetricsReporter->reportFrameMetrics(frameInfo->data(), false /*hasPresentTime*/);
-    }
-}
-
 void CanvasContext::reportMetricsWithPresentTime() {
     if (mFrameMetricsReporter == nullptr) {
         return;
@@ -675,7 +666,7 @@
         }
         frameInfo->set(FrameInfoIndex::FrameCompleted) = gpuCompleteTime;
         frameInfo->set(FrameInfoIndex::GpuCompleted) = gpuCompleteTime;
-        instance->finishFrame(frameInfo);
+        instance->mJankTracker.finishFrame(*frameInfo, instance->mFrameMetricsReporter);
     }
 }
 
@@ -704,10 +695,11 @@
     nsecs_t vsync = mRenderThread.timeLord().computeFrameTimeNanos();
     int64_t vsyncId = mRenderThread.timeLord().lastVsyncId();
     int64_t frameDeadline = mRenderThread.timeLord().lastFrameDeadline();
+    int64_t frameInterval = mRenderThread.timeLord().frameIntervalNanos();
     int64_t frameInfo[UI_THREAD_FRAME_INFO_SIZE];
     UiFrameInfoBuilder(frameInfo)
         .addFlag(FrameInfoFlags::RTAnimation)
-        .setVsync(vsync, vsync, vsyncId, frameDeadline);
+        .setVsync(vsync, vsync, vsyncId, frameDeadline, frameInterval);
 
     TreeInfo info(TreeInfo::MODE_RT_ONLY, *this);
     prepareTree(info, frameInfo, systemTime(SYSTEM_TIME_MONOTONIC), node);
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 7a38a3b..cb92aa1 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -161,7 +161,9 @@
     int64_t intendedVsync = mFrameInfo[static_cast<int>(FrameInfoIndex::IntendedVsync)];
     int64_t vsyncId = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameTimelineVsyncId)];
     int64_t frameDeadline = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameDeadline)];
-    mRenderThread->timeLord().vsyncReceived(vsync, intendedVsync, vsyncId, frameDeadline);
+    int64_t frameInterval = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameInterval)];
+    mRenderThread->timeLord().vsyncReceived(vsync, intendedVsync, vsyncId, frameDeadline,
+            frameInterval);
     bool canDraw = mContext->makeCurrent();
     mContext->unpinImages();
 
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 79b9388..682baa6 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -87,9 +87,10 @@
     RenderThread* rt = reinterpret_cast<RenderThread*>(data);
     int64_t vsyncId = AChoreographer_getVsyncId(rt->mChoreographer);
     int64_t frameDeadline = AChoreographer_getFrameDeadline(rt->mChoreographer);
+    int64_t frameInterval = AChoreographer_getFrameInterval(rt->mChoreographer);
     rt->mVsyncRequested = false;
-    if (rt->timeLord().vsyncReceived(frameTimeNanos, frameTimeNanos, vsyncId, frameDeadline) &&
-            !rt->mFrameCallbackTaskPending) {
+    if (rt->timeLord().vsyncReceived(frameTimeNanos, frameTimeNanos, vsyncId, frameDeadline,
+            frameInterval) && !rt->mFrameCallbackTaskPending) {
         ATRACE_NAME("queue mFrameCallbackTask");
         rt->mFrameCallbackTaskPending = true;
         nsecs_t runAt = (frameTimeNanos + rt->mDispatchFrameDelay);
diff --git a/libs/hwui/renderthread/TimeLord.cpp b/libs/hwui/renderthread/TimeLord.cpp
index abb6330..406066c 100644
--- a/libs/hwui/renderthread/TimeLord.cpp
+++ b/libs/hwui/renderthread/TimeLord.cpp
@@ -27,11 +27,14 @@
                        mFrameDeadline(std::numeric_limits<int64_t>::max()){}
 
 bool TimeLord::vsyncReceived(nsecs_t vsync, nsecs_t intendedVsync, int64_t vsyncId,
-                             int64_t frameDeadline) {
+                             int64_t frameDeadline, nsecs_t frameInterval) {
     if (intendedVsync > mFrameIntendedTimeNanos) {
         mFrameIntendedTimeNanos = intendedVsync;
         mFrameVsyncId = vsyncId;
         mFrameDeadline = frameDeadline;
+        if (frameInterval > 0) {
+            mFrameIntervalNanos = frameInterval;
+        }
     }
 
     if (vsync > mFrameTimeNanos) {
diff --git a/libs/hwui/renderthread/TimeLord.h b/libs/hwui/renderthread/TimeLord.h
index fa05c030..8cd6733 100644
--- a/libs/hwui/renderthread/TimeLord.h
+++ b/libs/hwui/renderthread/TimeLord.h
@@ -33,7 +33,7 @@
 
     // returns true if the vsync is newer, false if it was rejected for staleness
     bool vsyncReceived(nsecs_t vsync, nsecs_t indendedVsync, int64_t vsyncId,
-                       int64_t frameDeadline);
+                       int64_t frameDeadline, nsecs_t frameInterval);
     nsecs_t latestVsync() { return mFrameTimeNanos; }
     nsecs_t computeFrameTimeNanos();
     int64_t lastVsyncId() const { return mFrameVsyncId; }