diff options
Diffstat (limited to 'services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp')
-rw-r--r-- | services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp | 215 |
1 files changed, 31 insertions, 184 deletions
diff --git a/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp b/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp index a9ad249383..afebc40aa9 100644 --- a/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp +++ b/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp @@ -27,99 +27,13 @@ #include "AsyncCallRecorder.h" #include "Scheduler/DispSyncSource.h" -#include "Scheduler/VSyncDispatch.h" +#include "mock/MockDispSync.h" namespace android { namespace { using namespace std::chrono_literals; -using namespace testing; - -class MockVSyncDispatch : public scheduler::VSyncDispatch { -public: - MOCK_METHOD2(registerCallback, - CallbackToken(std::function<void(nsecs_t, nsecs_t, nsecs_t)> const&, std::string)); - MOCK_METHOD1(unregisterCallback, void(CallbackToken)); - MOCK_METHOD2(schedule, scheduler::ScheduleResult(CallbackToken, ScheduleTiming)); - MOCK_METHOD1(cancel, scheduler::CancelResult(CallbackToken token)); - MOCK_CONST_METHOD1(dump, void(std::string&)); - - MockVSyncDispatch() { - ON_CALL(*this, registerCallback) - .WillByDefault( - [this](std::function<void(nsecs_t, nsecs_t, nsecs_t)> const& callback, - std::string) { - CallbackToken token(mNextToken); - mNextToken++; - - mCallbacks.emplace(token, CallbackData(callback)); - ALOGD("registerCallback: %zu", token.value()); - return token; - }); - - ON_CALL(*this, unregisterCallback).WillByDefault([this](CallbackToken token) { - ALOGD("unregisterCallback: %zu", token.value()); - mCallbacks.erase(token); - }); - - ON_CALL(*this, schedule).WillByDefault([this](CallbackToken token, ScheduleTiming timing) { - ALOGD("schedule: %zu", token.value()); - if (mCallbacks.count(token) == 0) { - ALOGD("schedule: callback %zu not registered", token.value()); - return scheduler::ScheduleResult{}; - } - - auto& callback = mCallbacks.at(token); - callback.scheduled = true; - callback.vsyncTime = timing.earliestVsync; - callback.targetWakeupTime = - timing.earliestVsync - timing.workDuration - timing.readyDuration; - ALOGD("schedule: callback %zu scheduled", token.value()); - return scheduler::ScheduleResult{callback.targetWakeupTime}; - }); - - ON_CALL(*this, cancel).WillByDefault([this](CallbackToken token) { - ALOGD("cancel: %zu", token.value()); - if (mCallbacks.count(token) == 0) { - ALOGD("cancel: callback %zu is not registered", token.value()); - return scheduler::CancelResult::Error; - } - - auto& callback = mCallbacks.at(token); - callback.scheduled = false; - ALOGD("cancel: callback %zu cancelled", token.value()); - return scheduler::CancelResult::Cancelled; - }); - } - - void triggerCallbacks() { - ALOGD("triggerCallbacks"); - for (auto& [token, callback] : mCallbacks) { - if (callback.scheduled) { - ALOGD("triggerCallbacks: callback %zu", token.value()); - callback.scheduled = false; - callback.func(callback.vsyncTime, callback.targetWakeupTime, callback.readyTime); - } else { - ALOGD("triggerCallbacks: callback %zu is not scheduled", token.value()); - } - } - } - -private: - struct CallbackData { - explicit CallbackData(std::function<void(nsecs_t, nsecs_t, nsecs_t)> func) - : func(std::move(func)) {} - - std::function<void(nsecs_t, nsecs_t, nsecs_t)> func; - bool scheduled = false; - nsecs_t vsyncTime = 0; - nsecs_t targetWakeupTime = 0; - nsecs_t readyTime = 0; - }; - - std::unordered_map<CallbackToken, CallbackData> mCallbacks; - size_t mNextToken; -}; +using testing::Return; class DispSyncSourceTest : public testing::Test, private VSyncSource::Callback { protected: @@ -129,19 +43,15 @@ protected: void createDispSync(); void createDispSyncSource(); - void onVSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp, - nsecs_t deadlineTimestamp) override; + void onVSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp) override; - std::unique_ptr<MockVSyncDispatch> mVSyncDispatch; - std::unique_ptr<scheduler::DispSyncSource> mDispSyncSource; + std::unique_ptr<mock::DispSync> mDispSync; + std::unique_ptr<DispSyncSource> mDispSyncSource; - AsyncCallRecorder<void (*)(nsecs_t, nsecs_t, nsecs_t)> mVSyncEventCallRecorder; + AsyncCallRecorder<void (*)(nsecs_t)> mVSyncEventCallRecorder; - static constexpr std::chrono::nanoseconds mWorkDuration = 20ms; - static constexpr std::chrono::nanoseconds mReadyDuration = 10ms; + static constexpr std::chrono::nanoseconds mPhaseOffset = 6ms; static constexpr int mIterations = 100; - const scheduler::VSyncDispatch::CallbackToken mFakeToken{2398}; - const std::string mName = "DispSyncSourceTest"; }; DispSyncSourceTest::DispSyncSourceTest() { @@ -156,21 +66,20 @@ DispSyncSourceTest::~DispSyncSourceTest() { ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name()); } -void DispSyncSourceTest::onVSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp, - nsecs_t deadlineTimestamp) { +void DispSyncSourceTest::onVSyncEvent(nsecs_t when, nsecs_t /*expectedVSyncTimestamp*/) { ALOGD("onVSyncEvent: %" PRId64, when); - mVSyncEventCallRecorder.recordCall(when, expectedVSyncTimestamp, deadlineTimestamp); + mVSyncEventCallRecorder.recordCall(when); } void DispSyncSourceTest::createDispSync() { - mVSyncDispatch = std::make_unique<MockVSyncDispatch>(); + mDispSync = std::make_unique<mock::DispSync>(); } void DispSyncSourceTest::createDispSyncSource() { - mDispSyncSource = - std::make_unique<scheduler::DispSyncSource>(*mVSyncDispatch, mWorkDuration, - mReadyDuration, true, mName.c_str()); + createDispSync(); + mDispSyncSource = std::make_unique<DispSyncSource>(mDispSync.get(), mPhaseOffset.count(), true, + "DispSyncSourceTest"); mDispSyncSource->setCallback(this); } @@ -180,119 +89,57 @@ void DispSyncSourceTest::createDispSyncSource() { TEST_F(DispSyncSourceTest, createDispSync) { createDispSync(); - EXPECT_TRUE(mVSyncDispatch); + EXPECT_TRUE(mDispSync); } TEST_F(DispSyncSourceTest, createDispSyncSource) { - createDispSync(); - - InSequence seq; - EXPECT_CALL(*mVSyncDispatch, registerCallback(_, mName)).WillOnce(Return(mFakeToken)); - EXPECT_CALL(*mVSyncDispatch, cancel(mFakeToken)) - .WillOnce(Return(scheduler::CancelResult::Cancelled)); - EXPECT_CALL(*mVSyncDispatch, unregisterCallback(mFakeToken)).WillOnce(Return()); createDispSyncSource(); - EXPECT_TRUE(mDispSyncSource); } TEST_F(DispSyncSourceTest, noCallbackAfterInit) { - createDispSync(); - - InSequence seq; - EXPECT_CALL(*mVSyncDispatch, registerCallback(_, mName)).Times(1); - EXPECT_CALL(*mVSyncDispatch, cancel(_)).Times(1); - EXPECT_CALL(*mVSyncDispatch, unregisterCallback(_)).Times(1); createDispSyncSource(); - EXPECT_TRUE(mDispSyncSource); // DispSyncSource starts with Vsync disabled - mVSyncDispatch->triggerCallbacks(); + mDispSync->triggerCallback(); EXPECT_FALSE(mVSyncEventCallRecorder.waitForUnexpectedCall().has_value()); } TEST_F(DispSyncSourceTest, waitForCallbacks) { - createDispSync(); - - InSequence seq; - EXPECT_CALL(*mVSyncDispatch, registerCallback(_, mName)).Times(1); - EXPECT_CALL(*mVSyncDispatch, - schedule(_, Truly([&](auto timings) { - return timings.workDuration == mWorkDuration.count() && - timings.readyDuration == mReadyDuration.count(); - }))) - .Times(mIterations + 1); - EXPECT_CALL(*mVSyncDispatch, cancel(_)).Times(1); - EXPECT_CALL(*mVSyncDispatch, unregisterCallback(_)).Times(1); createDispSyncSource(); - EXPECT_TRUE(mDispSyncSource); mDispSyncSource->setVSyncEnabled(true); + EXPECT_EQ(mDispSync->getCallbackPhase(), mPhaseOffset.count()); + for (int i = 0; i < mIterations; i++) { - mVSyncDispatch->triggerCallbacks(); - const auto callbackData = mVSyncEventCallRecorder.waitForCall(); - ASSERT_TRUE(callbackData.has_value()); - const auto [when, expectedVSyncTimestamp, deadlineTimestamp] = callbackData.value(); - EXPECT_EQ(when, expectedVSyncTimestamp - mWorkDuration.count() - mReadyDuration.count()); + mDispSync->triggerCallback(); + EXPECT_TRUE(mVSyncEventCallRecorder.waitForCall().has_value()); } } -TEST_F(DispSyncSourceTest, waitForCallbacksWithDurationChange) { - createDispSync(); - - InSequence seq; - EXPECT_CALL(*mVSyncDispatch, registerCallback(_, mName)).Times(1); - EXPECT_CALL(*mVSyncDispatch, - schedule(_, Truly([&](auto timings) { - return timings.workDuration == mWorkDuration.count() && - timings.readyDuration == mReadyDuration.count(); - }))) - .Times(1); - +TEST_F(DispSyncSourceTest, waitForCallbacksWithPhaseChange) { createDispSyncSource(); - EXPECT_TRUE(mDispSyncSource); mDispSyncSource->setVSyncEnabled(true); - EXPECT_CALL(*mVSyncDispatch, - schedule(_, Truly([&](auto timings) { - return timings.workDuration == mWorkDuration.count() && - timings.readyDuration == mReadyDuration.count(); - }))) - .Times(mIterations); + EXPECT_EQ(mDispSync->getCallbackPhase(), mPhaseOffset.count()); + for (int i = 0; i < mIterations; i++) { - mVSyncDispatch->triggerCallbacks(); - const auto callbackData = mVSyncEventCallRecorder.waitForCall(); - ASSERT_TRUE(callbackData.has_value()); - const auto [when, expectedVSyncTimestamp, deadlineTimestamp] = callbackData.value(); - EXPECT_EQ(when, expectedVSyncTimestamp - mWorkDuration.count() - mReadyDuration.count()); + mDispSync->triggerCallback(); + EXPECT_TRUE(mVSyncEventCallRecorder.waitForCall().has_value()); } - const auto newDuration = mWorkDuration / 2; - EXPECT_CALL(*mVSyncDispatch, schedule(_, Truly([&](auto timings) { - return timings.workDuration == newDuration.count() && - timings.readyDuration == 0; - }))) - .Times(1); - mDispSyncSource->setDuration(newDuration, 0ns); - - EXPECT_CALL(*mVSyncDispatch, schedule(_, Truly([&](auto timings) { - return timings.workDuration == newDuration.count() && - timings.readyDuration == 0; - }))) - .Times(mIterations); + EXPECT_CALL(*mDispSync, getPeriod()).Times(1).WillOnce(Return(16666666)); + mDispSyncSource->setPhaseOffset((mPhaseOffset / 2).count()); + + EXPECT_EQ(mDispSync->getCallbackPhase(), (mPhaseOffset / 2).count()); + for (int i = 0; i < mIterations; i++) { - mVSyncDispatch->triggerCallbacks(); - const auto callbackData = mVSyncEventCallRecorder.waitForCall(); - ASSERT_TRUE(callbackData.has_value()); - const auto [when, expectedVSyncTimestamp, deadlineTimestamp] = callbackData.value(); - EXPECT_EQ(when, expectedVSyncTimestamp - newDuration.count()); + mDispSync->triggerCallback(); + EXPECT_TRUE(mVSyncEventCallRecorder.waitForCall().has_value()); } - - EXPECT_CALL(*mVSyncDispatch, cancel(_)).Times(1); - EXPECT_CALL(*mVSyncDispatch, unregisterCallback(_)).Times(1); } } // namespace |