SF: call onFrameBegin before scheduling the next frame
Bug: 329036771
Test: presubmit
Change-Id: Ie8643df787aa1080c59f280b005b40841715970b
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 7968096..005ec05 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -250,18 +250,6 @@
mPacesetterFrameDurationFractionToSkip = 0.f;
}
- if (FlagManager::getInstance().vrr_config()) {
- const auto minFramePeriod = pacesetterPtr->schedulePtr->minFramePeriod();
- const auto presentFenceForPastVsync =
- pacesetterPtr->targeterPtr->target().presentFenceForPastVsync(minFramePeriod);
- const auto lastConfirmedPresentTime = presentFenceForPastVsync->getSignalTime();
- if (lastConfirmedPresentTime != Fence::SIGNAL_TIME_PENDING &&
- lastConfirmedPresentTime != Fence::SIGNAL_TIME_INVALID) {
- pacesetterPtr->schedulePtr->getTracker()
- .onFrameBegin(expectedVsyncTime, TimePoint::fromNs(lastConfirmedPresentTime));
- }
- }
-
const auto resultsPerDisplay = compositor.composite(pacesetterPtr->displayId, targeters);
if (FlagManager::getInstance().vrr_config()) {
compositor.sendNotifyExpectedPresentHint(pacesetterPtr->displayId);
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
index a5bb6c2..d6a3f62 100644
--- a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
@@ -71,6 +71,7 @@
bool isFramePending() const { return mFramePending; }
bool didMissFrame() const { return mFrameMissed; }
bool didMissHwcFrame() const { return mHwcFrameMissed && !mGpuFrameMissed; }
+ TimePoint lastSignaledFrameTime() const { return mLastSignaledFrameTime; };
protected:
explicit FrameTarget(const std::string& displayLabel);
@@ -98,6 +99,7 @@
FenceTimePtr fenceTime = FenceTime::NO_FENCE;
};
std::array<FenceWithFenceTime, 2> mPresentFences;
+ TimePoint mLastSignaledFrameTime;
private:
friend class FrameTargeterTestBase;
diff --git a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
index 68c277d..8335568 100644
--- a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
+++ b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
@@ -113,6 +113,7 @@
mFrameMissed = mFramePending || [&] {
const nsecs_t pastPresentTime = pastPresentFence->getSignalTime();
if (pastPresentTime < 0) return false;
+ mLastSignaledFrameTime = TimePoint::fromNs(pastPresentTime);
const nsecs_t frameMissedSlop = vsyncPeriod.ns() / 2;
return lastScheduledPresentTime.ns() < pastPresentTime - frameMissedSlop;
}();
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 734058a..cf94f94 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2606,6 +2606,14 @@
flushTransactions, transactionsAreEmpty);
}
+ // Tell VsyncTracker that we are going to present this frame before scheduling
+ // setTransactionFlags which will schedule another SF frame. This was if the tracker
+ // needs to adjust the vsync timeline, it will be done before the next frame.
+ if (FlagManager::getInstance().vrr_config() && mustComposite) {
+ mScheduler->getVsyncSchedule()->getTracker().onFrameBegin(
+ pacesetterFrameTarget.expectedPresentTime(),
+ pacesetterFrameTarget.lastSignaledFrameTime());
+ }
if (transactionFlushNeeded()) {
setTransactionFlags(eTransactionFlushNeeded);
}