SF: kernel idle timer is not applicable for VRR
Bug: 356061399
Change-Id: I784de91ae8bd4202e2e3dfe4bdb3d21e6779abd4
Test: Sysui perf test from bug
Flag: EXEMPT bugfix
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index 04491a2..4a7cff5 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -89,7 +89,9 @@
}
bool VSyncPredictor::validate(nsecs_t timestamp) const {
+ SFTRACE_CALL();
if (mLastTimestampIndex < 0 || mTimestamps.empty()) {
+ SFTRACE_INSTANT("timestamp valid (first)");
return true;
}
@@ -98,7 +100,11 @@
(timestamp - aValidTimestamp) % idealPeriod() * kMaxPercent / idealPeriod();
if (percent >= kOutlierTolerancePercent &&
percent <= (kMaxPercent - kOutlierTolerancePercent)) {
- SFTRACE_FORMAT_INSTANT("timestamp is not aligned with model");
+ SFTRACE_FORMAT_INSTANT("timestamp not aligned with model. aValidTimestamp %.2fms ago"
+ ", timestamp %.2fms ago, idealPeriod=%.2 percent=%d",
+ (mClock->now() - aValidTimestamp) / 1e6f,
+ (mClock->now() - timestamp) / 1e6f,
+ idealPeriod() / 1e6f, percent);
return false;
}
@@ -148,7 +154,10 @@
// Add the timestamp to mTimestamps before clearing it so we could
// update mKnownTimestamp based on the new timestamp.
mTimestamps.push_back(timestamp);
- clearTimestamps();
+
+ // Do not clear timelines as we don't want to break the phase while
+ // we are still learning.
+ clearTimestamps(/* clearTimelines */ false);
} else if (!mTimestamps.empty()) {
mKnownTimestamp =
std::max(timestamp, *std::max_element(mTimestamps.begin(), mTimestamps.end()));
@@ -235,7 +244,7 @@
if (CC_UNLIKELY(bottom == 0)) {
it->second = {idealPeriod(), 0};
- clearTimestamps();
+ clearTimestamps(/* clearTimelines */ true);
return false;
}
@@ -245,7 +254,7 @@
auto const percent = std::abs(anticipatedPeriod - idealPeriod()) * kMaxPercent / idealPeriod();
if (percent >= kOutlierTolerancePercent) {
it->second = {idealPeriod(), 0};
- clearTimestamps();
+ clearTimestamps(/* clearTimelines */ true);
return false;
}
@@ -425,6 +434,9 @@
timeout ? std::to_string(timeout->timeoutNs).c_str() : "N/A");
std::lock_guard lock(mMutex);
+ // do not clear the timelines on VRR displays if we didn't change the mode
+ const bool isVrr = modePtr->getVrrConfig().has_value();
+ const bool clearTimelines = !isVrr || mDisplayModePtr->getId() != modePtr->getId();
mDisplayModePtr = modePtr;
mNumVsyncsForFrame = numVsyncsPerFrame(mDisplayModePtr);
traceInt64("VSP-setPeriod", modePtr->getVsyncRate().getPeriodNsecs());
@@ -438,8 +450,10 @@
mRateMap[idealPeriod()] = {idealPeriod(), 0};
}
- mTimelines.clear();
- clearTimestamps();
+ if (clearTimelines) {
+ mTimelines.clear();
+ }
+ clearTimestamps(clearTimelines);
}
Duration VSyncPredictor::ensureMinFrameDurationIsKept(TimePoint expectedPresentTime,
@@ -556,15 +570,19 @@
return mRateMap.find(idealPeriod())->second;
}
-void VSyncPredictor::clearTimestamps() {
- SFTRACE_CALL();
+void VSyncPredictor::clearTimestamps(bool clearTimelines) {
+ SFTRACE_FORMAT("%s: clearTimelines=%d", __func__, clearTimelines);
if (!mTimestamps.empty()) {
auto const maxRb = *std::max_element(mTimestamps.begin(), mTimestamps.end());
if (mKnownTimestamp) {
mKnownTimestamp = std::max(*mKnownTimestamp, maxRb);
+ SFTRACE_FORMAT_INSTANT("mKnownTimestamp was %.2fms ago",
+ (mClock->now() - *mKnownTimestamp) / 1e6f);
} else {
mKnownTimestamp = maxRb;
+ SFTRACE_FORMAT_INSTANT("mKnownTimestamp (maxRb) was %.2fms ago",
+ (mClock->now() - *mKnownTimestamp) / 1e6f);
}
mTimestamps.clear();
@@ -575,7 +593,7 @@
if (mTimelines.empty()) {
mLastCommittedVsync = TimePoint::fromNs(0);
mTimelines.emplace_back(mLastCommittedVsync, mIdealPeriod, mRenderRateOpt);
- } else {
+ } else if (clearTimelines) {
while (mTimelines.size() > 1) {
mTimelines.pop_front();
}
@@ -596,9 +614,10 @@
}
void VSyncPredictor::resetModel() {
+ SFTRACE_CALL();
std::lock_guard lock(mMutex);
mRateMap[idealPeriod()] = {idealPeriod(), 0};
- clearTimestamps();
+ clearTimestamps(/* clearTimelines */ true);
}
void VSyncPredictor::dump(std::string& result) const {