SF: Dispatch frame rate overrides to pacesetter
...not the active display, though they are the same display in practice
(until pacesetter candidates include external displays).
Remove the Scheduler's round trip through SurfaceFlinger to look up the
active display.
Bug: 255635821
Flag: EXEMPT refactor
Test: adb shell service call SurfaceFlinger 1039 i32 <uid> f 30
Change-Id: I2eb6fe9214dcb6dbdb26676a1dc62207a2a84ba4
diff --git a/services/surfaceflinger/Scheduler/ISchedulerCallback.h b/services/surfaceflinger/Scheduler/ISchedulerCallback.h
index f430526..2b9e88c 100644
--- a/services/surfaceflinger/Scheduler/ISchedulerCallback.h
+++ b/services/surfaceflinger/Scheduler/ISchedulerCallback.h
@@ -28,7 +28,6 @@
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;
virtual void onChoreographerAttached() = 0;
virtual void onExpectedPresentTimePosted(TimePoint, ftl::NonNull<DisplayModePtr>,
Fps renderRate) = 0;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 0cf7bdc..84584a4 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -403,14 +403,20 @@
eventThreadFor(Cycle::Render).enableSyntheticVsync(enable);
}
-void Scheduler::onFrameRateOverridesChanged(Cycle cycle, PhysicalDisplayId displayId) {
- const bool supportsFrameRateOverrideByContent =
- pacesetterSelectorPtr()->supportsAppFrameRateOverrideByContent();
+void Scheduler::onFrameRateOverridesChanged() {
+ const auto [pacesetterId, supportsFrameRateOverrideByContent] = [this] {
+ std::scoped_lock lock(mDisplayLock);
+ const auto pacesetterOpt = pacesetterDisplayLocked();
+ LOG_ALWAYS_FATAL_IF(!pacesetterOpt);
+ const Display& pacesetter = *pacesetterOpt;
+ return std::make_pair(FTL_FAKE_GUARD(kMainThreadContext, *mPacesetterDisplayId),
+ pacesetter.selectorPtr->supportsAppFrameRateOverrideByContent());
+ }();
std::vector<FrameRateOverride> overrides =
mFrameRateOverrideMappings.getAllFrameRateOverrides(supportsFrameRateOverrideByContent);
- eventThreadFor(cycle).onFrameRateOverridesChanged(displayId, std::move(overrides));
+ eventThreadFor(Cycle::Render).onFrameRateOverridesChanged(pacesetterId, std::move(overrides));
}
void Scheduler::onHdcpLevelsChanged(Cycle cycle, PhysicalDisplayId displayId,
@@ -907,9 +913,13 @@
}
}
-bool Scheduler::updateFrameRateOverrides(GlobalSignals consideredSignals, Fps displayRefreshRate) {
- std::scoped_lock lock(mPolicyLock);
- return updateFrameRateOverridesLocked(consideredSignals, displayRefreshRate);
+void Scheduler::updateFrameRateOverrides(GlobalSignals consideredSignals, Fps displayRefreshRate) {
+ const bool changed = (std::scoped_lock(mPolicyLock),
+ updateFrameRateOverridesLocked(consideredSignals, displayRefreshRate));
+
+ if (changed) {
+ onFrameRateOverridesChanged();
+ }
}
bool Scheduler::updateFrameRateOverridesLocked(GlobalSignals consideredSignals,
@@ -1157,7 +1167,7 @@
updateFrameRateOverridesLocked(consideredSignals, mPolicy.modeOpt->fps);
}
if (frameRateOverridesChanged) {
- mSchedulerCallback.triggerOnFrameRateOverridesChanged();
+ onFrameRateOverridesChanged();
}
return consideredSignals;
}
@@ -1257,6 +1267,8 @@
} else {
mFrameRateOverrideMappings.setGameModeRefreshRateForUid(frameRateOverride);
}
+
+ onFrameRateOverridesChanged();
}
void Scheduler::setGameDefaultFrameRateForUid(FrameRateOverride frameRateOverride) {
@@ -1275,6 +1287,7 @@
}
mFrameRateOverrideMappings.setPreferredRefreshRateForUid(frameRateOverride);
+ onFrameRateOverridesChanged();
}
void Scheduler::updateSmallAreaDetection(
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 94583db..e1f4d20 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -159,8 +159,6 @@
void enableSyntheticVsync(bool = true) REQUIRES(kMainThreadContext);
- void onFrameRateOverridesChanged(Cycle, PhysicalDisplayId);
-
void onHdcpLevelsChanged(Cycle, PhysicalDisplayId, int32_t, int32_t);
// Modifies work duration in the event thread.
@@ -326,7 +324,7 @@
return mLayerHistory.getLayerFramerate(now, id);
}
- bool updateFrameRateOverrides(GlobalSignals, Fps displayRefreshRate) EXCLUDES(mPolicyLock);
+ void updateFrameRateOverrides(GlobalSignals, Fps displayRefreshRate) EXCLUDES(mPolicyLock);
// Returns true if the small dirty detection is enabled for the appId.
bool supportSmallDirtyDetection(int32_t appId) {
@@ -450,6 +448,9 @@
bool updateFrameRateOverridesLocked(GlobalSignals, Fps displayRefreshRate)
REQUIRES(mPolicyLock);
+
+ void onFrameRateOverridesChanged();
+
void updateAttachedChoreographers(const surfaceflinger::frontend::LayerHierarchy&,
Fps displayRefreshRate);
int updateAttachedChoreographersInternal(const surfaceflinger::frontend::LayerHierarchy&,