Snap for 6643974 from cd6b92d7c8e577a6684964011019860cd2ef7934 to mainline-release
Change-Id: Iab3d9aac63edd4f2599371f667bd31e473034224
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index a3cb772..ab5773d 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -77,7 +77,14 @@
std::lock_guard<std::mutex> lk(mMutex);
if (!validate(timestamp)) {
- ALOGV("timestamp was too far off the last known timestamp");
+ // VSR could elect to ignore the incongruent timestamp or resetModel(). If ts is ignored,
+ // don't insert this ts into mTimestamps ringbuffer.
+ if (!mTimestamps.empty()) {
+ mKnownTimestamp =
+ std::max(timestamp, *std::max_element(mTimestamps.begin(), mTimestamps.end()));
+ } else {
+ mKnownTimestamp = timestamp;
+ }
return false;
}
@@ -236,7 +243,13 @@
void VSyncPredictor::clearTimestamps() {
if (!mTimestamps.empty()) {
- mKnownTimestamp = *std::max_element(mTimestamps.begin(), mTimestamps.end());
+ auto const maxRb = *std::max_element(mTimestamps.begin(), mTimestamps.end());
+ if (mKnownTimestamp) {
+ mKnownTimestamp = std::max(*mKnownTimestamp, maxRb);
+ } else {
+ mKnownTimestamp = maxRb;
+ }
+
mTimestamps.clear();
mLastTimestampIndex = 0;
}
diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
index bf2a889..fc39235 100644
--- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
@@ -124,6 +124,38 @@
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + changedPeriod));
}
+// b/159882858
+TEST_F(VSyncPredictorTest, updatesTimebaseForSyntheticAfterIdleTime) {
+ for (auto i = 0u; i < kMinimumSamplesForPrediction; i++) {
+ EXPECT_TRUE(tracker.addVsyncTimestamp(mNow += mPeriod));
+ }
+
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + mPeriod));
+
+ auto const halfPeriod = mPeriod >> 2;
+ nsecs_t relativelyLongGapWithDrift = mPeriod * 100 + halfPeriod;
+
+ EXPECT_FALSE(tracker.addVsyncTimestamp(mNow += relativelyLongGapWithDrift));
+
+ tracker.resetModel();
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + mPeriod));
+}
+
+TEST_F(VSyncPredictorTest, uponBadVsyncWillSwitchToSyntheticWhileRecalibrating) {
+ auto const slightlyMorePeriod = mPeriod + 10;
+ for (auto i = 0u; i < kMinimumSamplesForPrediction; i++) {
+ EXPECT_TRUE(tracker.addVsyncTimestamp(mNow += slightlyMorePeriod));
+ }
+
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + slightlyMorePeriod));
+
+ auto const halfPeriod = mPeriod >> 2;
+ EXPECT_FALSE(tracker.addVsyncTimestamp(mNow += halfPeriod));
+
+ tracker.resetModel();
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + mPeriod));
+}
+
TEST_F(VSyncPredictorTest, adaptsToFenceTimelines_60hzHighVariance) {
// these are precomputed simulated 16.6s vsyncs with uniform distribution +/- 1.6ms error
std::vector<nsecs_t> const simulatedVsyncs{