Loading services/surfaceflinger/Scheduler/VsyncSchedule.h +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <string> #include <ThreadContext.h> #include <android-base/thread_annotations.h> #include <ftl/enum.h> #include <ftl/optional.h> #include <scheduler/Features.h> Loading @@ -27,6 +28,7 @@ namespace android { class EventThreadTest; class VsyncScheduleTest; } namespace android::fuzz { Loading Loading @@ -96,6 +98,7 @@ public: private: friend class TestableScheduler; friend class android::EventThreadTest; friend class android::VsyncScheduleTest; friend class android::fuzz::SchedulerFuzzer; using TrackerPtr = std::unique_ptr<VsyncTracker>; Loading services/surfaceflinger/tests/unittests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ cc_test { "VSyncPredictorTest.cpp", "VSyncReactorTest.cpp", "VsyncConfigurationTest.cpp", "VsyncScheduleTest.cpp", ], } Loading services/surfaceflinger/tests/unittests/VsyncScheduleTest.cpp 0 → 100644 +215 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #undef LOG_TAG #define LOG_TAG "LibSurfaceFlingerUnittests" #include <ftl/fake_guard.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <log/log.h> #include <scheduler/Fps.h> #include "Scheduler/VsyncSchedule.h" #include "ThreadContext.h" #include "mock/MockSchedulerCallback.h" #include "mock/MockVSyncDispatch.h" #include "mock/MockVSyncTracker.h" #include "mock/MockVsyncController.h" using testing::_; namespace android { class VsyncScheduleTest : public testing::Test { protected: VsyncScheduleTest(); ~VsyncScheduleTest() override; scheduler::mock::SchedulerCallback mCallback; const std::unique_ptr<scheduler::VsyncSchedule> mVsyncSchedule = std::unique_ptr<scheduler::VsyncSchedule>( new scheduler::VsyncSchedule(std::make_unique<mock::VSyncTracker>(), std::make_unique<mock::VSyncDispatch>(), std::make_unique<mock::VsyncController>())); mock::VsyncController& getController() { return *static_cast<mock::VsyncController*>(&mVsyncSchedule->getController()); } }; VsyncScheduleTest::VsyncScheduleTest() { 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()); } VsyncScheduleTest::~VsyncScheduleTest() { 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 { using namespace testing; TEST_F(VsyncScheduleTest, InitiallyDisallowed) { ASSERT_FALSE(mVsyncSchedule->isHardwareVsyncAllowed(false /* makeAllowed */)); } TEST_F(VsyncScheduleTest, EnableDoesNothingWhenDisallowed) { EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); mVsyncSchedule->enableHardwareVsync(mCallback); } TEST_F(VsyncScheduleTest, DisableDoesNothingWhenDisallowed) { EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */); } TEST_F(VsyncScheduleTest, MakeAllowed) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); } TEST_F(VsyncScheduleTest, DisableDoesNothingWhenDisabled) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */); } TEST_F(VsyncScheduleTest, EnableWorksWhenDisabled) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); EXPECT_CALL(mCallback, setVsyncEnabled(true)); mVsyncSchedule->enableHardwareVsync(mCallback); } TEST_F(VsyncScheduleTest, EnableWorksOnce) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); EXPECT_CALL(mCallback, setVsyncEnabled(true)); mVsyncSchedule->enableHardwareVsync(mCallback); EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); mVsyncSchedule->enableHardwareVsync(mCallback); } TEST_F(VsyncScheduleTest, AllowedIsSticky) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(false /* makeAllowed */)); } TEST_F(VsyncScheduleTest, EnableDisable) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); EXPECT_CALL(mCallback, setVsyncEnabled(true)); mVsyncSchedule->enableHardwareVsync(mCallback); EXPECT_CALL(mCallback, setVsyncEnabled(false)); mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */); } TEST_F(VsyncScheduleTest, StartPeriodTransition) { // Note: startPeriodTransition is only called when hardware vsyncs are // allowed. ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); const Period period = (60_Hz).getPeriod(); EXPECT_CALL(mCallback, setVsyncEnabled(true)); EXPECT_CALL(getController(), startPeriodTransition(period.ns())); mVsyncSchedule->startPeriodTransition(mCallback, period); } TEST_F(VsyncScheduleTest, StartPeriodTransitionAlreadyEnabled) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); mVsyncSchedule->enableHardwareVsync(mCallback); const Period period = (60_Hz).getPeriod(); EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); EXPECT_CALL(getController(), startPeriodTransition(period.ns())); mVsyncSchedule->startPeriodTransition(mCallback, period); } TEST_F(VsyncScheduleTest, AddResyncSampleDisallowed) { const Period period = (60_Hz).getPeriod(); const auto timestamp = TimePoint::now(); EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); EXPECT_CALL(getController(), addHwVsyncTimestamp(_, _, _)).Times(0); mVsyncSchedule->addResyncSample(mCallback, timestamp, period); } TEST_F(VsyncScheduleTest, AddResyncSampleDisabled) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); const Period period = (60_Hz).getPeriod(); const auto timestamp = TimePoint::now(); EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); EXPECT_CALL(getController(), addHwVsyncTimestamp(_, _, _)).Times(0); mVsyncSchedule->addResyncSample(mCallback, timestamp, period); } TEST_F(VsyncScheduleTest, AddResyncSampleReturnsTrue) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); mVsyncSchedule->enableHardwareVsync(mCallback); const Period period = (60_Hz).getPeriod(); const auto timestamp = TimePoint::now(); EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); EXPECT_CALL(getController(), addHwVsyncTimestamp(timestamp.ns(), std::optional<nsecs_t>(period.ns()), _)) .WillOnce(Return(true)); mVsyncSchedule->addResyncSample(mCallback, timestamp, period); } TEST_F(VsyncScheduleTest, AddResyncSampleReturnsFalse) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); mVsyncSchedule->enableHardwareVsync(mCallback); const Period period = (60_Hz).getPeriod(); const auto timestamp = TimePoint::now(); EXPECT_CALL(mCallback, setVsyncEnabled(false)); EXPECT_CALL(getController(), addHwVsyncTimestamp(timestamp.ns(), std::optional<nsecs_t>(period.ns()), _)) .WillOnce(Return(false)); mVsyncSchedule->addResyncSample(mCallback, timestamp, period); } TEST_F(VsyncScheduleTest, PendingState) FTL_FAKE_GUARD(kMainThreadContext) { ASSERT_FALSE(mVsyncSchedule->getPendingHardwareVsyncState()); mVsyncSchedule->setPendingHardwareVsyncState(true); ASSERT_TRUE(mVsyncSchedule->getPendingHardwareVsyncState()); mVsyncSchedule->setPendingHardwareVsyncState(false); ASSERT_FALSE(mVsyncSchedule->getPendingHardwareVsyncState()); } } // namespace } // namespace android services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h +1 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ #include <gmock/gmock.h> #include "Scheduler/Scheduler.h" #include "Scheduler/ISchedulerCallback.h" namespace android::scheduler::mock { Loading Loading
services/surfaceflinger/Scheduler/VsyncSchedule.h +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <string> #include <ThreadContext.h> #include <android-base/thread_annotations.h> #include <ftl/enum.h> #include <ftl/optional.h> #include <scheduler/Features.h> Loading @@ -27,6 +28,7 @@ namespace android { class EventThreadTest; class VsyncScheduleTest; } namespace android::fuzz { Loading Loading @@ -96,6 +98,7 @@ public: private: friend class TestableScheduler; friend class android::EventThreadTest; friend class android::VsyncScheduleTest; friend class android::fuzz::SchedulerFuzzer; using TrackerPtr = std::unique_ptr<VsyncTracker>; Loading
services/surfaceflinger/tests/unittests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ cc_test { "VSyncPredictorTest.cpp", "VSyncReactorTest.cpp", "VsyncConfigurationTest.cpp", "VsyncScheduleTest.cpp", ], } Loading
services/surfaceflinger/tests/unittests/VsyncScheduleTest.cpp 0 → 100644 +215 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #undef LOG_TAG #define LOG_TAG "LibSurfaceFlingerUnittests" #include <ftl/fake_guard.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <log/log.h> #include <scheduler/Fps.h> #include "Scheduler/VsyncSchedule.h" #include "ThreadContext.h" #include "mock/MockSchedulerCallback.h" #include "mock/MockVSyncDispatch.h" #include "mock/MockVSyncTracker.h" #include "mock/MockVsyncController.h" using testing::_; namespace android { class VsyncScheduleTest : public testing::Test { protected: VsyncScheduleTest(); ~VsyncScheduleTest() override; scheduler::mock::SchedulerCallback mCallback; const std::unique_ptr<scheduler::VsyncSchedule> mVsyncSchedule = std::unique_ptr<scheduler::VsyncSchedule>( new scheduler::VsyncSchedule(std::make_unique<mock::VSyncTracker>(), std::make_unique<mock::VSyncDispatch>(), std::make_unique<mock::VsyncController>())); mock::VsyncController& getController() { return *static_cast<mock::VsyncController*>(&mVsyncSchedule->getController()); } }; VsyncScheduleTest::VsyncScheduleTest() { 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()); } VsyncScheduleTest::~VsyncScheduleTest() { 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 { using namespace testing; TEST_F(VsyncScheduleTest, InitiallyDisallowed) { ASSERT_FALSE(mVsyncSchedule->isHardwareVsyncAllowed(false /* makeAllowed */)); } TEST_F(VsyncScheduleTest, EnableDoesNothingWhenDisallowed) { EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); mVsyncSchedule->enableHardwareVsync(mCallback); } TEST_F(VsyncScheduleTest, DisableDoesNothingWhenDisallowed) { EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */); } TEST_F(VsyncScheduleTest, MakeAllowed) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); } TEST_F(VsyncScheduleTest, DisableDoesNothingWhenDisabled) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */); } TEST_F(VsyncScheduleTest, EnableWorksWhenDisabled) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); EXPECT_CALL(mCallback, setVsyncEnabled(true)); mVsyncSchedule->enableHardwareVsync(mCallback); } TEST_F(VsyncScheduleTest, EnableWorksOnce) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); EXPECT_CALL(mCallback, setVsyncEnabled(true)); mVsyncSchedule->enableHardwareVsync(mCallback); EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); mVsyncSchedule->enableHardwareVsync(mCallback); } TEST_F(VsyncScheduleTest, AllowedIsSticky) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(false /* makeAllowed */)); } TEST_F(VsyncScheduleTest, EnableDisable) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); EXPECT_CALL(mCallback, setVsyncEnabled(true)); mVsyncSchedule->enableHardwareVsync(mCallback); EXPECT_CALL(mCallback, setVsyncEnabled(false)); mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */); } TEST_F(VsyncScheduleTest, StartPeriodTransition) { // Note: startPeriodTransition is only called when hardware vsyncs are // allowed. ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); const Period period = (60_Hz).getPeriod(); EXPECT_CALL(mCallback, setVsyncEnabled(true)); EXPECT_CALL(getController(), startPeriodTransition(period.ns())); mVsyncSchedule->startPeriodTransition(mCallback, period); } TEST_F(VsyncScheduleTest, StartPeriodTransitionAlreadyEnabled) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); mVsyncSchedule->enableHardwareVsync(mCallback); const Period period = (60_Hz).getPeriod(); EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); EXPECT_CALL(getController(), startPeriodTransition(period.ns())); mVsyncSchedule->startPeriodTransition(mCallback, period); } TEST_F(VsyncScheduleTest, AddResyncSampleDisallowed) { const Period period = (60_Hz).getPeriod(); const auto timestamp = TimePoint::now(); EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); EXPECT_CALL(getController(), addHwVsyncTimestamp(_, _, _)).Times(0); mVsyncSchedule->addResyncSample(mCallback, timestamp, period); } TEST_F(VsyncScheduleTest, AddResyncSampleDisabled) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); const Period period = (60_Hz).getPeriod(); const auto timestamp = TimePoint::now(); EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); EXPECT_CALL(getController(), addHwVsyncTimestamp(_, _, _)).Times(0); mVsyncSchedule->addResyncSample(mCallback, timestamp, period); } TEST_F(VsyncScheduleTest, AddResyncSampleReturnsTrue) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); mVsyncSchedule->enableHardwareVsync(mCallback); const Period period = (60_Hz).getPeriod(); const auto timestamp = TimePoint::now(); EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0); EXPECT_CALL(getController(), addHwVsyncTimestamp(timestamp.ns(), std::optional<nsecs_t>(period.ns()), _)) .WillOnce(Return(true)); mVsyncSchedule->addResyncSample(mCallback, timestamp, period); } TEST_F(VsyncScheduleTest, AddResyncSampleReturnsFalse) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); mVsyncSchedule->enableHardwareVsync(mCallback); const Period period = (60_Hz).getPeriod(); const auto timestamp = TimePoint::now(); EXPECT_CALL(mCallback, setVsyncEnabled(false)); EXPECT_CALL(getController(), addHwVsyncTimestamp(timestamp.ns(), std::optional<nsecs_t>(period.ns()), _)) .WillOnce(Return(false)); mVsyncSchedule->addResyncSample(mCallback, timestamp, period); } TEST_F(VsyncScheduleTest, PendingState) FTL_FAKE_GUARD(kMainThreadContext) { ASSERT_FALSE(mVsyncSchedule->getPendingHardwareVsyncState()); mVsyncSchedule->setPendingHardwareVsyncState(true); ASSERT_TRUE(mVsyncSchedule->getPendingHardwareVsyncState()); mVsyncSchedule->setPendingHardwareVsyncState(false); ASSERT_FALSE(mVsyncSchedule->getPendingHardwareVsyncState()); } } // namespace } // namespace android
services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h +1 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ #include <gmock/gmock.h> #include "Scheduler/Scheduler.h" #include "Scheduler/ISchedulerCallback.h" namespace android::scheduler::mock { Loading