Reland "SF: Encapsulate frame targeting"
Introduce FrameTargeter to isolate a display's per-frame metrics around
past/upcoming deadline targets. The Scheduler updates the FrameTargeter
on frame begin/end, whereas ICompositor (concretely SurfaceFlinger) has
read-only access via the FrameTarget interface.
For now, only instantiate the pacesetter's FrameTargeter.
The reverted Idf9f43b37f3479c94a478d154eaa46f43e0c6c9d had an incorrect
functional change that adjusted `earliestPresentTime` based on the past
VSYNC, which differs from the previous frame's VSYNC when targeting two
VSYNCs ahead. This CL restores the `earliestPresentTime` to be relative
to the previous frame.
Bug: 262269033
Bug: 241285475
Bug: 241285191
Test: Perfetto
Test: dumpsys SurfaceFlinger --scheduler
Test: atest libscheduler_test:FrameTargeterTest
Test: systemui-bubble-1-jank-suite on raven-userdebug
Change-Id: I584e299e8af55baae1125f45fd47b13f705a268c
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 918d401..41639b6 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -171,14 +171,21 @@
void Scheduler::onFrameSignal(ICompositor& compositor, VsyncId vsyncId,
TimePoint expectedVsyncTime) {
- const TimePoint frameTime = SchedulerClock::now();
+ mPacesetterFrameTargeter.beginFrame({.frameBeginTime = SchedulerClock::now(),
+ .vsyncId = vsyncId,
+ .expectedVsyncTime = expectedVsyncTime,
+ .sfWorkDuration =
+ mVsyncModulator->getVsyncConfig().sfWorkDuration},
+ *getVsyncSchedule());
- if (!compositor.commit(frameTime, vsyncId, expectedVsyncTime)) {
+ if (!compositor.commit(mPacesetterFrameTargeter.target())) {
return;
}
- compositor.composite(frameTime, vsyncId);
+ const auto compositeResult = compositor.composite(mPacesetterFrameTargeter);
compositor.sample();
+
+ mPacesetterFrameTargeter.endFrame(compositeResult);
}
std::optional<Fps> Scheduler::getFrameRateOverride(uid_t uid) const {
@@ -188,23 +195,23 @@
.getFrameRateOverrideForUid(uid, supportsFrameRateOverrideByContent);
}
-bool Scheduler::isVsyncValid(TimePoint expectedVsyncTimestamp, uid_t uid) const {
+bool Scheduler::isVsyncValid(TimePoint expectedVsyncTime, uid_t uid) const {
const auto frameRate = getFrameRateOverride(uid);
if (!frameRate.has_value()) {
return true;
}
ATRACE_FORMAT("%s uid: %d frameRate: %s", __func__, uid, to_string(*frameRate).c_str());
- return getVsyncSchedule()->getTracker().isVSyncInPhase(expectedVsyncTimestamp.ns(), *frameRate);
+ return getVsyncSchedule()->getTracker().isVSyncInPhase(expectedVsyncTime.ns(), *frameRate);
}
-bool Scheduler::isVsyncInPhase(TimePoint timePoint, const Fps frameRate) const {
- return getVsyncSchedule()->getTracker().isVSyncInPhase(timePoint.ns(), frameRate);
+bool Scheduler::isVsyncInPhase(TimePoint expectedVsyncTime, Fps frameRate) const {
+ return getVsyncSchedule()->getTracker().isVSyncInPhase(expectedVsyncTime.ns(), frameRate);
}
impl::EventThread::ThrottleVsyncCallback Scheduler::makeThrottleVsyncCallback() const {
- return [this](nsecs_t expectedVsyncTimestamp, uid_t uid) {
- return !isVsyncValid(TimePoint::fromNs(expectedVsyncTimestamp), uid);
+ return [this](nsecs_t expectedVsyncTime, uid_t uid) {
+ return !isVsyncValid(TimePoint::fromNs(expectedVsyncTime), uid);
};
}
@@ -716,6 +723,8 @@
mFrameRateOverrideMappings.dump(dumper);
dumper.eol();
+
+ mPacesetterFrameTargeter.dump(dumper);
}
void Scheduler::dumpVsync(std::string& out) const {