Merge "SF: VSyncReactor ensure period change confirmation"
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index a652053..158a184 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -175,10 +175,25 @@
return mTracker->nextAnticipatedVSyncTimeFrom(mClock->now());
}
+void VSyncReactor::startPeriodTransition(nsecs_t newPeriod) {
+ mPeriodTransitioningTo = newPeriod;
+ mMoreSamplesNeeded = true;
+}
+
+void VSyncReactor::endPeriodTransition() {
+ mPeriodTransitioningTo.reset();
+ mLastHwVsync.reset();
+ mMoreSamplesNeeded = false;
+}
+
void VSyncReactor::setPeriod(nsecs_t period) {
std::lock_guard lk(mMutex);
mLastHwVsync.reset();
- mPeriodTransitioningTo = period;
+ if (period == getPeriod()) {
+ endPeriodTransition();
+ } else {
+ startPeriodTransition(period);
+ }
}
nsecs_t VSyncReactor::getPeriod() {
@@ -202,16 +217,13 @@
std::lock_guard<std::mutex> lk(mMutex);
if (periodChangeDetected(timestamp)) {
- mMoreSamplesNeeded = false;
- *periodFlushed = true;
-
mTracker->setPeriod(*mPeriodTransitioningTo);
for (auto& entry : mCallbacks) {
entry.second->setPeriod(*mPeriodTransitioningTo);
}
- mPeriodTransitioningTo.reset();
- mLastHwVsync.reset();
+ endPeriodTransition();
+ *periodFlushed = true;
} else if (mPeriodTransitioningTo) {
mLastHwVsync = timestamp;
mMoreSamplesNeeded = true;
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.h b/services/surfaceflinger/Scheduler/VSyncReactor.h
index 73a5e37..f318dcb 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.h
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.h
@@ -61,6 +61,8 @@
void reset() final;
private:
+ void startPeriodTransition(nsecs_t newPeriod) REQUIRES(mMutex);
+ void endPeriodTransition() REQUIRES(mMutex);
bool periodChangeDetected(nsecs_t vsync_timestamp) REQUIRES(mMutex);
std::unique_ptr<Clock> const mClock;
diff --git a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
index 72f8bb9..4df20af 100644
--- a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
@@ -292,6 +292,46 @@
EXPECT_TRUE(periodFlushed);
}
+TEST_F(VSyncReactorTest, changingPeriodBackAbortsConfirmationProcess) {
+ nsecs_t sampleTime = 0;
+ nsecs_t const newPeriod = 5000;
+ mReactor.setPeriod(newPeriod);
+ bool periodFlushed = true;
+ EXPECT_TRUE(mReactor.addResyncSample(sampleTime += period, &periodFlushed));
+ EXPECT_FALSE(periodFlushed);
+
+ EXPECT_TRUE(mReactor.addResyncSample(sampleTime += period, &periodFlushed));
+ EXPECT_FALSE(periodFlushed);
+
+ mReactor.setPeriod(period);
+ EXPECT_FALSE(mReactor.addResyncSample(sampleTime += period, &periodFlushed));
+ EXPECT_FALSE(periodFlushed);
+}
+
+TEST_F(VSyncReactorTest, changingToAThirdPeriodWillWaitForLastPeriod) {
+ nsecs_t sampleTime = 0;
+ nsecs_t const secondPeriod = 5000;
+ nsecs_t const thirdPeriod = 2000;
+
+ mReactor.setPeriod(secondPeriod);
+ bool periodFlushed = true;
+ EXPECT_TRUE(mReactor.addResyncSample(sampleTime += period, &periodFlushed));
+ EXPECT_FALSE(periodFlushed);
+ EXPECT_TRUE(mReactor.addResyncSample(sampleTime += period, &periodFlushed));
+ EXPECT_FALSE(periodFlushed);
+ mReactor.setPeriod(thirdPeriod);
+ EXPECT_TRUE(mReactor.addResyncSample(sampleTime += secondPeriod, &periodFlushed));
+ EXPECT_FALSE(periodFlushed);
+ EXPECT_FALSE(mReactor.addResyncSample(sampleTime += thirdPeriod, &periodFlushed));
+ EXPECT_TRUE(periodFlushed);
+}
+
+TEST_F(VSyncReactorTest, presentFenceAdditionDoesNotInterruptConfirmationProcess) {
+ nsecs_t const newPeriod = 5000;
+ mReactor.setPeriod(newPeriod);
+ EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
+}
+
TEST_F(VSyncReactorTest, setPeriodCalledFirstTwoEventsNewPeriod) {
nsecs_t const newPeriod = 5000;
EXPECT_CALL(*mMockTracker, setPeriod(_)).Times(0);