Revert "Revert "SF: pass a render rate to VsyncTracker instead of a divisor""
This reverts commit 3d21d3afa1056efacf702b74449f9e2e7b5701f1.
Reason for revert: https://b.corp.google.com/issues/269561042#comment14
Bug: 269561042
Change-Id: Iae8d0e62be2eafb4278b64ffcb1524ece211a00c
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 17cdff9..dab01ba 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -418,11 +418,7 @@
ALOGV("%s %s (%s)", __func__, to_string(mode.fps).c_str(),
to_string(mode.modePtr->getFps()).c_str());
- const auto divisor = RefreshRateSelector::getFrameRateDivisor(mode.modePtr->getFps(), mode.fps);
- LOG_ALWAYS_FATAL_IF(divisor == 0, "%s <> %s -- not divisors", to_string(mode.fps).c_str(),
- to_string(mode.fps).c_str());
-
- mVsyncSchedule->getTracker().setDivisor(static_cast<unsigned>(divisor));
+ mVsyncSchedule->getTracker().setRenderRate(renderFrameRate);
}
void Scheduler::resync() {
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index 5a5afd8..de7b338 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -272,13 +272,26 @@
// update the mLastVsyncSequence for reference point
mLastVsyncSequence = getVsyncSequenceLocked(timePoint);
- const auto mod = mLastVsyncSequence->seq % mDivisor;
- if (mod == 0) {
+ const auto renderRatePhase = [&]() REQUIRES(mMutex) -> int {
+ if (!mRenderRate) return 0;
+
+ const auto divisor =
+ RefreshRateSelector::getFrameRateDivisor(Fps::fromPeriodNsecs(mIdealPeriod),
+ *mRenderRate);
+ if (divisor <= 1) return 0;
+
+ const int mod = mLastVsyncSequence->seq % divisor;
+ if (mod == 0) return 0;
+
+ return divisor - mod;
+ }();
+
+ if (renderRatePhase == 0) {
return mLastVsyncSequence->vsyncTime;
}
auto const [slope, intercept] = getVSyncPredictionModelLocked();
- const auto approximateNextVsync = mLastVsyncSequence->vsyncTime + slope * (mDivisor - mod);
+ const auto approximateNextVsync = mLastVsyncSequence->vsyncTime + slope * renderRatePhase;
return nextAnticipatedVSyncTimeFromLocked(approximateNextVsync - slope / 2);
}
@@ -317,10 +330,10 @@
return vsyncSequence.seq % divisor == 0;
}
-void VSyncPredictor::setDivisor(unsigned divisor) {
- ALOGV("%s: %d", __func__, divisor);
+void VSyncPredictor::setRenderRate(Fps fps) {
+ ALOGV("%s: %s", __func__, to_string(fps).c_str());
std::lock_guard lock(mMutex);
- mDivisor = divisor;
+ mRenderRate = fps;
}
VSyncPredictor::Model VSyncPredictor::getVSyncPredictionModel() const {
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.h b/services/surfaceflinger/Scheduler/VSyncPredictor.h
index d0e3098..cd5d9ef 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.h
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.h
@@ -67,7 +67,7 @@
bool isVSyncInPhase(nsecs_t timePoint, Fps frameRate) const final EXCLUDES(mMutex);
- void setDivisor(unsigned divisor) final EXCLUDES(mMutex);
+ void setRenderRate(Fps) final EXCLUDES(mMutex);
void dump(std::string& result) const final EXCLUDES(mMutex);
@@ -106,7 +106,7 @@
size_t mLastTimestampIndex GUARDED_BY(mMutex) = 0;
std::vector<nsecs_t> mTimestamps GUARDED_BY(mMutex);
- unsigned mDivisor GUARDED_BY(mMutex) = 1;
+ std::optional<Fps> mRenderRate GUARDED_BY(mMutex);
mutable std::optional<VsyncSequence> mLastVsyncSequence GUARDED_BY(mMutex);
};
diff --git a/services/surfaceflinger/Scheduler/VSyncTracker.h b/services/surfaceflinger/Scheduler/VSyncTracker.h
index 8d1629f..bc0e3bc 100644
--- a/services/surfaceflinger/Scheduler/VSyncTracker.h
+++ b/services/surfaceflinger/Scheduler/VSyncTracker.h
@@ -80,15 +80,16 @@
virtual bool isVSyncInPhase(nsecs_t timePoint, Fps frameRate) const = 0;
/*
- * Sets a divisor on the rate (which is a multiplier of the period).
+ * Sets a render rate on the tracker. If the render rate is not a divisor
+ * of the period, the render rate is ignored until the period changes.
* The tracker will continue to track the vsync timeline and expect it
* to match the current period, however, nextAnticipatedVSyncTimeFrom will
- * return vsyncs according to the divisor set. Setting a divisor is useful
+ * return vsyncs according to the render rate set. Setting a render rate is useful
* when a display is running at 120Hz but the render frame rate is 60Hz.
*
- * \param [in] divisor The rate divisor the tracker should operate at.
+ * \param [in] Fps The render rate the tracker should operate at.
*/
- virtual void setDivisor(unsigned divisor) = 0;
+ virtual void setRenderRate(Fps) = 0;
virtual void dump(std::string& result) const = 0;