diff options
Diffstat (limited to 'services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp')
-rw-r--r-- | services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp | 492 |
1 files changed, 125 insertions, 367 deletions
diff --git a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp index a97256203d..5826a9b6cf 100644 --- a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp @@ -14,6 +14,10 @@ * limitations under the License. */ +// TODO(b/129481165): remove the #pragma below and fix conversion issues +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wextra" + #undef LOG_TAG #define LOG_TAG "LibSurfaceFlingerUnittests" #define LOG_NDEBUG 0 @@ -41,28 +45,11 @@ public: MOCK_CONST_METHOD0(currentPeriod, nsecs_t()); MOCK_METHOD1(setPeriod, void(nsecs_t)); MOCK_METHOD0(resetModel, void()); + MOCK_CONST_METHOD0(needsMoreSamples, bool()); + MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps)); MOCK_CONST_METHOD1(dump, void(std::string&)); }; -class VSyncTrackerWrapper : public VSyncTracker { -public: - VSyncTrackerWrapper(std::shared_ptr<VSyncTracker> const& tracker) : mTracker(tracker) {} - - bool addVsyncTimestamp(nsecs_t timestamp) final { - return mTracker->addVsyncTimestamp(timestamp); - } - nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const final { - return mTracker->nextAnticipatedVSyncTimeFrom(timePoint); - } - nsecs_t currentPeriod() const final { return mTracker->currentPeriod(); } - void setPeriod(nsecs_t period) final { mTracker->setPeriod(period); } - void resetModel() final { mTracker->resetModel(); } - void dump(std::string& result) const final { mTracker->dump(result); } - -private: - std::shared_ptr<VSyncTracker> const mTracker; -}; - class MockClock : public Clock { public: MOCK_CONST_METHOD0(now, nsecs_t()); @@ -81,89 +68,46 @@ private: class MockVSyncDispatch : public VSyncDispatch { public: MOCK_METHOD2(registerCallback, - CallbackToken(std::function<void(nsecs_t, nsecs_t)> const&, std::string)); + CallbackToken(std::function<void(nsecs_t, nsecs_t, nsecs_t)> const&, std::string)); MOCK_METHOD1(unregisterCallback, void(CallbackToken)); - MOCK_METHOD3(schedule, ScheduleResult(CallbackToken, nsecs_t, nsecs_t)); + MOCK_METHOD2(schedule, ScheduleResult(CallbackToken, ScheduleTiming)); MOCK_METHOD1(cancel, CancelResult(CallbackToken token)); MOCK_CONST_METHOD1(dump, void(std::string&)); }; -class VSyncDispatchWrapper : public VSyncDispatch { -public: - VSyncDispatchWrapper(std::shared_ptr<VSyncDispatch> const& dispatch) : mDispatch(dispatch) {} - CallbackToken registerCallback(std::function<void(nsecs_t, nsecs_t)> const& callbackFn, - std::string callbackName) final { - return mDispatch->registerCallback(callbackFn, callbackName); - } - - void unregisterCallback(CallbackToken token) final { mDispatch->unregisterCallback(token); } - - ScheduleResult schedule(CallbackToken token, nsecs_t workDuration, - nsecs_t earliestVsync) final { - return mDispatch->schedule(token, workDuration, earliestVsync); - } - - CancelResult cancel(CallbackToken token) final { return mDispatch->cancel(token); } - - void dump(std::string& result) const final { return mDispatch->dump(result); } - -private: - std::shared_ptr<VSyncDispatch> const mDispatch; -}; - -std::shared_ptr<FenceTime> generateInvalidFence() { +std::shared_ptr<android::FenceTime> generateInvalidFence() { sp<Fence> fence = new Fence(); - return std::make_shared<FenceTime>(fence); + return std::make_shared<android::FenceTime>(fence); } -std::shared_ptr<FenceTime> generatePendingFence() { +std::shared_ptr<android::FenceTime> generatePendingFence() { sp<Fence> fence = new Fence(dup(fileno(tmpfile()))); - return std::make_shared<FenceTime>(fence); + return std::make_shared<android::FenceTime>(fence); } -void signalFenceWithTime(std::shared_ptr<FenceTime> const& fence, nsecs_t time) { - FenceTime::Snapshot snap(time); +void signalFenceWithTime(std::shared_ptr<android::FenceTime> const& fence, nsecs_t time) { + android::FenceTime::Snapshot snap(time); fence->applyTrustedSnapshot(snap); } -std::shared_ptr<FenceTime> generateSignalledFenceWithTime(nsecs_t time) { +std::shared_ptr<android::FenceTime> generateSignalledFenceWithTime(nsecs_t time) { sp<Fence> fence = new Fence(dup(fileno(tmpfile()))); - std::shared_ptr<FenceTime> ft = std::make_shared<FenceTime>(fence); + std::shared_ptr<android::FenceTime> ft = std::make_shared<android::FenceTime>(fence); signalFenceWithTime(ft, time); return ft; } -class StubCallback : public DispSync::Callback { -public: - void onDispSyncEvent(nsecs_t when, nsecs_t /*expectedVSyncTimestamp*/) final { - std::lock_guard<std::mutex> lk(mMutex); - mLastCallTime = when; - } - std::optional<nsecs_t> lastCallTime() const { - std::lock_guard<std::mutex> lk(mMutex); - return mLastCallTime; - } - -private: - std::mutex mutable mMutex; - std::optional<nsecs_t> mLastCallTime GUARDED_BY(mMutex); -}; - class VSyncReactorTest : public testing::Test { protected: VSyncReactorTest() - : mMockDispatch(std::make_shared<NiceMock<MockVSyncDispatch>>()), - mMockTracker(std::make_shared<NiceMock<MockVSyncTracker>>()), + : mMockTracker(std::make_shared<NiceMock<MockVSyncTracker>>()), mMockClock(std::make_shared<NiceMock<MockClock>>()), - mReactor(std::make_unique<ClockWrapper>(mMockClock), - std::make_unique<VSyncDispatchWrapper>(mMockDispatch), - std::make_unique<VSyncTrackerWrapper>(mMockTracker), kPendingLimit, + mReactor(std::make_unique<ClockWrapper>(mMockClock), *mMockTracker, kPendingLimit, false /* supportKernelIdleTimer */) { ON_CALL(*mMockClock, now()).WillByDefault(Return(mFakeNow)); ON_CALL(*mMockTracker, currentPeriod()).WillByDefault(Return(period)); } - std::shared_ptr<MockVSyncDispatch> mMockDispatch; std::shared_ptr<MockVSyncTracker> mMockTracker; std::shared_ptr<MockClock> mMockClock; static constexpr size_t kPendingLimit = 3; @@ -178,7 +122,7 @@ protected: VSyncDispatch::CallbackToken const mFakeToken{2398}; nsecs_t lastCallbackTime = 0; - StubCallback outerCb; + // StubCallback outerCb; std::function<void(nsecs_t, nsecs_t)> innerCb; VSyncReactor mReactor; @@ -213,7 +157,7 @@ TEST_F(VSyncReactorTest, addingPendingFenceAddsSignalled) { } TEST_F(VSyncReactorTest, limitsPendingFences) { - std::array<std::shared_ptr<FenceTime>, kPendingLimit * 2> fences; + std::array<std::shared_ptr<android::FenceTime>, kPendingLimit * 2> fences; std::array<nsecs_t, fences.size()> fakeTimes; std::generate(fences.begin(), fences.end(), [] { return generatePendingFence(); }); std::generate(fakeTimes.begin(), fakeTimes.end(), [i = 10]() mutable { @@ -254,86 +198,48 @@ TEST_F(VSyncReactorTest, ignoresProperlyAfterAPeriodConfirmation) { mReactor.setIgnorePresentFences(true); nsecs_t const newPeriod = 5000; - mReactor.setPeriod(newPeriod); + mReactor.startPeriodTransition(newPeriod); - EXPECT_TRUE(mReactor.addResyncSample(0, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(0, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); - EXPECT_FALSE(mReactor.addResyncSample(newPeriod, std::nullopt, &periodFlushed)); + EXPECT_FALSE(mReactor.addHwVsyncTimestamp(newPeriod, std::nullopt, &periodFlushed)); EXPECT_TRUE(periodFlushed); EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0))); } -TEST_F(VSyncReactorTest, queriesTrackerForNextRefreshNow) { - nsecs_t const fakeTimestamp = 4839; - EXPECT_CALL(*mMockTracker, currentPeriod()).Times(0); - EXPECT_CALL(*mMockTracker, nextAnticipatedVSyncTimeFrom(_)) - .Times(1) - .WillOnce(Return(fakeTimestamp)); - - EXPECT_THAT(mReactor.computeNextRefresh(0, mMockClock->now()), Eq(fakeTimestamp)); -} - -TEST_F(VSyncReactorTest, queriesTrackerForExpectedPresentTime) { - nsecs_t const fakeTimestamp = 4839; - EXPECT_CALL(*mMockTracker, currentPeriod()).Times(0); - EXPECT_CALL(*mMockTracker, nextAnticipatedVSyncTimeFrom(_)) - .Times(1) - .WillOnce(Return(fakeTimestamp)); - - EXPECT_THAT(mReactor.expectedPresentTime(mMockClock->now()), Eq(fakeTimestamp)); -} - -TEST_F(VSyncReactorTest, queriesTrackerForNextRefreshFuture) { - nsecs_t const fakeTimestamp = 4839; - nsecs_t const fakePeriod = 1010; - nsecs_t const mFakeNow = 2214; - int const numPeriodsOut = 3; - EXPECT_CALL(*mMockClock, now()).WillOnce(Return(mFakeNow)); - EXPECT_CALL(*mMockTracker, currentPeriod()).WillOnce(Return(fakePeriod)); - EXPECT_CALL(*mMockTracker, nextAnticipatedVSyncTimeFrom(mFakeNow + numPeriodsOut * fakePeriod)) - .WillOnce(Return(fakeTimestamp)); - EXPECT_THAT(mReactor.computeNextRefresh(numPeriodsOut, mMockClock->now()), Eq(fakeTimestamp)); -} - -TEST_F(VSyncReactorTest, getPeriod) { - nsecs_t const fakePeriod = 1010; - EXPECT_CALL(*mMockTracker, currentPeriod()).WillOnce(Return(fakePeriod)); - EXPECT_THAT(mReactor.getPeriod(), Eq(fakePeriod)); -} - TEST_F(VSyncReactorTest, setPeriodCalledOnceConfirmedChange) { nsecs_t const newPeriod = 5000; EXPECT_CALL(*mMockTracker, setPeriod(_)).Times(0); - mReactor.setPeriod(newPeriod); + mReactor.startPeriodTransition(newPeriod); bool periodFlushed = true; - EXPECT_TRUE(mReactor.addResyncSample(10000, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(10000, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); - EXPECT_TRUE(mReactor.addResyncSample(20000, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(20000, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); Mock::VerifyAndClearExpectations(mMockTracker.get()); EXPECT_CALL(*mMockTracker, setPeriod(newPeriod)).Times(1); - EXPECT_FALSE(mReactor.addResyncSample(25000, std::nullopt, &periodFlushed)); + EXPECT_FALSE(mReactor.addHwVsyncTimestamp(25000, std::nullopt, &periodFlushed)); EXPECT_TRUE(periodFlushed); } TEST_F(VSyncReactorTest, changingPeriodBackAbortsConfirmationProcess) { nsecs_t sampleTime = 0; nsecs_t const newPeriod = 5000; - mReactor.setPeriod(newPeriod); + mReactor.startPeriodTransition(newPeriod); bool periodFlushed = true; - EXPECT_TRUE(mReactor.addResyncSample(sampleTime += period, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); - EXPECT_TRUE(mReactor.addResyncSample(sampleTime += period, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); - mReactor.setPeriod(period); - EXPECT_FALSE(mReactor.addResyncSample(sampleTime += period, std::nullopt, &periodFlushed)); + mReactor.startPeriodTransition(period); + EXPECT_FALSE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); } @@ -342,16 +248,18 @@ TEST_F(VSyncReactorTest, changingToAThirdPeriodWillWaitForLastPeriod) { nsecs_t const secondPeriod = 5000; nsecs_t const thirdPeriod = 2000; - mReactor.setPeriod(secondPeriod); + mReactor.startPeriodTransition(secondPeriod); bool periodFlushed = true; - EXPECT_TRUE(mReactor.addResyncSample(sampleTime += period, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); - EXPECT_TRUE(mReactor.addResyncSample(sampleTime += period, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); - mReactor.setPeriod(thirdPeriod); - EXPECT_TRUE(mReactor.addResyncSample(sampleTime += secondPeriod, std::nullopt, &periodFlushed)); + mReactor.startPeriodTransition(thirdPeriod); + EXPECT_TRUE( + mReactor.addHwVsyncTimestamp(sampleTime += secondPeriod, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); - EXPECT_FALSE(mReactor.addResyncSample(sampleTime += thirdPeriod, std::nullopt, &periodFlushed)); + EXPECT_FALSE( + mReactor.addHwVsyncTimestamp(sampleTime += thirdPeriod, std::nullopt, &periodFlushed)); EXPECT_TRUE(periodFlushed); } @@ -366,9 +274,10 @@ TEST_F(VSyncReactorTest, reportedBadTimestampFromPredictorWillReactivateHwVSync) nsecs_t skewyPeriod = period >> 1; bool periodFlushed = false; nsecs_t sampleTime = 0; - EXPECT_TRUE(mReactor.addResyncSample(sampleTime += skewyPeriod, std::nullopt, &periodFlushed)); + EXPECT_TRUE( + mReactor.addHwVsyncTimestamp(sampleTime += skewyPeriod, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); - EXPECT_FALSE(mReactor.addResyncSample(sampleTime += period, std::nullopt, &periodFlushed)); + EXPECT_FALSE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); } @@ -386,22 +295,22 @@ TEST_F(VSyncReactorTest, reportedBadTimestampFromPredictorWillReactivateHwVSyncP TEST_F(VSyncReactorTest, presentFenceAdditionDoesNotInterruptConfirmationProcess) { nsecs_t const newPeriod = 5000; - mReactor.setPeriod(newPeriod); + mReactor.startPeriodTransition(newPeriod); EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0))); } TEST_F(VSyncReactorTest, setPeriodCalledFirstTwoEventsNewPeriod) { nsecs_t const newPeriod = 5000; EXPECT_CALL(*mMockTracker, setPeriod(_)).Times(0); - mReactor.setPeriod(newPeriod); + mReactor.startPeriodTransition(newPeriod); bool periodFlushed = true; - EXPECT_TRUE(mReactor.addResyncSample(5000, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(5000, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); Mock::VerifyAndClearExpectations(mMockTracker.get()); EXPECT_CALL(*mMockTracker, setPeriod(newPeriod)).Times(1); - EXPECT_FALSE(mReactor.addResyncSample(10000, std::nullopt, &periodFlushed)); + EXPECT_FALSE(mReactor.addHwVsyncTimestamp(10000, std::nullopt, &periodFlushed)); EXPECT_TRUE(periodFlushed); } @@ -410,7 +319,7 @@ TEST_F(VSyncReactorTest, addResyncSampleTypical) { bool periodFlushed = false; EXPECT_CALL(*mMockTracker, addVsyncTimestamp(fakeTimestamp)); - EXPECT_FALSE(mReactor.addResyncSample(fakeTimestamp, std::nullopt, &periodFlushed)); + EXPECT_FALSE(mReactor.addHwVsyncTimestamp(fakeTimestamp, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); } @@ -418,23 +327,23 @@ TEST_F(VSyncReactorTest, addResyncSamplePeriodChanges) { bool periodFlushed = false; nsecs_t const newPeriod = 4000; - mReactor.setPeriod(newPeriod); + mReactor.startPeriodTransition(newPeriod); auto time = 0; auto constexpr numTimestampSubmissions = 10; for (auto i = 0; i < numTimestampSubmissions; i++) { time += period; - EXPECT_TRUE(mReactor.addResyncSample(time, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); } time += newPeriod; - EXPECT_FALSE(mReactor.addResyncSample(time, std::nullopt, &periodFlushed)); + EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed)); EXPECT_TRUE(periodFlushed); for (auto i = 0; i < numTimestampSubmissions; i++) { time += newPeriod; - EXPECT_FALSE(mReactor.addResyncSample(time, std::nullopt, &periodFlushed)); + EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed)); EXPECT_FALSE(periodFlushed); } } @@ -443,222 +352,108 @@ TEST_F(VSyncReactorTest, addPresentFenceWhileAwaitingPeriodConfirmationRequestsH auto time = 0; bool periodFlushed = false; nsecs_t const newPeriod = 4000; - mReactor.setPeriod(newPeriod); + mReactor.startPeriodTransition(newPeriod); time += period; - mReactor.addResyncSample(time, std::nullopt, &periodFlushed); + mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed); EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0))); time += newPeriod; - mReactor.addResyncSample(time, std::nullopt, &periodFlushed); + mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed); EXPECT_FALSE(mReactor.addPresentFence(generateSignalledFenceWithTime(0))); } -static nsecs_t computeWorkload(nsecs_t period, nsecs_t phase) { - return period - phase; -} - -TEST_F(VSyncReactorTest, addEventListener) { - Sequence seq; - EXPECT_CALL(*mMockDispatch, registerCallback(_, std::string(mName))) - .InSequence(seq) - .WillOnce(Return(mFakeToken)); - EXPECT_CALL(*mMockDispatch, schedule(mFakeToken, computeWorkload(period, mPhase), mFakeNow)) - .InSequence(seq); - EXPECT_CALL(*mMockDispatch, cancel(mFakeToken)).Times(2).InSequence(seq); - EXPECT_CALL(*mMockDispatch, unregisterCallback(mFakeToken)).InSequence(seq); - - mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); - mReactor.removeEventListener(&outerCb, &lastCallbackTime); -} - -TEST_F(VSyncReactorTest, addEventListenerTwiceChangesPhase) { - Sequence seq; - EXPECT_CALL(*mMockDispatch, registerCallback(_, std::string(mName))) - .InSequence(seq) - .WillOnce(Return(mFakeToken)); - EXPECT_CALL(*mMockDispatch, schedule(mFakeToken, computeWorkload(period, mPhase), mFakeNow)) - .InSequence(seq); - EXPECT_CALL(*mMockDispatch, - schedule(mFakeToken, computeWorkload(period, mAnotherPhase), _)) // mFakeNow)) - .InSequence(seq); - EXPECT_CALL(*mMockDispatch, cancel(mFakeToken)).InSequence(seq); - EXPECT_CALL(*mMockDispatch, unregisterCallback(mFakeToken)).InSequence(seq); - - mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); - mReactor.addEventListener(mName, mAnotherPhase, &outerCb, lastCallbackTime); -} +TEST_F(VSyncReactorTest, hwVsyncIsRequestedForTracker) { + auto time = 0; + bool periodFlushed = false; + nsecs_t const newPeriod = 4000; + mReactor.startPeriodTransition(newPeriod); -TEST_F(VSyncReactorTest, eventListenerGetsACallbackAndReschedules) { + static auto constexpr numSamplesWithNewPeriod = 4; Sequence seq; - EXPECT_CALL(*mMockDispatch, registerCallback(_, std::string(mName))) + EXPECT_CALL(*mMockTracker, needsMoreSamples()) + .Times(numSamplesWithNewPeriod - 2) .InSequence(seq) - .WillOnce(DoAll(SaveArg<0>(&innerCb), Return(mFakeToken))); - EXPECT_CALL(*mMockDispatch, schedule(mFakeToken, computeWorkload(period, mPhase), mFakeNow)) - .InSequence(seq); - EXPECT_CALL(*mMockDispatch, - schedule(mFakeToken, computeWorkload(period, mPhase), mFakeVSyncTime)) - .Times(2) - .InSequence(seq); - EXPECT_CALL(*mMockDispatch, cancel(mFakeToken)).InSequence(seq); - EXPECT_CALL(*mMockDispatch, unregisterCallback(mFakeToken)).InSequence(seq); - - mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); - ASSERT_TRUE(innerCb); - innerCb(mFakeVSyncTime, mFakeWakeupTime); - innerCb(mFakeVSyncTime, mFakeWakeupTime); -} - -TEST_F(VSyncReactorTest, callbackTimestampDistributedIsWakeupTime) { - Sequence seq; - EXPECT_CALL(*mMockDispatch, registerCallback(_, _)) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*mMockTracker, needsMoreSamples()) + .Times(1) .InSequence(seq) - .WillOnce(DoAll(SaveArg<0>(&innerCb), Return(mFakeToken))); - EXPECT_CALL(*mMockDispatch, schedule(mFakeToken, computeWorkload(period, mPhase), mFakeNow)) - .InSequence(seq); - EXPECT_CALL(*mMockDispatch, - schedule(mFakeToken, computeWorkload(period, mPhase), mFakeVSyncTime)) - .InSequence(seq); - - mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); - ASSERT_TRUE(innerCb); - innerCb(mFakeVSyncTime, mFakeWakeupTime); - EXPECT_THAT(outerCb.lastCallTime(), Optional(mFakeWakeupTime)); -} + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(numSamplesWithNewPeriod); -TEST_F(VSyncReactorTest, eventListenersRemovedOnDestruction) { - Sequence seq; - EXPECT_CALL(*mMockDispatch, registerCallback(_, std::string(mName))) - .InSequence(seq) - .WillOnce(Return(mFakeToken)); - EXPECT_CALL(*mMockDispatch, schedule(mFakeToken, computeWorkload(period, mPhase), mFakeNow)) - .InSequence(seq); - EXPECT_CALL(*mMockDispatch, cancel(mFakeToken)).InSequence(seq); - EXPECT_CALL(*mMockDispatch, unregisterCallback(mFakeToken)).InSequence(seq); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed)); - mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed)); + // confirmed period, but predictor wants numRequest samples. This one and prior are valid. + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod, std::nullopt, &periodFlushed)); + EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time += newPeriod, std::nullopt, &periodFlushed)); } -// b/149221293 -TEST_F(VSyncReactorTest, selfRemovingEventListenerStopsCallbacks) { - class SelfRemovingCallback : public DispSync::Callback { - public: - SelfRemovingCallback(VSyncReactor& vsr) : mVsr(vsr) {} - void onDispSyncEvent(nsecs_t when, nsecs_t /*expectedVSyncTimestamp*/) final { - mVsr.removeEventListener(this, &when); - } - - private: - VSyncReactor& mVsr; - } selfRemover(mReactor); +TEST_F(VSyncReactorTest, hwVsyncturnsOffOnConfirmationWhenTrackerDoesntRequest) { + auto time = 0; + bool periodFlushed = false; + nsecs_t const newPeriod = 4000; + mReactor.startPeriodTransition(newPeriod); Sequence seq; - EXPECT_CALL(*mMockDispatch, registerCallback(_, std::string(mName))) + EXPECT_CALL(*mMockTracker, needsMoreSamples()) + .Times(1) .InSequence(seq) - .WillOnce(DoAll(SaveArg<0>(&innerCb), Return(mFakeToken))); - EXPECT_CALL(*mMockDispatch, schedule(mFakeToken, computeWorkload(period, mPhase), mFakeNow)) - .InSequence(seq); - EXPECT_CALL(*mMockDispatch, cancel(mFakeToken)).Times(2).InSequence(seq); - EXPECT_CALL(*mMockDispatch, unregisterCallback(mFakeToken)).InSequence(seq); - - mReactor.addEventListener(mName, mPhase, &selfRemover, lastCallbackTime); - innerCb(0, 0); -} + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(2); -TEST_F(VSyncReactorTest, addEventListenerChangePeriod) { - Sequence seq; - EXPECT_CALL(*mMockDispatch, registerCallback(_, std::string(mName))) - .InSequence(seq) - .WillOnce(Return(mFakeToken)); - EXPECT_CALL(*mMockDispatch, schedule(mFakeToken, computeWorkload(period, mPhase), mFakeNow)) - .InSequence(seq); - EXPECT_CALL(*mMockDispatch, - schedule(mFakeToken, computeWorkload(period, mAnotherPhase), mFakeNow)) - .InSequence(seq); - EXPECT_CALL(*mMockDispatch, cancel(mFakeToken)).InSequence(seq); - EXPECT_CALL(*mMockDispatch, unregisterCallback(mFakeToken)).InSequence(seq); - - mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); - mReactor.addEventListener(mName, mAnotherPhase, &outerCb, lastCallbackTime); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed)); + EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time += newPeriod, std::nullopt, &periodFlushed)); } -TEST_F(VSyncReactorTest, changingPeriodChangesOffsetsOnNextCb) { - static constexpr nsecs_t anotherPeriod = 23333; - Sequence seq; - EXPECT_CALL(*mMockDispatch, registerCallback(_, std::string(mName))) - .InSequence(seq) - .WillOnce(Return(mFakeToken)); - EXPECT_CALL(*mMockDispatch, schedule(mFakeToken, computeWorkload(period, mPhase), mFakeNow)) - .InSequence(seq); - EXPECT_CALL(*mMockTracker, setPeriod(anotherPeriod)); - EXPECT_CALL(*mMockDispatch, - schedule(mFakeToken, computeWorkload(anotherPeriod, mPhase), mFakeNow)) - .InSequence(seq); - - mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); - +TEST_F(VSyncReactorTest, hwVsyncIsRequestedForTrackerMultiplePeriodChanges) { + auto time = 0; bool periodFlushed = false; - mReactor.setPeriod(anotherPeriod); - EXPECT_TRUE(mReactor.addResyncSample(anotherPeriod, std::nullopt, &periodFlushed)); - EXPECT_FALSE(mReactor.addResyncSample(anotherPeriod * 2, std::nullopt, &periodFlushed)); + nsecs_t const newPeriod1 = 4000; + nsecs_t const newPeriod2 = 7000; - mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); -} + mReactor.startPeriodTransition(newPeriod1); -TEST_F(VSyncReactorTest, offsetsAppliedOnNextOpportunity) { Sequence seq; - EXPECT_CALL(*mMockDispatch, registerCallback(_, std::string(mName))) - .InSequence(seq) - .WillOnce(DoAll(SaveArg<0>(&innerCb), Return(mFakeToken))); - EXPECT_CALL(*mMockDispatch, schedule(mFakeToken, computeWorkload(period, mPhase), _)) - .InSequence(seq) - .WillOnce(Return(ScheduleResult::Scheduled)); - - EXPECT_CALL(*mMockDispatch, schedule(mFakeToken, computeWorkload(period, mAnotherPhase), _)) + EXPECT_CALL(*mMockTracker, needsMoreSamples()) + .Times(4) .InSequence(seq) - .WillOnce(Return(ScheduleResult::Scheduled)); - - EXPECT_CALL(*mMockDispatch, schedule(mFakeToken, computeWorkload(period, mAnotherPhase), _)) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*mMockTracker, needsMoreSamples()) + .Times(1) .InSequence(seq) - .WillOnce(Return(ScheduleResult::Scheduled)); + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(7); - mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); - mReactor.changePhaseOffset(&outerCb, mAnotherPhase); - ASSERT_TRUE(innerCb); - innerCb(mFakeVSyncTime, mFakeWakeupTime); -} - -TEST_F(VSyncReactorTest, negativeOffsetsApplied) { - nsecs_t const negativePhase = -4000; - Sequence seq; - EXPECT_CALL(*mMockDispatch, registerCallback(_, std::string(mName))) - .InSequence(seq) - .WillOnce(Return(mFakeToken)); - EXPECT_CALL(*mMockDispatch, - schedule(mFakeToken, computeWorkload(period, negativePhase), mFakeNow)) - .InSequence(seq); - mReactor.addEventListener(mName, negativePhase, &outerCb, lastCallbackTime); -} + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed)); + // confirmed period, but predictor wants numRequest samples. This one and prior are valid. + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod1, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod1, std::nullopt, &periodFlushed)); -TEST_F(VSyncReactorTest, beginResyncResetsModel) { - EXPECT_CALL(*mMockTracker, resetModel()); - mReactor.beginResync(); + mReactor.startPeriodTransition(newPeriod2); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod1, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod2, std::nullopt, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod2, std::nullopt, &periodFlushed)); + EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time += newPeriod2, std::nullopt, &periodFlushed)); } TEST_F(VSyncReactorTest, periodChangeWithGivenVsyncPeriod) { bool periodFlushed = true; - EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(3); + EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(2); mReactor.setIgnorePresentFences(true); nsecs_t const newPeriod = 5000; - mReactor.setPeriod(newPeriod); + mReactor.startPeriodTransition(newPeriod); - EXPECT_TRUE(mReactor.addResyncSample(0, 0, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(0, 0, &periodFlushed)); EXPECT_FALSE(periodFlushed); - EXPECT_TRUE(mReactor.addResyncSample(newPeriod, 0, &periodFlushed)); + EXPECT_TRUE(mReactor.addHwVsyncTimestamp(newPeriod, 0, &periodFlushed)); EXPECT_FALSE(periodFlushed); - EXPECT_FALSE(mReactor.addResyncSample(newPeriod, newPeriod, &periodFlushed)); + EXPECT_FALSE(mReactor.addHwVsyncTimestamp(newPeriod, newPeriod, &periodFlushed)); EXPECT_TRUE(periodFlushed); EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0))); @@ -666,77 +461,40 @@ TEST_F(VSyncReactorTest, periodChangeWithGivenVsyncPeriod) { TEST_F(VSyncReactorTest, periodIsMeasuredIfIgnoringComposer) { // Create a reactor which supports the kernel idle timer - auto idleReactor = VSyncReactor(std::make_unique<ClockWrapper>(mMockClock), - std::make_unique<VSyncDispatchWrapper>(mMockDispatch), - std::make_unique<VSyncTrackerWrapper>(mMockTracker), + auto idleReactor = VSyncReactor(std::make_unique<ClockWrapper>(mMockClock), *mMockTracker, kPendingLimit, true /* supportKernelIdleTimer */); bool periodFlushed = true; - EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(5); + EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(4); idleReactor.setIgnorePresentFences(true); // First, set the same period, which should only be confirmed when we receive two // matching callbacks - idleReactor.setPeriod(10000); - EXPECT_TRUE(idleReactor.addResyncSample(0, 0, &periodFlushed)); + idleReactor.startPeriodTransition(10000); + EXPECT_TRUE(idleReactor.addHwVsyncTimestamp(0, 0, &periodFlushed)); EXPECT_FALSE(periodFlushed); // Correct period but incorrect timestamp delta - EXPECT_TRUE(idleReactor.addResyncSample(0, 10000, &periodFlushed)); + EXPECT_TRUE(idleReactor.addHwVsyncTimestamp(0, 10000, &periodFlushed)); EXPECT_FALSE(periodFlushed); // Correct period and correct timestamp delta - EXPECT_FALSE(idleReactor.addResyncSample(10000, 10000, &periodFlushed)); + EXPECT_FALSE(idleReactor.addHwVsyncTimestamp(10000, 10000, &periodFlushed)); EXPECT_TRUE(periodFlushed); // Then, set a new period, which should be confirmed as soon as we receive a callback // reporting the new period nsecs_t const newPeriod = 5000; - idleReactor.setPeriod(newPeriod); + idleReactor.startPeriodTransition(newPeriod); // Incorrect timestamp delta and period - EXPECT_TRUE(idleReactor.addResyncSample(20000, 10000, &periodFlushed)); + EXPECT_TRUE(idleReactor.addHwVsyncTimestamp(20000, 10000, &periodFlushed)); EXPECT_FALSE(periodFlushed); // Incorrect timestamp delta but correct period - EXPECT_FALSE(idleReactor.addResyncSample(20000, 5000, &periodFlushed)); + EXPECT_FALSE(idleReactor.addHwVsyncTimestamp(20000, 5000, &periodFlushed)); EXPECT_TRUE(periodFlushed); EXPECT_TRUE(idleReactor.addPresentFence(generateSignalledFenceWithTime(0))); } -using VSyncReactorDeathTest = VSyncReactorTest; -TEST_F(VSyncReactorDeathTest, invalidRemoval) { - mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); - mReactor.removeEventListener(&outerCb, &lastCallbackTime); - EXPECT_DEATH(mReactor.removeEventListener(&outerCb, &lastCallbackTime), ".*"); -} - -TEST_F(VSyncReactorDeathTest, invalidChange) { - EXPECT_DEATH(mReactor.changePhaseOffset(&outerCb, mPhase), ".*"); - - // the current DispSync-interface usage pattern has evolved around an implementation quirk, - // which is a callback is assumed to always exist, and it is valid api usage to change the - // offset of an object that is in the removed state. - mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); - mReactor.removeEventListener(&outerCb, &lastCallbackTime); - mReactor.changePhaseOffset(&outerCb, mPhase); -} - -TEST_F(VSyncReactorDeathTest, cannotScheduleOnRegistration) { - ON_CALL(*mMockDispatch, schedule(_, _, _)) - .WillByDefault(Return(ScheduleResult::CannotSchedule)); - EXPECT_DEATH(mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime), ".*"); -} - -TEST_F(VSyncReactorDeathTest, cannotScheduleOnCallback) { - EXPECT_CALL(*mMockDispatch, registerCallback(_, std::string(mName))) - .WillOnce(DoAll(SaveArg<0>(&innerCb), Return(mFakeToken))); - EXPECT_CALL(*mMockDispatch, schedule(_, _, _)).WillOnce(Return(ScheduleResult::Scheduled)); - - mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); - ASSERT_TRUE(innerCb); - Mock::VerifyAndClearExpectations(mMockDispatch.get()); - - ON_CALL(*mMockDispatch, schedule(_, _, _)) - .WillByDefault(Return(ScheduleResult::CannotSchedule)); - EXPECT_DEATH(innerCb(mFakeVSyncTime, mFakeWakeupTime), ".*"); -} - } // namespace android::scheduler + +// TODO(b/129481165): remove the #pragma below and fix conversion issues +#pragma clang diagnostic pop // ignored "-Wextra"
\ No newline at end of file |