Pass actual present time to ViewRootImpl
To measure end-to-end touch latency, we need to report the actual
present time to ViewRootImpl. ViewRootImpl, in turn, will report this
information to InputDispatcher. Finally, InputDispatcher will combine
all known information for a specific input event, and will report this
data to westworld.
In another patch, we will add a new call, 'reportLatencyInfo', to
InputPublisher. This call will allow the app to send this latency data
to InputDispatcher.
Bug: 169866723
Test: printed the input event present times inside ViewRootImpl
Change-Id: Ibd3a2cfeb1a340eb15cd2165071df1f8589634af
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f69ddac..9793300 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -599,10 +599,41 @@
// 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());
+ mFrameMetricsReporter->reportFrameMetrics(frameInfo->data(), false /*hasPresentTime*/);
}
}
+void CanvasContext::reportMetricsWithPresentTime() {
+ if (mFrameMetricsReporter == nullptr) {
+ return;
+ }
+ if (mNativeSurface == nullptr) {
+ return;
+ }
+ FrameInfo* forthBehind;
+ int64_t frameNumber;
+ { // acquire lock
+ std::scoped_lock lock(mLast4FrameInfosMutex);
+ if (mLast4FrameInfos.size() != mLast4FrameInfos.capacity()) {
+ // Not enough frames yet
+ return;
+ }
+ // Surface object keeps stats for the last 8 frames.
+ std::tie(forthBehind, frameNumber) = mLast4FrameInfos.front();
+ } // release lock
+
+ nsecs_t presentTime = 0;
+ native_window_get_frame_timestamps(
+ mNativeSurface->getNativeWindow(), frameNumber, nullptr /*outRequestedPresentTime*/,
+ nullptr /*outAcquireTime*/, nullptr /*outLatchTime*/,
+ nullptr /*outFirstRefreshStartTime*/, nullptr /*outLastRefreshStartTime*/,
+ nullptr /*outGpuCompositionDoneTime*/, &presentTime, nullptr /*outDequeueReadyTime*/,
+ nullptr /*outReleaseTime*/);
+
+ forthBehind->set(FrameInfoIndex::DisplayPresentTime) = presentTime;
+ mFrameMetricsReporter->reportFrameMetrics(forthBehind->data(), true /*hasPresentTime*/);
+}
+
void CanvasContext::onSurfaceStatsAvailable(void* context, ASurfaceControl* control,
ASurfaceControlStats* stats) {
@@ -624,6 +655,9 @@
}
}
}
+
+ instance->reportMetricsWithPresentTime();
+
if (frameInfo != nullptr) {
if (gpuCompleteTime == -1) {
gpuCompleteTime = frameInfo->get(FrameInfoIndex::SwapBuffersCompleted);
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 2e7b2f6..74f426e 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -219,6 +219,12 @@
SkRect computeDirtyRect(const Frame& frame, SkRect* dirty);
void finishFrame(FrameInfo* frameInfo);
+ /**
+ * Invoke 'reportFrameMetrics' on the last frame stored in 'mLast4FrameInfos'.
+ * Populate the 'presentTime' field before calling.
+ */
+ void reportMetricsWithPresentTime();
+
// The same type as Frame.mWidth and Frame.mHeight
int32_t mLastFrameWidth = 0;
int32_t mLastFrameHeight = 0;