Add Choreo method for vsync callback start time.
Currently store the start times globally.
Bug: 210043506
Test: perfetto log of with & w/o CL, using Chromium apk, bug 198192946
Change-Id: I33bd31adf72e3cb6c9979bf9e9a5518a03a03237
diff --git a/libs/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp
index a3eebdd..8240b08 100644
--- a/libs/nativedisplay/AChoreographer.cpp
+++ b/libs/nativedisplay/AChoreographer.cpp
@@ -111,6 +111,7 @@
struct {
std::mutex lock;
std::vector<Choreographer*> ptrs GUARDED_BY(lock);
+ std::map<AVsyncId, int64_t> startTimes GUARDED_BY(lock);
bool registeredToDisplayManager GUARDED_BY(lock) = false;
std::atomic<nsecs_t> mLastKnownVsync = -1;
@@ -160,6 +161,7 @@
void scheduleCallbacks();
ChoreographerFrameCallbackDataImpl createFrameCallbackData(nsecs_t timestamp) const;
+ void registerStartTime() const;
std::mutex mLock;
// Protected by mLock
@@ -172,6 +174,9 @@
const sp<Looper> mLooper;
const std::thread::id mThreadId;
+
+ // Approximation of num_threads_using_choreographer * num_frames_of_history with leeway.
+ static constexpr size_t kMaxStartTimes = 250;
};
static thread_local Choreographer* gChoreographer;
@@ -392,6 +397,7 @@
if (cb.vsyncCallback != nullptr) {
const ChoreographerFrameCallbackDataImpl frameCallbackData =
createFrameCallbackData(timestamp);
+ registerStartTime();
mInCallback = true;
cb.vsyncCallback(reinterpret_cast<const AChoreographerFrameCallbackData*>(
&frameCallbackData),
@@ -452,6 +458,16 @@
.choreographer = this};
}
+void Choreographer::registerStartTime() const {
+ std::scoped_lock _l(gChoreographers.lock);
+ for (VsyncEventData::FrameTimeline frameTimeline : mLastVsyncEventData.frameTimelines) {
+ while (gChoreographers.startTimes.size() >= kMaxStartTimes) {
+ gChoreographers.startTimes.erase(gChoreographers.startTimes.begin());
+ }
+ gChoreographers.startTimes[frameTimeline.vsyncId] = systemTime(SYSTEM_TIME_MONOTONIC);
+ }
+}
+
} // namespace android
using namespace android;
@@ -566,6 +582,16 @@
return AChoreographer_to_Choreographer(choreographer)->getFrameInterval();
}
+int64_t AChoreographer_getStartTimeNanosForVsyncId(AVsyncId vsyncId) {
+ std::scoped_lock _l(gChoreographers.lock);
+ const auto iter = gChoreographers.startTimes.find(vsyncId);
+ if (iter == gChoreographers.startTimes.end()) {
+ ALOGW("Start time was not found for vsync id: %" PRId64, vsyncId);
+ return 0;
+ }
+ return iter->second;
+}
+
} // namespace android
/* Glue for the NDK interface */