diff options
17 files changed, 370 insertions, 230 deletions
diff --git a/services/surfaceflinger/Scheduler/ISchedulerCallback.h b/services/surfaceflinger/Scheduler/ISchedulerCallback.h index 92c2189244..badbf53753 100644 --- a/services/surfaceflinger/Scheduler/ISchedulerCallback.h +++ b/services/surfaceflinger/Scheduler/ISchedulerCallback.h @@ -25,7 +25,7 @@ namespace android::scheduler { struct ISchedulerCallback { - virtual void setVsyncEnabled(PhysicalDisplayId, bool) = 0; + virtual void requestHardwareVsync(PhysicalDisplayId, bool enabled) = 0; virtual void requestDisplayModes(std::vector<display::DisplayModeRequest>) = 0; virtual void kernelTimerChanged(bool expired) = 0; virtual void triggerOnFrameRateOverridesChanged() = 0; diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp index 6d4089324a..41639b6c67 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.cpp +++ b/services/surfaceflinger/Scheduler/Scheduler.cpp @@ -114,8 +114,12 @@ void Scheduler::setPacesetterDisplay(std::optional<PhysicalDisplayId> pacesetter } void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr) { - registerDisplayInternal(displayId, std::move(selectorPtr), - std::make_shared<VsyncSchedule>(displayId, mFeatures)); + auto schedulePtr = std::make_shared<VsyncSchedule>(displayId, mFeatures, + [this](PhysicalDisplayId id, bool enable) { + onHardwareVsyncRequest(id, enable); + }); + + registerDisplayInternal(displayId, std::move(selectorPtr), std::move(schedulePtr)); } void Scheduler::registerDisplayInternal(PhysicalDisplayId displayId, @@ -123,14 +127,22 @@ void Scheduler::registerDisplayInternal(PhysicalDisplayId displayId, VsyncSchedulePtr schedulePtr) { demotePacesetterDisplay(); - std::shared_ptr<VsyncSchedule> pacesetterVsyncSchedule; - { + auto [pacesetterVsyncSchedule, isNew] = [&]() FTL_FAKE_GUARD(kMainThreadContext) { std::scoped_lock lock(mDisplayLock); - mDisplays.emplace_or_replace(displayId, std::move(selectorPtr), std::move(schedulePtr)); + const bool isNew = mDisplays + .emplace_or_replace(displayId, std::move(selectorPtr), + std::move(schedulePtr)) + .second; + + return std::make_pair(promotePacesetterDisplayLocked(), isNew); + }(); - pacesetterVsyncSchedule = promotePacesetterDisplayLocked(); - } applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule)); + + // Disable hardware VSYNC if the registration is new, as opposed to a renewal. + if (isNew) { + onHardwareVsyncRequest(displayId, false); + } } void Scheduler::unregisterDisplay(PhysicalDisplayId displayId) { @@ -414,13 +426,13 @@ void Scheduler::setVsyncConfig(const VsyncConfig& config, Period vsyncPeriod) { void Scheduler::enableHardwareVsync(PhysicalDisplayId id) { auto schedule = getVsyncSchedule(id); LOG_ALWAYS_FATAL_IF(!schedule); - schedule->enableHardwareVsync(mSchedulerCallback); + schedule->enableHardwareVsync(); } void Scheduler::disableHardwareVsync(PhysicalDisplayId id, bool disallow) { auto schedule = getVsyncSchedule(id); LOG_ALWAYS_FATAL_IF(!schedule); - schedule->disableHardwareVsync(mSchedulerCallback, disallow); + schedule->disableHardwareVsync(disallow); } void Scheduler::resyncAllToHardwareVsync(bool allowToEnable) { @@ -447,12 +459,32 @@ void Scheduler::resyncToHardwareVsyncLocked(PhysicalDisplayId id, bool allowToEn refreshRate = display.selectorPtr->getActiveMode().modePtr->getFps(); } if (refreshRate->isValid()) { - display.schedulePtr->startPeriodTransition(mSchedulerCallback, refreshRate->getPeriod(), - false /* force */); + constexpr bool kForce = false; + display.schedulePtr->startPeriodTransition(refreshRate->getPeriod(), kForce); } } } +void Scheduler::onHardwareVsyncRequest(PhysicalDisplayId id, bool enabled) { + static const auto& whence = __func__; + ATRACE_NAME(ftl::Concat(whence, ' ', id.value, ' ', enabled).c_str()); + + // On main thread to serialize reads/writes of pending hardware VSYNC state. + static_cast<void>( + schedule([=]() FTL_FAKE_GUARD(mDisplayLock) FTL_FAKE_GUARD(kMainThreadContext) { + ATRACE_NAME(ftl::Concat(whence, ' ', id.value, ' ', enabled).c_str()); + + if (const auto displayOpt = mDisplays.get(id)) { + auto& display = displayOpt->get(); + display.schedulePtr->setPendingHardwareVsyncState(enabled); + + if (display.powerMode != hal::PowerMode::OFF) { + mSchedulerCallback.requestHardwareVsync(id, enabled); + } + } + })); +} + void Scheduler::setRenderRate(PhysicalDisplayId id, Fps renderFrameRate) { std::scoped_lock lock(mDisplayLock); ftl::FakeGuard guard(kMainThreadContext); @@ -498,18 +530,17 @@ bool Scheduler::addResyncSample(PhysicalDisplayId id, nsecs_t timestamp, ALOGW("%s: Invalid display %s!", __func__, to_string(id).c_str()); return false; } - return schedule->addResyncSample(mSchedulerCallback, TimePoint::fromNs(timestamp), - hwcVsyncPeriod); + return schedule->addResyncSample(TimePoint::fromNs(timestamp), hwcVsyncPeriod); } void Scheduler::addPresentFence(PhysicalDisplayId id, std::shared_ptr<FenceTime> fence) { auto schedule = getVsyncSchedule(id); LOG_ALWAYS_FATAL_IF(!schedule); - const bool needMoreSignals = schedule->getController().addPresentFence(std::move(fence)); - if (needMoreSignals) { - schedule->enableHardwareVsync(mSchedulerCallback); + if (const bool needMoreSignals = schedule->getController().addPresentFence(std::move(fence))) { + schedule->enableHardwareVsync(); } else { - schedule->disableHardwareVsync(mSchedulerCallback, false /* disallow */); + constexpr bool kDisallow = false; + schedule->disableHardwareVsync(kDisallow); } } @@ -573,9 +604,13 @@ void Scheduler::setDisplayPowerMode(PhysicalDisplayId id, hal::PowerMode powerMo } { std::scoped_lock lock(mDisplayLock); - auto vsyncSchedule = getVsyncScheduleLocked(id); - LOG_ALWAYS_FATAL_IF(!vsyncSchedule); - vsyncSchedule->getController().setDisplayPowerMode(powerMode); + + const auto displayOpt = mDisplays.get(id); + LOG_ALWAYS_FATAL_IF(!displayOpt); + auto& display = displayOpt->get(); + + display.powerMode = powerMode; + display.schedulePtr->getController().setDisplayPowerMode(powerMode); } if (!isPacesetter) return; @@ -633,7 +668,7 @@ void Scheduler::kernelIdleTimerCallback(TimerState state) { ftl::FakeGuard guard(kMainThreadContext); for (const auto& [_, display] : mDisplays) { constexpr bool kDisallow = false; - display.schedulePtr->disableHardwareVsync(mSchedulerCallback, kDisallow); + display.schedulePtr->disableHardwareVsync(kDisallow); } } @@ -754,8 +789,8 @@ std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked( newVsyncSchedulePtr = pacesetter.schedulePtr; const Fps refreshRate = pacesetter.selectorPtr->getActiveMode().modePtr->getFps(); - newVsyncSchedulePtr->startPeriodTransition(mSchedulerCallback, refreshRate.getPeriod(), - true /* force */); + constexpr bool kForce = true; + newVsyncSchedulePtr->startPeriodTransition(refreshRate.getPeriod(), kForce); } return newVsyncSchedulePtr; } diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h index d628ac31b3..17e9ceaf66 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.h +++ b/services/surfaceflinger/Scheduler/Scheduler.h @@ -320,6 +320,9 @@ private: void touchTimerCallback(TimerState); void displayPowerTimerCallback(TimerState); + // VsyncSchedule delegate. + void onHardwareVsyncRequest(PhysicalDisplayId, bool enable); + void resyncToHardwareVsyncLocked(PhysicalDisplayId, bool allowToEnable, std::optional<Fps> refreshRate = std::nullopt) REQUIRES(kMainThreadContext, mDisplayLock); @@ -433,6 +436,8 @@ private: // Effectively const except in move constructor. RefreshRateSelectorPtr selectorPtr; VsyncSchedulePtr schedulePtr; + + hal::PowerMode powerMode = hal::PowerMode::OFF; }; using DisplayRef = std::reference_wrapper<Display>; diff --git a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp index 84671aea0d..ff3f29dbbf 100644 --- a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp +++ b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp @@ -22,7 +22,6 @@ #include "VsyncSchedule.h" -#include "ISchedulerCallback.h" #include "Utils/Dumper.h" #include "VSyncDispatchTimerQueue.h" #include "VSyncPredictor.h" @@ -54,8 +53,10 @@ private: VSyncCallbackRegistration mRegistration; }; -VsyncSchedule::VsyncSchedule(PhysicalDisplayId id, FeatureFlags features) +VsyncSchedule::VsyncSchedule(PhysicalDisplayId id, FeatureFlags features, + RequestHardwareVsync requestHardwareVsync) : mId(id), + mRequestHardwareVsync(std::move(requestHardwareVsync)), mTracker(createTracker(id)), mDispatch(createDispatch(mTracker)), mController(createController(id, *mTracker, features)), @@ -64,8 +65,9 @@ VsyncSchedule::VsyncSchedule(PhysicalDisplayId id, FeatureFlags features) : nullptr) {} VsyncSchedule::VsyncSchedule(PhysicalDisplayId id, TrackerPtr tracker, DispatchPtr dispatch, - ControllerPtr controller) + ControllerPtr controller, RequestHardwareVsync requestHardwareVsync) : mId(id), + mRequestHardwareVsync(std::move(requestHardwareVsync)), mTracker(std::move(tracker)), mDispatch(std::move(dispatch)), mController(std::move(controller)) {} @@ -135,14 +137,13 @@ VsyncSchedule::ControllerPtr VsyncSchedule::createController(PhysicalDisplayId i return reactor; } -void VsyncSchedule::startPeriodTransition(ISchedulerCallback& callback, Period period, bool force) { +void VsyncSchedule::startPeriodTransition(Period period, bool force) { std::lock_guard<std::mutex> lock(mHwVsyncLock); mController->startPeriodTransition(period.ns(), force); - enableHardwareVsyncLocked(callback); + enableHardwareVsyncLocked(); } -bool VsyncSchedule::addResyncSample(ISchedulerCallback& callback, TimePoint timestamp, - ftl::Optional<Period> hwcVsyncPeriod) { +bool VsyncSchedule::addResyncSample(TimePoint timestamp, ftl::Optional<Period> hwcVsyncPeriod) { bool needsHwVsync = false; bool periodFlushed = false; { @@ -154,31 +155,32 @@ bool VsyncSchedule::addResyncSample(ISchedulerCallback& callback, TimePoint time } } if (needsHwVsync) { - enableHardwareVsync(callback); + enableHardwareVsync(); } else { - disableHardwareVsync(callback, false /* disallow */); + constexpr bool kDisallow = false; + disableHardwareVsync(kDisallow); } return periodFlushed; } -void VsyncSchedule::enableHardwareVsync(ISchedulerCallback& callback) { +void VsyncSchedule::enableHardwareVsync() { std::lock_guard<std::mutex> lock(mHwVsyncLock); - enableHardwareVsyncLocked(callback); + enableHardwareVsyncLocked(); } -void VsyncSchedule::enableHardwareVsyncLocked(ISchedulerCallback& callback) { +void VsyncSchedule::enableHardwareVsyncLocked() { if (mHwVsyncState == HwVsyncState::Disabled) { getTracker().resetModel(); - callback.setVsyncEnabled(mId, true); + mRequestHardwareVsync(mId, true); mHwVsyncState = HwVsyncState::Enabled; } } -void VsyncSchedule::disableHardwareVsync(ISchedulerCallback& callback, bool disallow) { +void VsyncSchedule::disableHardwareVsync(bool disallow) { std::lock_guard<std::mutex> lock(mHwVsyncLock); switch (mHwVsyncState) { case HwVsyncState::Enabled: - callback.setVsyncEnabled(mId, false); + mRequestHardwareVsync(mId, false); [[fallthrough]]; case HwVsyncState::Disabled: mHwVsyncState = disallow ? HwVsyncState::Disallowed : HwVsyncState::Disabled; diff --git a/services/surfaceflinger/Scheduler/VsyncSchedule.h b/services/surfaceflinger/Scheduler/VsyncSchedule.h index 9867b41a2e..0757b5789d 100644 --- a/services/surfaceflinger/Scheduler/VsyncSchedule.h +++ b/services/surfaceflinger/Scheduler/VsyncSchedule.h @@ -16,6 +16,7 @@ #pragma once +#include <functional> #include <memory> #include <string> @@ -41,8 +42,6 @@ class SchedulerFuzzer; namespace android::scheduler { -struct ISchedulerCallback; - // TODO(b/185535769): Rename classes, and remove aliases. class VSyncDispatch; class VSyncTracker; @@ -54,7 +53,9 @@ using VsyncTracker = VSyncTracker; // Schedule that synchronizes to hardware VSYNC of a physical display. class VsyncSchedule final : public IVsyncSource { public: - VsyncSchedule(PhysicalDisplayId, FeatureFlags); + using RequestHardwareVsync = std::function<void(PhysicalDisplayId, bool enabled)>; + + VsyncSchedule(PhysicalDisplayId, FeatureFlags, RequestHardwareVsync); ~VsyncSchedule(); // IVsyncSource overrides: @@ -68,13 +69,12 @@ public: // \param [in] period The period that the system is changing into. // \param [in] force True to force a transition even if it is not a // change. - void startPeriodTransition(ISchedulerCallback&, Period period, bool force); + void startPeriodTransition(Period period, bool force); // Pass a VSYNC sample to VsyncController. Return true if // VsyncController detected that the VSYNC period changed. Enable or disable // hardware VSYNCs depending on whether more samples are needed. - bool addResyncSample(ISchedulerCallback&, TimePoint timestamp, - ftl::Optional<Period> hwcVsyncPeriod); + bool addResyncSample(TimePoint timestamp, ftl::Optional<Period> hwcVsyncPeriod); // TODO(b/185535769): Hide behind API. const VsyncTracker& getTracker() const { return *mTracker; } @@ -93,12 +93,12 @@ public: // Turn on hardware VSYNCs, unless mHwVsyncState is Disallowed, in which // case this call is ignored. - void enableHardwareVsync(ISchedulerCallback&) EXCLUDES(mHwVsyncLock); + void enableHardwareVsync() EXCLUDES(mHwVsyncLock); // Disable hardware VSYNCs. If `disallow` is true, future calls to // enableHardwareVsync are ineffective until isHardwareVsyncAllowed is // called with `makeAllowed` set to true. - void disableHardwareVsync(ISchedulerCallback&, bool disallow) EXCLUDES(mHwVsyncLock); + void disableHardwareVsync(bool disallow) EXCLUDES(mHwVsyncLock); // If true, enableHardwareVsync can enable hardware VSYNC (if not already // enabled). If false, enableHardwareVsync does nothing. @@ -111,8 +111,11 @@ public: protected: using ControllerPtr = std::unique_ptr<VsyncController>; + static void NoOpRequestHardwareVsync(PhysicalDisplayId, bool) {} + // For tests. - VsyncSchedule(PhysicalDisplayId, TrackerPtr, DispatchPtr, ControllerPtr); + VsyncSchedule(PhysicalDisplayId, TrackerPtr, DispatchPtr, ControllerPtr, + RequestHardwareVsync = NoOpRequestHardwareVsync); private: friend class TestableScheduler; @@ -124,7 +127,7 @@ private: static DispatchPtr createDispatch(TrackerPtr); static ControllerPtr createController(PhysicalDisplayId, VsyncTracker&, FeatureFlags); - void enableHardwareVsyncLocked(ISchedulerCallback&) REQUIRES(mHwVsyncLock); + void enableHardwareVsyncLocked() REQUIRES(mHwVsyncLock); mutable std::mutex mHwVsyncLock; enum class HwVsyncState { @@ -151,6 +154,7 @@ private: using TracerPtr = std::unique_ptr<PredictedVsyncTracer>; const PhysicalDisplayId mId; + const RequestHardwareVsync mRequestHardwareVsync; const TrackerPtr mTracker; const DispatchPtr mDispatch; const ControllerPtr mController; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index de0280cf96..74776ce088 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2138,26 +2138,6 @@ void SurfaceFlinger::onRefreshRateChangedDebug(const RefreshRateChangedDebugData } } -void SurfaceFlinger::setVsyncEnabled(PhysicalDisplayId id, bool enabled) { - const char* const whence = __func__; - ATRACE_FORMAT("%s (%d) for %" PRIu64, whence, enabled, id.value); - - // On main thread to avoid race conditions with display power state. - static_cast<void>(mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) { - { - ftl::FakeGuard guard(kMainThreadContext); - if (auto schedule = mScheduler->getVsyncSchedule(id)) { - schedule->setPendingHardwareVsyncState(enabled); - } - } - - ATRACE_FORMAT("%s (%d) for %" PRIu64 " (main thread)", whence, enabled, id.value); - if (const auto display = getDisplayDeviceLocked(id); display && display->isPoweredOn()) { - setHWCVsyncEnabled(id, enabled); - } - })); -} - void SurfaceFlinger::configure() FTL_FAKE_GUARD(kMainThreadContext) { Mutex::Autolock lock(mStateLock); if (configureLocked()) { @@ -3783,6 +3763,10 @@ void SurfaceFlinger::updateCursorAsync() { moveSnapshotsFromCompositionArgs(refreshArgs, layers); } +void SurfaceFlinger::requestHardwareVsync(PhysicalDisplayId displayId, bool enable) { + getHwComposer().setVsyncEnabled(displayId, enable ? hal::Vsync::ENABLE : hal::Vsync::DISABLE); +} + void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest> modeRequests) { if (mBootStage != BootStage::FINISHED) { ALOGV("Currently in the boot stage, skipping display mode changes"); @@ -3869,8 +3853,6 @@ void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) { static_cast<ISchedulerCallback&>(*this), features, std::move(modulatorPtr)); mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector()); - - setVsyncEnabled(display->getPhysicalId(), false); mScheduler->startTimers(); const auto configs = mVsyncConfiguration->getCurrentConfigs(); @@ -5411,11 +5393,14 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: getHwComposer().setPowerMode(displayId, mode); if (displayId == mActiveDisplayId && mode != hal::PowerMode::DOZE_SUSPEND) { - setHWCVsyncEnabled(displayId, - mScheduler->getVsyncSchedule(displayId) - ->getPendingHardwareVsyncState()); + const bool enable = + mScheduler->getVsyncSchedule(displayId)->getPendingHardwareVsyncState(); + requestHardwareVsync(displayId, enable); + mScheduler->enableSyntheticVsync(false); - mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */, refreshRate); + + constexpr bool kAllowToEnable = true; + mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, refreshRate); } mVisibleRegionsDirty = true; @@ -5439,10 +5424,10 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: } } - // Make sure HWVsync is disabled before turning off the display - setHWCVsyncEnabled(displayId, false); - + // Disable VSYNC before turning off the display. + requestHardwareVsync(displayId, false); getHwComposer().setPowerMode(displayId, mode); + mVisibleRegionsDirty = true; // from this point on, SF will stop drawing on this display } else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) { @@ -5470,9 +5455,10 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: if (displayId == mActiveDisplayId) { mTimeStats->setPowerMode(mode); mRefreshRateStats->setPowerMode(mode); - mScheduler->setDisplayPowerMode(displayId, mode); } + mScheduler->setDisplayPowerMode(displayId, mode); + ALOGD("Finished setting power mode %d on display %s", mode, to_string(displayId).c_str()); } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 1db2ab6dbb..040573d322 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -632,10 +632,7 @@ private: void sample() override; // ISchedulerCallback overrides: - - // Toggles hardware VSYNC by calling into HWC. - // TODO(b/241286146): Rename for self-explanatory API. - void setVsyncEnabled(PhysicalDisplayId, bool) override; + void requestHardwareVsync(PhysicalDisplayId, bool) override; void requestDisplayModes(std::vector<display::DisplayModeRequest>) override; void kernelTimerChanged(bool expired) override; void triggerOnFrameRateOverridesChanged() override; @@ -992,11 +989,6 @@ private: */ nsecs_t getVsyncPeriodFromHWC() const REQUIRES(mStateLock); - void setHWCVsyncEnabled(PhysicalDisplayId id, bool enabled) { - hal::Vsync halState = enabled ? hal::Vsync::ENABLE : hal::Vsync::DISABLE; - getHwComposer().setVsyncEnabled(id, halState); - } - /* * Display identification */ diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h index acd301e1e8..5c152b52da 100644 --- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h +++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h @@ -789,7 +789,7 @@ public: } private: - void setVsyncEnabled(PhysicalDisplayId, bool) override {} + void requestHardwareVsync(PhysicalDisplayId, bool) override {} void requestDisplayModes(std::vector<display::DisplayModeRequest>) override {} void kernelTimerChanged(bool) override {} void triggerOnFrameRateOverridesChanged() override {} diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp index 55705cab76..1b0d892c8c 100644 --- a/services/surfaceflinger/tests/unittests/Android.bp +++ b/services/surfaceflinger/tests/unittests/Android.bp @@ -103,12 +103,12 @@ cc_test { "SurfaceFlinger_DisplayModeSwitching.cpp", "SurfaceFlinger_DisplayTransactionCommitTest.cpp", "SurfaceFlinger_ExcludeDolbyVisionTest.cpp", + "SurfaceFlinger_FoldableTest.cpp", "SurfaceFlinger_GetDisplayNativePrimariesTest.cpp", "SurfaceFlinger_GetDisplayStatsTest.cpp", "SurfaceFlinger_HdrOutputControlTest.cpp", "SurfaceFlinger_HotplugTest.cpp", "SurfaceFlinger_InitializeDisplaysTest.cpp", - "SurfaceFlinger_MultiDisplayPacesetterTest.cpp", "SurfaceFlinger_NotifyPowerBoostTest.cpp", "SurfaceFlinger_PowerHintTest.cpp", "SurfaceFlinger_SetDisplayStateTest.cpp", diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h index e64cb38b16..ee12276994 100644 --- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h +++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h @@ -371,10 +371,11 @@ struct HwcDisplayVariant { // Called by tests to inject a HWC display setup template <bool kInitPowerMode = true> static void injectHwcDisplay(DisplayTransactionTest* test) { - EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _)) - .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})), - Return(Error::NONE))); if constexpr (kInitPowerMode) { + EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _)) + .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})), + Return(Error::NONE))); + EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, INIT_POWER_MODE)) .WillOnce(Return(Error::NONE)); } diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp index 965e37873f..682c998542 100644 --- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp +++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp @@ -155,6 +155,33 @@ TEST_F(SchedulerTest, validConnectionHandle) { EXPECT_EQ(kEventConnections, mScheduler->getEventThreadConnectionCount(mConnectionHandle)); } +TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) { + // Hardware VSYNC should not change if the display is already registered. + EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId1, false)).Times(0); + mScheduler->registerDisplay(kDisplayId1, + std::make_shared<RefreshRateSelector>(kDisplay1Modes, + kDisplay1Mode60->getId())); + + // TODO(b/241285191): Restore once VsyncSchedule::getPendingHardwareVsyncState is called by + // Scheduler::setDisplayPowerMode rather than SF::setPowerModeInternal. +#if 0 + // Hardware VSYNC should be disabled for newly registered displays. + EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId2, false)).Times(1); + EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId3, false)).Times(1); +#endif + + mScheduler->registerDisplay(kDisplayId2, + std::make_shared<RefreshRateSelector>(kDisplay2Modes, + kDisplay2Mode60->getId())); + mScheduler->registerDisplay(kDisplayId3, + std::make_shared<RefreshRateSelector>(kDisplay3Modes, + kDisplay3Mode60->getId())); + + EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId1)->getPendingHardwareVsyncState()); + EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId2)->getPendingHardwareVsyncState()); + EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId3)->getPendingHardwareVsyncState()); +} + TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) { // The layer is registered at creation time and deregistered at destruction time. sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger()); diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp new file mode 100644 index 0000000000..bd2344c60d --- /dev/null +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp @@ -0,0 +1,162 @@ +/* + * 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 "DisplayTransactionTestHelpers.h" + +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +namespace android { +namespace { + +struct FoldableTest : DisplayTransactionTest { + static constexpr bool kWithMockScheduler = false; + FoldableTest() : DisplayTransactionTest(kWithMockScheduler) {} + + void SetUp() override { + injectMockScheduler(kInnerDisplayId); + + // Inject inner and outer displays with uninitialized power modes. + constexpr bool kInitPowerMode = false; + { + InnerDisplayVariant::injectHwcDisplay<kInitPowerMode>(this); + auto injector = InnerDisplayVariant::makeFakeExistingDisplayInjector(this); + injector.setPowerMode(std::nullopt); + injector.setRefreshRateSelector(mFlinger.scheduler()->refreshRateSelector()); + mInnerDisplay = injector.inject(); + } + { + OuterDisplayVariant::injectHwcDisplay<kInitPowerMode>(this); + auto injector = OuterDisplayVariant::makeFakeExistingDisplayInjector(this); + injector.setPowerMode(std::nullopt); + mOuterDisplay = injector.inject(); + } + } + + static inline PhysicalDisplayId kInnerDisplayId = InnerDisplayVariant::DISPLAY_ID::get(); + static inline PhysicalDisplayId kOuterDisplayId = OuterDisplayVariant::DISPLAY_ID::get(); + + sp<DisplayDevice> mInnerDisplay, mOuterDisplay; +}; + +TEST_F(FoldableTest, foldUnfold) { + // When the device boots, the inner display should be the pacesetter. + ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kInnerDisplayId); + + // ...and should still be after powering on. + mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); + ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kInnerDisplayId); + + // The outer display should become the pacesetter after folding. + mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::OFF); + mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::ON); + ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kOuterDisplayId); + + // The inner display should become the pacesetter after unfolding. + mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::OFF); + mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); + ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kInnerDisplayId); + + // The inner display should stay the pacesetter if both are powered on. + // TODO(b/255635821): The pacesetter should depend on the displays' refresh rates. + mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::ON); + ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kInnerDisplayId); + + // The outer display should become the pacesetter if designated. + mFlinger.scheduler()->setPacesetterDisplay(kOuterDisplayId); + ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kOuterDisplayId); +} + +TEST_F(FoldableTest, doesNotRequestHardwareVsyncIfPoweredOff) { + // Both displays are powered off. + EXPECT_CALL(mFlinger.mockSchedulerCallback(), requestHardwareVsync(kInnerDisplayId, _)) + .Times(0); + EXPECT_CALL(mFlinger.mockSchedulerCallback(), requestHardwareVsync(kOuterDisplayId, _)) + .Times(0); + + EXPECT_FALSE(mInnerDisplay->isPoweredOn()); + EXPECT_FALSE(mOuterDisplay->isPoweredOn()); + + auto& scheduler = *mFlinger.scheduler(); + scheduler.onHardwareVsyncRequest(kInnerDisplayId, true); + scheduler.onHardwareVsyncRequest(kOuterDisplayId, true); +} + +TEST_F(FoldableTest, requestsHardwareVsyncForInnerDisplay) { + // Only inner display is powered on. + EXPECT_CALL(mFlinger.mockSchedulerCallback(), requestHardwareVsync(kInnerDisplayId, true)) + .Times(1); + EXPECT_CALL(mFlinger.mockSchedulerCallback(), requestHardwareVsync(kOuterDisplayId, _)) + .Times(0); + + // The injected VsyncSchedule uses TestableScheduler::mockRequestHardwareVsync, so no calls to + // ISchedulerCallback::requestHardwareVsync are expected during setPowerModeInternal. + mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); + + EXPECT_TRUE(mInnerDisplay->isPoweredOn()); + EXPECT_FALSE(mOuterDisplay->isPoweredOn()); + + auto& scheduler = *mFlinger.scheduler(); + scheduler.onHardwareVsyncRequest(kInnerDisplayId, true); + scheduler.onHardwareVsyncRequest(kOuterDisplayId, true); +} + +TEST_F(FoldableTest, requestsHardwareVsyncForOuterDisplay) { + // Only outer display is powered on. + EXPECT_CALL(mFlinger.mockSchedulerCallback(), requestHardwareVsync(kInnerDisplayId, _)) + .Times(0); + EXPECT_CALL(mFlinger.mockSchedulerCallback(), requestHardwareVsync(kOuterDisplayId, true)) + .Times(1); + + // The injected VsyncSchedule uses TestableScheduler::mockRequestHardwareVsync, so no calls to + // ISchedulerCallback::requestHardwareVsync are expected during setPowerModeInternal. + mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); + mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::OFF); + mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::ON); + + EXPECT_FALSE(mInnerDisplay->isPoweredOn()); + EXPECT_TRUE(mOuterDisplay->isPoweredOn()); + + auto& scheduler = *mFlinger.scheduler(); + scheduler.onHardwareVsyncRequest(kInnerDisplayId, true); + scheduler.onHardwareVsyncRequest(kOuterDisplayId, true); +} + +TEST_F(FoldableTest, requestsHardwareVsyncForBothDisplays) { + // Both displays are powered on. + EXPECT_CALL(mFlinger.mockSchedulerCallback(), requestHardwareVsync(kInnerDisplayId, true)) + .Times(1); + EXPECT_CALL(mFlinger.mockSchedulerCallback(), requestHardwareVsync(kOuterDisplayId, true)) + .Times(1); + + // The injected VsyncSchedule uses TestableScheduler::mockRequestHardwareVsync, so no calls to + // ISchedulerCallback::requestHardwareVsync are expected during setPowerModeInternal. + mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); + mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::ON); + + EXPECT_TRUE(mInnerDisplay->isPoweredOn()); + EXPECT_TRUE(mOuterDisplay->isPoweredOn()); + + auto& scheduler = *mFlinger.scheduler(); + scheduler.onHardwareVsyncRequest(mInnerDisplay->getPhysicalId(), true); + scheduler.onHardwareVsyncRequest(mOuterDisplay->getPhysicalId(), true); +} + +} // namespace +} // namespace android diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_MultiDisplayPacesetterTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_MultiDisplayPacesetterTest.cpp deleted file mode 100644 index e38f56e65f..0000000000 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_MultiDisplayPacesetterTest.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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 "DisplayTransactionTestHelpers.h" - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -namespace android { -namespace { - -struct MultiDisplayPacesetterTest : DisplayTransactionTest { - static constexpr bool kWithMockScheduler = false; - MultiDisplayPacesetterTest() : DisplayTransactionTest(kWithMockScheduler) {} -}; - -TEST_F(MultiDisplayPacesetterTest, foldable) { - injectMockScheduler(InnerDisplayVariant::DISPLAY_ID::get()); - - // Inject inner and outer displays with uninitialized power modes. - sp<DisplayDevice> innerDisplay, outerDisplay; - constexpr bool kInitPowerMode = false; - { - InnerDisplayVariant::injectHwcDisplay<kInitPowerMode>(this); - auto injector = InnerDisplayVariant::makeFakeExistingDisplayInjector(this); - injector.setPowerMode(std::nullopt); - injector.setRefreshRateSelector(mFlinger.scheduler()->refreshRateSelector()); - innerDisplay = injector.inject(); - } - { - OuterDisplayVariant::injectHwcDisplay<kInitPowerMode>(this); - auto injector = OuterDisplayVariant::makeFakeExistingDisplayInjector(this); - injector.setPowerMode(std::nullopt); - outerDisplay = injector.inject(); - } - - // When the device boots, the inner display should be the pacesetter. - ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), innerDisplay->getPhysicalId()); - - // ...and should still be after powering on. - mFlinger.setPowerModeInternal(innerDisplay, PowerMode::ON); - ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), innerDisplay->getPhysicalId()); - - // The outer display should become the pacesetter after folding. - mFlinger.setPowerModeInternal(innerDisplay, PowerMode::OFF); - mFlinger.setPowerModeInternal(outerDisplay, PowerMode::ON); - ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), outerDisplay->getPhysicalId()); - - // The inner display should become the pacesetter after unfolding. - mFlinger.setPowerModeInternal(outerDisplay, PowerMode::OFF); - mFlinger.setPowerModeInternal(innerDisplay, PowerMode::ON); - ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), innerDisplay->getPhysicalId()); - - // The inner display should stay the pacesetter if both are powered on. - // TODO(b/255635821): The pacesetter should depend on the displays' refresh rates. - mFlinger.setPowerModeInternal(outerDisplay, PowerMode::ON); - ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), innerDisplay->getPhysicalId()); - - // The outer display should become the pacesetter if designated. - mFlinger.scheduler()->setPacesetterDisplay(outerDisplay->getPhysicalId()); - ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), outerDisplay->getPhysicalId()); -} - -} // namespace -} // namespace android diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp index 7754c21805..cf3fab3aa3 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp @@ -61,7 +61,7 @@ struct DozeNotSupportedVariant { struct EventThreadBaseSupportedVariant { static void setupVsyncNoCallExpectations(DisplayTransactionTest* test) { // Expect no change to hardware nor synthetic VSYNC. - EXPECT_CALL(test->mFlinger.mockSchedulerCallback(), setVsyncEnabled(_, _)).Times(0); + EXPECT_CALL(test->mFlinger.scheduler()->mockRequestHardwareVsync, Call(_, _)).Times(0); EXPECT_CALL(*test->mEventThread, enableSyntheticVsync(_)).Times(0); } }; @@ -79,13 +79,13 @@ struct EventThreadNotSupportedVariant : public EventThreadBaseSupportedVariant { struct EventThreadIsSupportedVariant : public EventThreadBaseSupportedVariant { static void setupEnableVsyncCallExpectations(DisplayTransactionTest* test) { // Expect to enable hardware VSYNC and disable synthetic VSYNC. - EXPECT_CALL(test->mFlinger.mockSchedulerCallback(), setVsyncEnabled(_, true)).Times(1); + EXPECT_CALL(test->mFlinger.scheduler()->mockRequestHardwareVsync, Call(_, true)).Times(1); EXPECT_CALL(*test->mEventThread, enableSyntheticVsync(false)).Times(1); } static void setupDisableVsyncCallExpectations(DisplayTransactionTest* test) { // Expect to disable hardware VSYNC and enable synthetic VSYNC. - EXPECT_CALL(test->mFlinger.mockSchedulerCallback(), setVsyncEnabled(_, false)).Times(1); + EXPECT_CALL(test->mFlinger.scheduler()->mockRequestHardwareVsync, Call(_, false)).Times(1); EXPECT_CALL(*test->mEventThread, enableSyntheticVsync(true)).Times(1); } }; diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h index 5d2dfe4dce..aac11c01b8 100644 --- a/services/surfaceflinger/tests/unittests/TestableScheduler.h +++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h @@ -27,6 +27,7 @@ #include "Scheduler/Scheduler.h" #include "Scheduler/VSyncTracker.h" #include "Scheduler/VsyncController.h" +#include "Scheduler/VsyncSchedule.h" #include "mock/MockVSyncDispatch.h" #include "mock/MockVSyncTracker.h" #include "mock/MockVsyncController.h" @@ -80,9 +81,13 @@ public: new VsyncSchedule(displayId, std::move(tracker), std::make_shared< mock::VSyncDispatch>(), - std::move(controller)))); + std::move(controller), + mockRequestHardwareVsync + .AsStdFunction()))); } + testing::MockFunction<void(PhysicalDisplayId, bool)> mockRequestHardwareVsync; + void unregisterDisplay(PhysicalDisplayId displayId) { ftl::FakeGuard guard(kMainThreadContext); Scheduler::unregisterDisplay(displayId); @@ -163,6 +168,8 @@ public: : VsyncSchedule::HwVsyncState::Disabled; } + using Scheduler::onHardwareVsyncRequest; + private: // ICompositor overrides: void configure() override {} diff --git a/services/surfaceflinger/tests/unittests/VsyncScheduleTest.cpp b/services/surfaceflinger/tests/unittests/VsyncScheduleTest.cpp index 4010fa6a5b..a8a3cd0293 100644 --- a/services/surfaceflinger/tests/unittests/VsyncScheduleTest.cpp +++ b/services/surfaceflinger/tests/unittests/VsyncScheduleTest.cpp @@ -25,7 +25,6 @@ #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" @@ -34,20 +33,21 @@ using testing::_; namespace android { -constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(42u); +constexpr PhysicalDisplayId kDisplayId = PhysicalDisplayId::fromPort(42u); class VsyncScheduleTest : public testing::Test { protected: VsyncScheduleTest(); ~VsyncScheduleTest() override; - scheduler::mock::SchedulerCallback mCallback; + testing::MockFunction<void(PhysicalDisplayId, bool)> mRequestHardwareVsync; + const std::unique_ptr<scheduler::VsyncSchedule> mVsyncSchedule = std::unique_ptr<scheduler::VsyncSchedule>( - new scheduler::VsyncSchedule(DEFAULT_DISPLAY_ID, - std::make_shared<mock::VSyncTracker>(), + new scheduler::VsyncSchedule(kDisplayId, std::make_shared<mock::VSyncTracker>(), std::make_shared<mock::VSyncDispatch>(), - std::make_unique<mock::VsyncController>())); + std::make_unique<mock::VsyncController>(), + mRequestHardwareVsync.AsStdFunction())); mock::VsyncController& getController() { return *static_cast<mock::VsyncController*>(&mVsyncSchedule->getController()); @@ -75,21 +75,21 @@ TEST_F(VsyncScheduleTest, InitiallyDisallowed) { } TEST_F(VsyncScheduleTest, EnableDoesNothingWhenDisallowed) { - EXPECT_CALL(mCallback, setVsyncEnabled(_, _)).Times(0); + EXPECT_CALL(mRequestHardwareVsync, Call(_, _)).Times(0); - mVsyncSchedule->enableHardwareVsync(mCallback); + mVsyncSchedule->enableHardwareVsync(); } TEST_F(VsyncScheduleTest, DisableDoesNothingWhenDisallowed) { - EXPECT_CALL(mCallback, setVsyncEnabled(_, _)).Times(0); + EXPECT_CALL(mRequestHardwareVsync, Call(_, _)).Times(0); - mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */); + mVsyncSchedule->disableHardwareVsync(false /* disallow */); } TEST_F(VsyncScheduleTest, DisableDoesNothingWhenDisallowed2) { - EXPECT_CALL(mCallback, setVsyncEnabled(_, _)).Times(0); + EXPECT_CALL(mRequestHardwareVsync, Call(_, _)).Times(0); - mVsyncSchedule->disableHardwareVsync(mCallback, true /* disallow */); + mVsyncSchedule->disableHardwareVsync(true /* disallow */); } TEST_F(VsyncScheduleTest, MakeAllowed) { @@ -98,33 +98,33 @@ TEST_F(VsyncScheduleTest, MakeAllowed) { TEST_F(VsyncScheduleTest, DisableDoesNothingWhenDisabled) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); - EXPECT_CALL(mCallback, setVsyncEnabled(_, _)).Times(0); + EXPECT_CALL(mRequestHardwareVsync, Call(_, _)).Times(0); - mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */); + mVsyncSchedule->disableHardwareVsync(false /* disallow */); } TEST_F(VsyncScheduleTest, DisableDoesNothingWhenDisabled2) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); - EXPECT_CALL(mCallback, setVsyncEnabled(_, _)).Times(0); + EXPECT_CALL(mRequestHardwareVsync, Call(_, _)).Times(0); - mVsyncSchedule->disableHardwareVsync(mCallback, true /* disallow */); + mVsyncSchedule->disableHardwareVsync(true /* disallow */); } TEST_F(VsyncScheduleTest, EnableWorksWhenDisabled) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); - EXPECT_CALL(mCallback, setVsyncEnabled(DEFAULT_DISPLAY_ID, true)); + EXPECT_CALL(mRequestHardwareVsync, Call(kDisplayId, true)); - mVsyncSchedule->enableHardwareVsync(mCallback); + mVsyncSchedule->enableHardwareVsync(); } TEST_F(VsyncScheduleTest, EnableWorksOnce) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); - EXPECT_CALL(mCallback, setVsyncEnabled(DEFAULT_DISPLAY_ID, true)); + EXPECT_CALL(mRequestHardwareVsync, Call(kDisplayId, true)); - mVsyncSchedule->enableHardwareVsync(mCallback); + mVsyncSchedule->enableHardwareVsync(); - EXPECT_CALL(mCallback, setVsyncEnabled(_, _)).Times(0); - mVsyncSchedule->enableHardwareVsync(mCallback); + EXPECT_CALL(mRequestHardwareVsync, Call(_, _)).Times(0); + mVsyncSchedule->enableHardwareVsync(); } TEST_F(VsyncScheduleTest, AllowedIsSticky) { @@ -134,22 +134,22 @@ TEST_F(VsyncScheduleTest, AllowedIsSticky) { TEST_F(VsyncScheduleTest, EnableDisable) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); - EXPECT_CALL(mCallback, setVsyncEnabled(DEFAULT_DISPLAY_ID, true)); + EXPECT_CALL(mRequestHardwareVsync, Call(kDisplayId, true)); - mVsyncSchedule->enableHardwareVsync(mCallback); + mVsyncSchedule->enableHardwareVsync(); - EXPECT_CALL(mCallback, setVsyncEnabled(DEFAULT_DISPLAY_ID, false)); - mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */); + EXPECT_CALL(mRequestHardwareVsync, Call(kDisplayId, false)); + mVsyncSchedule->disableHardwareVsync(false /* disallow */); } TEST_F(VsyncScheduleTest, EnableDisable2) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); - EXPECT_CALL(mCallback, setVsyncEnabled(DEFAULT_DISPLAY_ID, true)); + EXPECT_CALL(mRequestHardwareVsync, Call(kDisplayId, true)); - mVsyncSchedule->enableHardwareVsync(mCallback); + mVsyncSchedule->enableHardwareVsync(); - EXPECT_CALL(mCallback, setVsyncEnabled(DEFAULT_DISPLAY_ID, false)); - mVsyncSchedule->disableHardwareVsync(mCallback, true /* disallow */); + EXPECT_CALL(mRequestHardwareVsync, Call(kDisplayId, false)); + mVsyncSchedule->disableHardwareVsync(true /* disallow */); } TEST_F(VsyncScheduleTest, StartPeriodTransition) { @@ -159,22 +159,22 @@ TEST_F(VsyncScheduleTest, StartPeriodTransition) { const Period period = (60_Hz).getPeriod(); - EXPECT_CALL(mCallback, setVsyncEnabled(DEFAULT_DISPLAY_ID, true)); + EXPECT_CALL(mRequestHardwareVsync, Call(kDisplayId, true)); EXPECT_CALL(getController(), startPeriodTransition(period.ns(), false)); - mVsyncSchedule->startPeriodTransition(mCallback, period, false); + mVsyncSchedule->startPeriodTransition(period, false); } TEST_F(VsyncScheduleTest, StartPeriodTransitionAlreadyEnabled) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); - mVsyncSchedule->enableHardwareVsync(mCallback); + mVsyncSchedule->enableHardwareVsync(); const Period period = (60_Hz).getPeriod(); - EXPECT_CALL(mCallback, setVsyncEnabled(_, _)).Times(0); + EXPECT_CALL(mRequestHardwareVsync, Call(_, _)).Times(0); EXPECT_CALL(getController(), startPeriodTransition(period.ns(), false)); - mVsyncSchedule->startPeriodTransition(mCallback, period, false); + mVsyncSchedule->startPeriodTransition(period, false); } TEST_F(VsyncScheduleTest, StartPeriodTransitionForce) { @@ -182,20 +182,20 @@ TEST_F(VsyncScheduleTest, StartPeriodTransitionForce) { const Period period = (60_Hz).getPeriod(); - EXPECT_CALL(mCallback, setVsyncEnabled(DEFAULT_DISPLAY_ID, true)); + EXPECT_CALL(mRequestHardwareVsync, Call(kDisplayId, true)); EXPECT_CALL(getController(), startPeriodTransition(period.ns(), true)); - mVsyncSchedule->startPeriodTransition(mCallback, period, true); + mVsyncSchedule->startPeriodTransition(period, true); } TEST_F(VsyncScheduleTest, AddResyncSampleDisallowed) { const Period period = (60_Hz).getPeriod(); const auto timestamp = TimePoint::now(); - EXPECT_CALL(mCallback, setVsyncEnabled(_, _)).Times(0); + EXPECT_CALL(mRequestHardwareVsync, Call(_, _)).Times(0); EXPECT_CALL(getController(), addHwVsyncTimestamp(_, _, _)).Times(0); - mVsyncSchedule->addResyncSample(mCallback, timestamp, period); + mVsyncSchedule->addResyncSample(timestamp, period); } TEST_F(VsyncScheduleTest, AddResyncSampleDisabled) { @@ -203,40 +203,40 @@ TEST_F(VsyncScheduleTest, AddResyncSampleDisabled) { const Period period = (60_Hz).getPeriod(); const auto timestamp = TimePoint::now(); - EXPECT_CALL(mCallback, setVsyncEnabled(_, _)).Times(0); + EXPECT_CALL(mRequestHardwareVsync, Call(_, _)).Times(0); EXPECT_CALL(getController(), addHwVsyncTimestamp(_, _, _)).Times(0); - mVsyncSchedule->addResyncSample(mCallback, timestamp, period); + mVsyncSchedule->addResyncSample(timestamp, period); } TEST_F(VsyncScheduleTest, AddResyncSampleReturnsTrue) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); - mVsyncSchedule->enableHardwareVsync(mCallback); + mVsyncSchedule->enableHardwareVsync(); const Period period = (60_Hz).getPeriod(); const auto timestamp = TimePoint::now(); - EXPECT_CALL(mCallback, setVsyncEnabled(_, _)).Times(0); + EXPECT_CALL(mRequestHardwareVsync, Call(_, _)).Times(0); EXPECT_CALL(getController(), addHwVsyncTimestamp(timestamp.ns(), std::optional<nsecs_t>(period.ns()), _)) .WillOnce(Return(true)); - mVsyncSchedule->addResyncSample(mCallback, timestamp, period); + mVsyncSchedule->addResyncSample(timestamp, period); } TEST_F(VsyncScheduleTest, AddResyncSampleReturnsFalse) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); - mVsyncSchedule->enableHardwareVsync(mCallback); + mVsyncSchedule->enableHardwareVsync(); const Period period = (60_Hz).getPeriod(); const auto timestamp = TimePoint::now(); - EXPECT_CALL(mCallback, setVsyncEnabled(DEFAULT_DISPLAY_ID, false)); + EXPECT_CALL(mRequestHardwareVsync, Call(kDisplayId, false)); EXPECT_CALL(getController(), addHwVsyncTimestamp(timestamp.ns(), std::optional<nsecs_t>(period.ns()), _)) .WillOnce(Return(false)); - mVsyncSchedule->addResyncSample(mCallback, timestamp, period); + mVsyncSchedule->addResyncSample(timestamp, period); } TEST_F(VsyncScheduleTest, PendingState) FTL_FAKE_GUARD(kMainThreadContext) { @@ -250,19 +250,19 @@ TEST_F(VsyncScheduleTest, PendingState) FTL_FAKE_GUARD(kMainThreadContext) { TEST_F(VsyncScheduleTest, DisableDoesNotMakeAllowed) { ASSERT_FALSE(mVsyncSchedule->isHardwareVsyncAllowed(false /* makeAllowed */)); - mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */); + mVsyncSchedule->disableHardwareVsync(false /* disallow */); ASSERT_FALSE(mVsyncSchedule->isHardwareVsyncAllowed(false /* makeAllowed */)); } TEST_F(VsyncScheduleTest, DisallowMakesNotAllowed) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); - mVsyncSchedule->disableHardwareVsync(mCallback, true /* disallow */); + mVsyncSchedule->disableHardwareVsync(true /* disallow */); ASSERT_FALSE(mVsyncSchedule->isHardwareVsyncAllowed(false /* makeAllowed */)); } TEST_F(VsyncScheduleTest, StillAllowedAfterDisable) { ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */)); - mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */); + mVsyncSchedule->disableHardwareVsync(false /* disallow */); ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(false /* makeAllowed */)); } diff --git a/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h b/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h index a8eca2192f..306eb4d845 100644 --- a/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h +++ b/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h @@ -23,14 +23,14 @@ namespace android::scheduler::mock { struct SchedulerCallback final : ISchedulerCallback { - MOCK_METHOD(void, setVsyncEnabled, (PhysicalDisplayId, bool), (override)); + MOCK_METHOD(void, requestHardwareVsync, (PhysicalDisplayId, bool), (override)); MOCK_METHOD(void, requestDisplayModes, (std::vector<display::DisplayModeRequest>), (override)); MOCK_METHOD(void, kernelTimerChanged, (bool), (override)); MOCK_METHOD(void, triggerOnFrameRateOverridesChanged, (), (override)); }; struct NoOpSchedulerCallback final : ISchedulerCallback { - void setVsyncEnabled(PhysicalDisplayId, bool) override {} + void requestHardwareVsync(PhysicalDisplayId, bool) override {} void requestDisplayModes(std::vector<display::DisplayModeRequest>) override {} void kernelTimerChanged(bool) override {} void triggerOnFrameRateOverridesChanged() override {} |