SF: Fix pacesetter promotion for folded mirroring
The pacesetter display is demoted/promoted in response to a hotplug. On
foldables, the promoted display was hard-coded to the inner display, so
a hotplug while folded would incorrectly use that powered-off display as
the pacesetter, causing system-wide jank until the next fold/unfold.
Fixes: 347248313
Flag: EXEMPT bugfix
Test: Connect and disconnect external display while folded.
Test: Fold and unfold while external display is connected.
Test: Pacesetter is still correct on folded/unfolded boot.
Change-Id: Id5cb29c3cbaa8ed455a15d8be3a32e79a470cce5
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index ccaa05f..1a4aa79 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -101,9 +101,16 @@
using ConstVsyncSchedulePtr = std::shared_ptr<const VsyncSchedule>;
using VsyncSchedulePtr = std::shared_ptr<VsyncSchedule>;
- void registerDisplay(PhysicalDisplayId, RefreshRateSelectorPtr) REQUIRES(kMainThreadContext)
+ // After registration/unregistration, `activeDisplayId` is promoted to pacesetter. Note that the
+ // active display is never unregistered, since hotplug disconnect never happens for activatable
+ // displays, i.e. a foldable's internal displays or otherwise the (internal or external) primary
+ // display.
+ // TODO: b/255635821 - Remove active display parameters.
+ void registerDisplay(PhysicalDisplayId, RefreshRateSelectorPtr,
+ PhysicalDisplayId activeDisplayId) REQUIRES(kMainThreadContext)
EXCLUDES(mDisplayLock);
- void unregisterDisplay(PhysicalDisplayId) REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
+ void unregisterDisplay(PhysicalDisplayId, PhysicalDisplayId activeDisplayId)
+ REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
void run();
@@ -390,8 +397,9 @@
// the caller on the main thread to avoid deadlock, since the timer thread locks it before exit.
void demotePacesetterDisplay() REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock, mPolicyLock);
- void registerDisplayInternal(PhysicalDisplayId, RefreshRateSelectorPtr, VsyncSchedulePtr)
- REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
+ void registerDisplayInternal(PhysicalDisplayId, RefreshRateSelectorPtr, VsyncSchedulePtr,
+ PhysicalDisplayId activeDisplayId) REQUIRES(kMainThreadContext)
+ EXCLUDES(mDisplayLock);
struct Policy;