SF: Disable hardware VSYNC for any new display
Remove the special case for the primary display.
Bug: 271431077
Bug: 241286146
Bug: 241285191
Test: SchedulerTest.registerDisplay
Change-Id: I5c85852208972da7a82998f283283004ed15386b
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 6d40893..8e1ac36 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -123,14 +123,22 @@
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;
- pacesetterVsyncSchedule = promotePacesetterDisplayLocked();
- }
+ return std::make_pair(promotePacesetterDisplayLocked(), isNew);
+ }();
+
applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
+
+ // Disable hardware VSYNC if the registration is new, as opposed to a renewal.
+ if (isNew) {
+ mSchedulerCallback.setVsyncEnabled(displayId, false);
+ }
}
void Scheduler::unregisterDisplay(PhysicalDisplayId displayId) {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a5f4286..b258e04 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3869,8 +3869,6 @@
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();
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 965e378..16fa35e 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -155,6 +155,25 @@
EXPECT_EQ(kEventConnections, mScheduler->getEventThreadConnectionCount(mConnectionHandle));
}
+TEST_F(SchedulerTest, registerDisplay) {
+ // Hardware VSYNC should not change if the display is already registered.
+ EXPECT_CALL(mSchedulerCallback, setVsyncEnabled(kDisplayId1, false)).Times(0);
+ mScheduler->registerDisplay(kDisplayId1,
+ std::make_shared<RefreshRateSelector>(kDisplay1Modes,
+ kDisplay1Mode60->getId()));
+
+ // 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);
+
+ mScheduler->registerDisplay(kDisplayId2,
+ std::make_shared<RefreshRateSelector>(kDisplay2Modes,
+ kDisplay2Mode60->getId()));
+ mScheduler->registerDisplay(kDisplayId3,
+ std::make_shared<RefreshRateSelector>(kDisplay3Modes,
+ kDisplay3Mode60->getId()));
+}
+
TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) {
// The layer is registered at creation time and deregistered at destruction time.
sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());