SF: add render frame rate to the scheduler
Schedule SF at the rate of the render frame rate instead of
the display refresh rate.
Test: SF unit tests
Bug: 257072060
Change-Id: Idaf9be5f25373d38c0ef6440f9f401dc90de7a91
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index 0ad4236..ed4d25e 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -253,7 +253,13 @@
nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const {
std::lock_guard lock(mMutex);
- return nextAnticipatedVSyncTimeFromLocked(timePoint);
+
+ // TODO(b/246164114): This implementation is not efficient at all. Refactor.
+ nsecs_t nextVsync = nextAnticipatedVSyncTimeFromLocked(timePoint);
+ while (!isVSyncInPhaseLocked(nextVsync, mDivisor)) {
+ nextVsync = nextAnticipatedVSyncTimeFromLocked(nextVsync + 1);
+ }
+ return nextVsync;
}
/*
@@ -265,6 +271,13 @@
* isVSyncInPhase(50.0, 30) = true
*/
bool VSyncPredictor::isVSyncInPhase(nsecs_t timePoint, Fps frameRate) const {
+ std::lock_guard lock(mMutex);
+ const auto divisor =
+ RefreshRateSelector::getFrameRateDivisor(Fps::fromPeriodNsecs(mIdealPeriod), frameRate);
+ return isVSyncInPhaseLocked(timePoint, static_cast<unsigned>(divisor));
+}
+
+bool VSyncPredictor::isVSyncInPhaseLocked(nsecs_t timePoint, unsigned divisor) const {
struct VsyncError {
nsecs_t vsyncTimestamp;
float error;
@@ -272,9 +285,6 @@
bool operator<(const VsyncError& other) const { return error < other.error; }
};
- std::lock_guard lock(mMutex);
- const auto divisor =
- RefreshRateSelector::getFrameRateDivisor(Fps::fromPeriodNsecs(mIdealPeriod), frameRate);
if (divisor <= 1 || timePoint == 0) {
return true;
}
@@ -312,6 +322,12 @@
return std::abs(minVsyncError->vsyncTimestamp - timePoint) < period / 2;
}
+void VSyncPredictor::setDivisor(unsigned divisor) {
+ ALOGV("%s: %d", __func__, divisor);
+ std::lock_guard lock(mMutex);
+ mDivisor = divisor;
+}
+
VSyncPredictor::Model VSyncPredictor::getVSyncPredictionModel() const {
std::lock_guard lock(mMutex);
const auto model = VSyncPredictor::getVSyncPredictionModelLocked();