Loading services/surfaceflinger/Scheduler/VSyncPredictor.cpp +15 −2 Original line number Original line Diff line number Diff line Loading @@ -77,7 +77,14 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) { std::lock_guard<std::mutex> lk(mMutex); std::lock_guard<std::mutex> lk(mMutex); if (!validate(timestamp)) { 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; return false; } } Loading Loading @@ -236,7 +243,13 @@ void VSyncPredictor::setPeriod(nsecs_t period) { void VSyncPredictor::clearTimestamps() { void VSyncPredictor::clearTimestamps() { if (!mTimestamps.empty()) { 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(); mTimestamps.clear(); mLastTimestampIndex = 0; mLastTimestampIndex = 0; } } Loading services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp +32 −0 Original line number Original line Diff line number Diff line Loading @@ -124,6 +124,38 @@ TEST_F(VSyncPredictorTest, uponNotifiedOfInaccuracyUsesSynthetic) { EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + changedPeriod)); 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) { TEST_F(VSyncPredictorTest, adaptsToFenceTimelines_60hzHighVariance) { // these are precomputed simulated 16.6s vsyncs with uniform distribution +/- 1.6ms error // these are precomputed simulated 16.6s vsyncs with uniform distribution +/- 1.6ms error std::vector<nsecs_t> const simulatedVsyncs{ std::vector<nsecs_t> const simulatedVsyncs{ Loading Loading
services/surfaceflinger/Scheduler/VSyncPredictor.cpp +15 −2 Original line number Original line Diff line number Diff line Loading @@ -77,7 +77,14 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) { std::lock_guard<std::mutex> lk(mMutex); std::lock_guard<std::mutex> lk(mMutex); if (!validate(timestamp)) { 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; return false; } } Loading Loading @@ -236,7 +243,13 @@ void VSyncPredictor::setPeriod(nsecs_t period) { void VSyncPredictor::clearTimestamps() { void VSyncPredictor::clearTimestamps() { if (!mTimestamps.empty()) { 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(); mTimestamps.clear(); mLastTimestampIndex = 0; mLastTimestampIndex = 0; } } Loading
services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp +32 −0 Original line number Original line Diff line number Diff line Loading @@ -124,6 +124,38 @@ TEST_F(VSyncPredictorTest, uponNotifiedOfInaccuracyUsesSynthetic) { EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + changedPeriod)); 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) { TEST_F(VSyncPredictorTest, adaptsToFenceTimelines_60hzHighVariance) { // these are precomputed simulated 16.6s vsyncs with uniform distribution +/- 1.6ms error // these are precomputed simulated 16.6s vsyncs with uniform distribution +/- 1.6ms error std::vector<nsecs_t> const simulatedVsyncs{ std::vector<nsecs_t> const simulatedVsyncs{ Loading