SurfaceFlinger: fix wake up time when sf duration change
When SF changes its work duration, it may already have a scheduled
wake up callback. In this case the callback needs to be updated with the
new duration.
Bug: 172683933
Test: launch an app and observe systraces
Change-Id: Ie63cd5fa3f82f193cfba031bbbc0b4f8bf8086a9
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index 1343375..47a4f42 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -90,6 +90,7 @@
{
std::lock_guard lock(mVsync.mutex);
mVsync.lastCallbackTime = std::chrono::nanoseconds(vsyncTime);
+ mVsync.mScheduled = false;
}
mHandler->dispatchInvalidate(mVsync.tokenManager->generateTokenForPredictions(
{targetWakeupTime, readyTime, vsyncTime}),
@@ -114,6 +115,10 @@
ATRACE_CALL();
std::lock_guard lock(mVsync.mutex);
mVsync.workDuration = workDuration;
+ if (mVsync.mScheduled) {
+ mVsync.registration->schedule({mVsync.workDuration.get().count(), /*readyDuration=*/0,
+ mVsync.lastCallbackTime.count()});
+ }
}
void MessageQueue::waitMessage() {
@@ -147,13 +152,10 @@
if (mEvents) {
mEvents->requestNextVsync();
} else {
- const auto [workDuration, lastVsyncCallback] = [&] {
- std::lock_guard lock(mVsync.mutex);
- std::chrono::nanoseconds mWorkDurationNanos = mVsync.workDuration;
- return std::make_pair(mWorkDurationNanos.count(), mVsync.lastCallbackTime.count());
- }();
-
- mVsync.registration->schedule({workDuration, /*readyDuration=*/0, lastVsyncCallback});
+ std::lock_guard lock(mVsync.mutex);
+ mVsync.mScheduled = true;
+ mVsync.registration->schedule({mVsync.workDuration.get().count(), /*readyDuration=*/0,
+ mVsync.lastCallbackTime.count()});
}
}
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h
index 139b38e..99ce3a6 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.h
+++ b/services/surfaceflinger/Scheduler/MessageQueue.h
@@ -109,6 +109,7 @@
TracedOrdinal<std::chrono::nanoseconds> workDuration
GUARDED_BY(mutex) = {"VsyncWorkDuration-sf", std::chrono::nanoseconds(0)};
std::chrono::nanoseconds lastCallbackTime GUARDED_BY(mutex) = std::chrono::nanoseconds{0};
+ bool mScheduled GUARDED_BY(mutex) = false;
TracedOrdinal<int> value = {"VSYNC-sf", 0};
};
diff --git a/services/surfaceflinger/TracedOrdinal.h b/services/surfaceflinger/TracedOrdinal.h
index 49cf80c..eee4bec 100644
--- a/services/surfaceflinger/TracedOrdinal.h
+++ b/services/surfaceflinger/TracedOrdinal.h
@@ -57,7 +57,9 @@
trace();
}
- operator T() const { return mData; }
+ T get() const { return mData; }
+
+ operator T() const { return get(); }
TracedOrdinal& operator=(T other) {
mData = other;