diff options
Diffstat (limited to 'services/surfaceflinger/tests/unittests/SchedulerTest.cpp')
-rw-r--r-- | services/surfaceflinger/tests/unittests/SchedulerTest.cpp | 202 |
1 files changed, 68 insertions, 134 deletions
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp index f680d802e6..1aa7320a8a 100644 --- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp +++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp @@ -14,34 +14,40 @@ * limitations under the License. */ +// TODO(b/129481165): remove the #pragma below and fix conversion issues +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wconversion" + +#undef LOG_TAG +#define LOG_TAG "SchedulerUnittests" + #include <gmock/gmock.h> #include <gtest/gtest.h> #include <log/log.h> #include <mutex> +#include "Scheduler/EventControlThread.h" #include "Scheduler/EventThread.h" #include "Scheduler/RefreshRateConfigs.h" #include "TestableScheduler.h" -#include "TestableSurfaceFlinger.h" +#include "mock/DisplayHardware/MockDisplay.h" #include "mock/MockEventThread.h" -#include "mock/MockLayer.h" -#include "mock/MockSchedulerCallback.h" using testing::_; using testing::Return; namespace android { -namespace { -constexpr PhysicalDisplayId PHYSICAL_DISPLAY_ID(999); +constexpr PhysicalDisplayId PHYSICAL_DISPLAY_ID = 999; class SchedulerTest : public testing::Test { protected: class MockEventThreadConnection : public android::EventThreadConnection { public: explicit MockEventThreadConnection(EventThread* eventThread) - : EventThreadConnection(eventThread, /*callingUid=*/0, ResyncCallback()) {} + : EventThreadConnection(eventThread, ResyncCallback(), + ISurfaceComposer::eConfigChangedSuppress) {} ~MockEventThreadConnection() = default; MOCK_METHOD1(stealReceiveChannel, status_t(gui::BitTube* outChannel)); @@ -50,39 +56,32 @@ protected: }; SchedulerTest(); + ~SchedulerTest() override; - const DisplayModePtr mode60 = DisplayMode::Builder(0) - .setId(DisplayModeId(0)) - .setVsyncPeriod(Fps(60.f).getPeriodNsecs()) - .setGroup(0) - .build(); - const DisplayModePtr mode120 = DisplayMode::Builder(1) - .setId(DisplayModeId(1)) - .setVsyncPeriod(Fps(120.f).getPeriodNsecs()) - .setGroup(0) - .build(); - - scheduler::RefreshRateConfigs mConfigs{{mode60}, mode60->getId()}; - - mock::SchedulerCallback mSchedulerCallback; - - // The scheduler should initially disable VSYNC. - struct ExpectDisableVsync { - ExpectDisableVsync(mock::SchedulerCallback& callback) { - EXPECT_CALL(callback, setVsyncEnabled(false)).Times(1); - } - } mExpectDisableVsync{mSchedulerCallback}; - - TestableScheduler* mScheduler = new TestableScheduler{mConfigs, mSchedulerCallback}; + std::unique_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs; + std::unique_ptr<TestableScheduler> mScheduler; Scheduler::ConnectionHandle mConnectionHandle; mock::EventThread* mEventThread; sp<MockEventThreadConnection> mEventThreadConnection; - - TestableSurfaceFlinger mFlinger; + Hwc2::mock::Display mDisplay; }; SchedulerTest::SchedulerTest() { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); + + std::vector<std::shared_ptr<const HWC2::Display::Config>> configs{ + HWC2::Display::Config::Builder(mDisplay, 0) + .setVsyncPeriod(int32_t(16666667)) + .setConfigGroup(0) + .build()}; + mRefreshRateConfigs = std::make_unique< + scheduler::RefreshRateConfigs>(configs, /*currentConfig=*/HwcConfigIndexType(0)); + + mScheduler = std::make_unique<TestableScheduler>(*mRefreshRateConfigs, false); + auto eventThread = std::make_unique<mock::EventThread>(); mEventThread = eventThread.get(); EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0)); @@ -96,149 +95,84 @@ SchedulerTest::SchedulerTest() { mConnectionHandle = mScheduler->createConnection(std::move(eventThread)); EXPECT_TRUE(mConnectionHandle); +} - mFlinger.resetScheduler(mScheduler); +SchedulerTest::~SchedulerTest() { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name()); } -} // namespace +namespace { +/* ------------------------------------------------------------------------ + * Test cases + */ TEST_F(SchedulerTest, invalidConnectionHandle) { Scheduler::ConnectionHandle handle; - const sp<IDisplayEventConnection> connection = mScheduler->createDisplayEventConnection(handle); - + sp<IDisplayEventConnection> connection; + ASSERT_NO_FATAL_FAILURE( + connection = mScheduler->createDisplayEventConnection(handle, + ISurfaceComposer:: + eConfigChangedSuppress)); EXPECT_FALSE(connection); EXPECT_FALSE(mScheduler->getEventConnection(handle)); // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads. EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0); - mScheduler->onHotplugReceived(handle, PHYSICAL_DISPLAY_ID, false); + ASSERT_NO_FATAL_FAILURE(mScheduler->onHotplugReceived(handle, PHYSICAL_DISPLAY_ID, false)); EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(0); - mScheduler->onScreenAcquired(handle); + ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(handle)); EXPECT_CALL(*mEventThread, onScreenReleased()).Times(0); - mScheduler->onScreenReleased(handle); + ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenReleased(handle)); std::string output; EXPECT_CALL(*mEventThread, dump(_)).Times(0); - mScheduler->dump(handle, output); + ASSERT_NO_FATAL_FAILURE(mScheduler->dump(handle, output)); EXPECT_TRUE(output.empty()); - EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(0); - mScheduler->setDuration(handle, 10ns, 20ns); + EXPECT_CALL(*mEventThread, setPhaseOffset(_)).Times(0); + ASSERT_NO_FATAL_FAILURE(mScheduler->setPhaseOffset(handle, 10)); } TEST_F(SchedulerTest, validConnectionHandle) { - const sp<IDisplayEventConnection> connection = - mScheduler->createDisplayEventConnection(mConnectionHandle); - + sp<IDisplayEventConnection> connection; + ASSERT_NO_FATAL_FAILURE( + connection = mScheduler->createDisplayEventConnection(mConnectionHandle, + ISurfaceComposer:: + eConfigChangedSuppress)); ASSERT_EQ(mEventThreadConnection, connection); EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle)); EXPECT_CALL(*mEventThread, onHotplugReceived(PHYSICAL_DISPLAY_ID, false)).Times(1); - mScheduler->onHotplugReceived(mConnectionHandle, PHYSICAL_DISPLAY_ID, false); + ASSERT_NO_FATAL_FAILURE( + mScheduler->onHotplugReceived(mConnectionHandle, PHYSICAL_DISPLAY_ID, false)); EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(1); - mScheduler->onScreenAcquired(mConnectionHandle); + ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(mConnectionHandle)); EXPECT_CALL(*mEventThread, onScreenReleased()).Times(1); - mScheduler->onScreenReleased(mConnectionHandle); + ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenReleased(mConnectionHandle)); std::string output("dump"); EXPECT_CALL(*mEventThread, dump(output)).Times(1); - mScheduler->dump(mConnectionHandle, output); + ASSERT_NO_FATAL_FAILURE(mScheduler->dump(mConnectionHandle, output)); EXPECT_FALSE(output.empty()); - EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(1); - mScheduler->setDuration(mConnectionHandle, 10ns, 20ns); + EXPECT_CALL(*mEventThread, setPhaseOffset(10)).Times(1); + ASSERT_NO_FATAL_FAILURE(mScheduler->setPhaseOffset(mConnectionHandle, 10)); static constexpr size_t kEventConnections = 5; - EXPECT_CALL(*mEventThread, getEventThreadConnectionCount()).WillOnce(Return(kEventConnections)); + ON_CALL(*mEventThread, getEventThreadConnectionCount()) + .WillByDefault(Return(kEventConnections)); EXPECT_EQ(kEventConnections, mScheduler->getEventThreadConnectionCount(mConnectionHandle)); } -TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) { - // The layer is registered at creation time and deregistered at destruction time. - sp<mock::MockLayer> layer = sp<mock::MockLayer>::make(mFlinger.flinger()); - - // recordLayerHistory should be a noop - ASSERT_EQ(static_cast<size_t>(0), mScheduler->getNumActiveLayers()); - mScheduler->recordLayerHistory(layer.get(), 0, LayerHistory::LayerUpdateType::Buffer); - ASSERT_EQ(static_cast<size_t>(0), mScheduler->getNumActiveLayers()); - - constexpr bool kPowerStateNormal = true; - mScheduler->setDisplayPowerState(kPowerStateNormal); - - constexpr uint32_t kDisplayArea = 999'999; - mScheduler->onPrimaryDisplayAreaChanged(kDisplayArea); - - EXPECT_CALL(mSchedulerCallback, changeRefreshRate(_, _)).Times(0); - mScheduler->chooseRefreshRateForContent(); -} - -TEST_F(SchedulerTest, updateDisplayModes) { - ASSERT_EQ(static_cast<size_t>(0), mScheduler->layerHistorySize()); - sp<mock::MockLayer> layer = sp<mock::MockLayer>::make(mFlinger.flinger()); - ASSERT_EQ(static_cast<size_t>(1), mScheduler->layerHistorySize()); - - mConfigs.updateDisplayModes({mode60, mode120}, /* activeMode */ mode60->getId()); - - ASSERT_EQ(static_cast<size_t>(0), mScheduler->getNumActiveLayers()); - mScheduler->recordLayerHistory(layer.get(), 0, LayerHistory::LayerUpdateType::Buffer); - ASSERT_EQ(static_cast<size_t>(1), mScheduler->getNumActiveLayers()); -} - -TEST_F(SchedulerTest, testDispatchCachedReportedMode) { - // If the optional fields are cleared, the function should return before - // onModeChange is called. - mScheduler->clearOptionalFieldsInFeatures(); - EXPECT_NO_FATAL_FAILURE(mScheduler->dispatchCachedReportedMode()); - EXPECT_CALL(*mEventThread, onModeChanged(_, _, _)).Times(0); -} - -TEST_F(SchedulerTest, onNonPrimaryDisplayModeChanged_invalidParameters) { - DisplayModeId modeId = DisplayModeId(111); - nsecs_t vsyncPeriod = 111111; - - // If the handle is incorrect, the function should return before - // onModeChange is called. - Scheduler::ConnectionHandle invalidHandle = {.id = 123}; - EXPECT_NO_FATAL_FAILURE(mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle, - PHYSICAL_DISPLAY_ID, modeId, - vsyncPeriod)); - EXPECT_CALL(*mEventThread, onModeChanged(_, _, _)).Times(0); -} - -TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) { - EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(Fps(60), 30ms)); - EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(Fps(90), 30ms)); - EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(Fps(120), 30ms)); - - EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(Fps(60), 40ms)); - - EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(Fps(60), 10ms)); -} - -MATCHER(Is120Hz, "") { - return arg.getFps().equalsWithMargin(Fps(120.f)); -} - -TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) { - mConfigs.updateDisplayModes({mode60, mode120}, /* activeMode */ mode60->getId()); - - sp<mock::MockLayer> layer = sp<mock::MockLayer>::make(mFlinger.flinger()); - - mScheduler->recordLayerHistory(layer.get(), 0, LayerHistory::LayerUpdateType::Buffer); - - constexpr bool kPowerStateNormal = true; - mScheduler->setDisplayPowerState(kPowerStateNormal); - - constexpr uint32_t kDisplayArea = 999'999; - mScheduler->onPrimaryDisplayAreaChanged(kDisplayArea); - - EXPECT_CALL(mSchedulerCallback, changeRefreshRate(Is120Hz(), _)).Times(1); - mScheduler->chooseRefreshRateForContent(); -} - +} // namespace } // namespace android + +// TODO(b/129481165): remove the #pragma below and fix conversion issues +#pragma clang diagnostic pop // ignored "-Wconversion" |