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/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());
}