SF: Simplify Scheduler's hardware VSYNC delegate
As a step toward hiding implementation details of how Scheduler handles
changes in a display's power mode (e.g. toggling of hardware/synthetic
VSYNC), move and rename SurfaceFlinger::setVsyncEnabled to Scheduler::
onHardwareVsyncRequest. This hides setPendingHardwareVsyncState.
(getPendingHardwareVsyncState will be moved to Scheduler later.)
Store the per-display hal::PowerMode in Scheduler. On power mode change
in SurfaceFlinger::setPowerModeInternal, update the Scheduler for every
display, not just the active display.
Inject the delegate into VsyncSchedule's constructor, instead of passing
the (partly unrelated) ISchedulerCallback to several member functions.
Bug: 271431077
Bug: 241286146
Bug: 255635821
Bug: 241285191
Test: FoldableTest
Change-Id: I157b0895a77f055763f86dd21602d0dac13622da
diff --git a/services/surfaceflinger/Scheduler/ISchedulerCallback.h b/services/surfaceflinger/Scheduler/ISchedulerCallback.h
index 92c2189..badbf53 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 8e1ac36..41639b6 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -114,8 +114,12 @@
}
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,
@@ -137,7 +141,7 @@
// Disable hardware VSYNC if the registration is new, as opposed to a renewal.
if (isNew) {
- mSchedulerCallback.setVsyncEnabled(displayId, false);
+ onHardwareVsyncRequest(displayId, false);
}
}
@@ -422,13 +426,13 @@
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) {
@@ -455,12 +459,32 @@
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);
@@ -506,18 +530,17 @@
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);
}
}
@@ -581,9 +604,13 @@
}
{
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;
@@ -641,7 +668,7 @@
ftl::FakeGuard guard(kMainThreadContext);
for (const auto& [_, display] : mDisplays) {
constexpr bool kDisallow = false;
- display.schedulePtr->disableHardwareVsync(mSchedulerCallback, kDisallow);
+ display.schedulePtr->disableHardwareVsync(kDisallow);
}
}
@@ -762,8 +789,8 @@
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 d628ac3..17e9cea 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -320,6 +320,9 @@
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 @@
// 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 84671ae..ff3f29d 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 @@
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 @@
: 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 @@
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 @@
}
}
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 9867b41..0757b57 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 @@
namespace android::scheduler {
-struct ISchedulerCallback;
-
// TODO(b/185535769): Rename classes, and remove aliases.
class VSyncDispatch;
class VSyncTracker;
@@ -54,7 +53,9 @@
// 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 @@
// \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 @@
// 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 @@
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 @@
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 @@
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 b258e04..4f14201 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2138,26 +2138,6 @@
}
}
-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 @@
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");
@@ -5404,11 +5388,14 @@
}
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;
@@ -5426,10 +5413,10 @@
mScheduler->enableSyntheticVsync();
}
- // 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) {
@@ -5457,9 +5444,10 @@
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 1db2ab6..040573d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -632,10 +632,7 @@
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 @@
*/
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 acd301e..5c152b5 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
@@ -789,7 +789,7 @@
}
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 55705ca..1b0d892 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -103,12 +103,12 @@
"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 e64cb38..ee12276 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
@@ -371,10 +371,11 @@
// 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 16fa35e..682c998 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -155,16 +155,20 @@
EXPECT_EQ(kEventConnections, mScheduler->getEventThreadConnectionCount(mConnectionHandle));
}
-TEST_F(SchedulerTest, registerDisplay) {
+TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) {
// Hardware VSYNC should not change if the display is already registered.
- EXPECT_CALL(mSchedulerCallback, setVsyncEnabled(kDisplayId1, false)).Times(0);
+ 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, setVsyncEnabled(kDisplayId2, false)).Times(1);
- EXPECT_CALL(mSchedulerCallback, setVsyncEnabled(kDisplayId3, false)).Times(1);
+ 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,
@@ -172,6 +176,10 @@
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) {
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp
new file mode 100644
index 0000000..bd2344c
--- /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 e38f56e..0000000
--- 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 7754c21..cf3fab3 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
@@ -61,7 +61,7 @@
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 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 5d2dfe4..aac11c0 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 @@
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 @@
: 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 4010fa6..a8a3cd0 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 @@
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, 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, 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, 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 @@
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 @@
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 @@
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, 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 a8eca21..306eb4d 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 {}