SF: flush setRenderRate when changing mode
There is no point to try to syncronize changing the render rate
if the display mode changes. This would just cause more latency
to getting the next vsync.
Bug: 328140524
Test: presubmit
Change-Id: I78a82bee01ba793890d459564ab701d257851b49
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 3f91682..d92edb8 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -565,7 +565,7 @@
}));
}
-void Scheduler::setRenderRate(PhysicalDisplayId id, Fps renderFrameRate) {
+void Scheduler::setRenderRate(PhysicalDisplayId id, Fps renderFrameRate, bool applyImmediately) {
std::scoped_lock lock(mDisplayLock);
ftl::FakeGuard guard(kMainThreadContext);
@@ -586,7 +586,7 @@
ALOGV("%s %s (%s)", __func__, to_string(mode.fps).c_str(),
to_string(mode.modePtr->getVsyncRate()).c_str());
- display.schedulePtr->getTracker().setRenderRate(renderFrameRate);
+ display.schedulePtr->getTracker().setRenderRate(renderFrameRate, applyImmediately);
}
Fps Scheduler::getNextFrameInterval(PhysicalDisplayId id,
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 09f75fd..494a91b 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -188,7 +188,7 @@
const VsyncConfiguration& getVsyncConfiguration() const { return *mVsyncConfiguration; }
// Sets the render rate for the scheduler to run at.
- void setRenderRate(PhysicalDisplayId, Fps);
+ void setRenderRate(PhysicalDisplayId, Fps, bool applyImmediately);
void enableHardwareVsync(PhysicalDisplayId) REQUIRES(kMainThreadContext);
void disableHardwareVsync(PhysicalDisplayId, bool disallow) REQUIRES(kMainThreadContext);
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index 156cf99..58457d8 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -296,6 +296,10 @@
const auto now = TimePoint::fromNs(mClock->now());
purgeTimelines(now);
+ if (lastVsyncOpt && *lastVsyncOpt > timePoint) {
+ timePoint = *lastVsyncOpt;
+ }
+
const auto model = getVSyncPredictionModelLocked();
const auto threshold = model.slope / 2;
std::optional<TimePoint> vsyncOpt;
@@ -352,7 +356,7 @@
return mTimelines.back().isVSyncInPhase(model, vsync, frameRate);
}
-void VSyncPredictor::setRenderRate(Fps renderRate) {
+void VSyncPredictor::setRenderRate(Fps renderRate, bool applyImmediately) {
ATRACE_FORMAT("%s %s", __func__, to_string(renderRate).c_str());
ALOGV("%s %s: RenderRate %s ", __func__, to_string(mId).c_str(), to_string(renderRate).c_str());
std::lock_guard lock(mMutex);
@@ -360,8 +364,9 @@
mRenderRateOpt = renderRate;
const auto renderPeriodDelta =
prevRenderRate ? prevRenderRate->getPeriodNsecs() - renderRate.getPeriodNsecs() : 0;
- if (renderPeriodDelta > renderRate.getPeriodNsecs() &&
- mLastCommittedVsync.ns() - mClock->now() > 2 * renderRate.getPeriodNsecs()) {
+ const bool newRenderRateIsHigher = renderPeriodDelta > renderRate.getPeriodNsecs() &&
+ mLastCommittedVsync.ns() - mClock->now() > 2 * renderRate.getPeriodNsecs();
+ if (applyImmediately || newRenderRateIsHigher) {
mTimelines.clear();
mLastCommittedVsync = TimePoint::fromNs(0);
} else {
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.h b/services/surfaceflinger/Scheduler/VSyncPredictor.h
index a1e72d1..21039f1 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.h
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.h
@@ -68,7 +68,7 @@
void setDisplayModePtr(ftl::NonNull<DisplayModePtr>) final EXCLUDES(mMutex);
- void setRenderRate(Fps) final EXCLUDES(mMutex);
+ void setRenderRate(Fps, bool applyImmediately) final EXCLUDES(mMutex);
void onFrameBegin(TimePoint expectedPresentTime, TimePoint lastConfirmedPresentTime) final
EXCLUDES(mMutex);
diff --git a/services/surfaceflinger/Scheduler/VSyncTracker.h b/services/surfaceflinger/Scheduler/VSyncTracker.h
index 1e55a87..8787cdb 100644
--- a/services/surfaceflinger/Scheduler/VSyncTracker.h
+++ b/services/surfaceflinger/Scheduler/VSyncTracker.h
@@ -102,8 +102,10 @@
* when a display is running at 120Hz but the render frame rate is 60Hz.
*
* \param [in] Fps The render rate the tracker should operate at.
+ * \param [in] applyImmediately Whether to apply the new render rate immediately regardless of
+ * already committed vsyncs.
*/
- virtual void setRenderRate(Fps) = 0;
+ virtual void setRenderRate(Fps, bool applyImmediately) = 0;
virtual void onFrameBegin(TimePoint expectedPresentTime,
TimePoint lastConfirmedPresentTime) = 0;