Revert "Create a VsyncSchedule per display"
This reverts commit 31d41415101ff3483ce1cc5a9c2ef322490a05bd.
Conflicts:
services/surfaceflinger/Scheduler/EventThread.cpp
services/surfaceflinger/SurfaceFlinger.cpp
Bug: 267562341
Test: ARC Regression Dashboard
Change-Id: I0757a7df540fad316b2db42e4c77f1c73bc49420
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a0c3eb0..169e101 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1130,33 +1130,21 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& displayToken,
- DisplayStatInfo* outStats) {
+status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>&, DisplayStatInfo* outStats) {
if (!outStats) {
return BAD_VALUE;
}
- std::optional<PhysicalDisplayId> displayIdOpt;
- {
- Mutex::Autolock lock(mStateLock);
- displayIdOpt = getPhysicalDisplayIdLocked(displayToken);
- }
-
- if (!displayIdOpt) {
- ALOGE("%s: Invalid physical display token %p", __func__, displayToken.get());
- return NAME_NOT_FOUND;
- }
- const auto schedule = mScheduler->getVsyncSchedule(displayIdOpt);
- outStats->vsyncTime = schedule->vsyncDeadlineAfter(TimePoint::now()).ns();
- outStats->vsyncPeriod = schedule->period().ns();
+ const auto& schedule = mScheduler->getVsyncSchedule();
+ outStats->vsyncTime = schedule.vsyncDeadlineAfter(TimePoint::now()).ns();
+ outStats->vsyncPeriod = schedule.period().ns();
return NO_ERROR;
}
void SurfaceFlinger::setDesiredActiveMode(display::DisplayModeRequest&& request, bool force) {
ATRACE_CALL();
- const auto displayId = request.mode.modePtr->getPhysicalDisplayId();
- const auto display = getDisplayDeviceLocked(displayId);
+ auto display = getDisplayDeviceLocked(request.mode.modePtr->getPhysicalDisplayId());
if (!display) {
ALOGW("%s: display is no longer valid", __func__);
return;
@@ -1169,25 +1157,23 @@
force)) {
case DisplayDevice::DesiredActiveModeAction::InitiateDisplayModeSwitch:
// Set the render rate as setDesiredActiveMode updated it.
- mScheduler->setRenderRate(displayId,
- display->refreshRateSelector().getActiveMode().fps);
+ mScheduler->setRenderRate(display->refreshRateSelector().getActiveMode().fps);
// Schedule a new frame to initiate the display mode switch.
scheduleComposite(FrameHint::kNone);
// Start receiving vsync samples now, so that we can detect a period
// switch.
- mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */,
- mode.modePtr->getFps());
-
+ mScheduler->resyncToHardwareVsync(true, mode.modePtr->getFps());
// As we called to set period, we will call to onRefreshRateChangeCompleted once
// VsyncController model is locked.
- mScheduler->modulateVsync(displayId, &VsyncModulator::onRefreshRateChangeInitiated);
+ mScheduler->modulateVsync(&VsyncModulator::onRefreshRateChangeInitiated);
+
updatePhaseConfiguration(mode.fps);
mScheduler->setModeChangePending(true);
break;
case DisplayDevice::DesiredActiveModeAction::InitiateRenderRateSwitch:
- mScheduler->setRenderRate(displayId, mode.fps);
+ mScheduler->setRenderRate(mode.fps);
updatePhaseConfiguration(mode.fps);
mRefreshRateStats->setRefreshRate(mode.fps);
if (display->getPhysicalId() == mActiveDisplayId && emitEvent) {
@@ -1303,14 +1289,11 @@
}
void SurfaceFlinger::desiredActiveModeChangeDone(const sp<DisplayDevice>& display) {
- const auto desiredActiveMode = display->getDesiredActiveMode();
- const auto& modeOpt = desiredActiveMode->modeOpt;
- const auto displayId = modeOpt->modePtr->getPhysicalDisplayId();
- const auto displayFps = modeOpt->modePtr->getFps();
- const auto renderFps = modeOpt->fps;
+ const auto displayFps = display->getDesiredActiveMode()->modeOpt->modePtr->getFps();
+ const auto renderFps = display->getDesiredActiveMode()->modeOpt->fps;
clearDesiredActiveModeState(display);
- mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */, displayFps);
- mScheduler->setRenderRate(displayId, renderFps);
+ mScheduler->resyncToHardwareVsync(true, displayFps);
+ mScheduler->setRenderRate(renderFps);
updatePhaseConfiguration(renderFps);
}
@@ -2047,11 +2030,21 @@
ATRACE_FORMAT("onComposerHalVsync%s", tracePeriod.c_str());
Mutex::Autolock lock(mStateLock);
- if (const auto displayIdOpt = getHwComposer().onVsync(hwcDisplayId, timestamp)) {
- if (mScheduler->addResyncSample(*displayIdOpt, timestamp, vsyncPeriod)) {
- // period flushed
- mScheduler->modulateVsync(displayIdOpt, &VsyncModulator::onRefreshRateChangeCompleted);
- }
+
+ if (!getHwComposer().onVsync(hwcDisplayId, timestamp)) {
+ return;
+ }
+
+ if (const auto displayId = getHwComposer().toPhysicalDisplayId(hwcDisplayId);
+ displayId != mActiveDisplayId) {
+ // For now, we don't do anything with non active display vsyncs.
+ return;
+ }
+
+ bool periodFlushed = false;
+ mScheduler->addResyncSample(timestamp, vsyncPeriod, &periodFlushed);
+ if (periodFlushed) {
+ mScheduler->modulateVsync(&VsyncModulator::onRefreshRateChangeCompleted);
}
}
@@ -2092,15 +2085,16 @@
mScheduler->forceNextResync();
}
-void SurfaceFlinger::setVsyncEnabled(PhysicalDisplayId id, bool enabled) {
- const char* const whence = __func__;
- ATRACE_FORMAT("%s (%d) for %" PRIu64, whence, enabled, id.value);
+void SurfaceFlinger::setVsyncEnabled(bool enabled) {
+ ATRACE_CALL();
// On main thread to avoid race conditions with display power state.
static_cast<void>(mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) {
- ATRACE_FORMAT("%s (%d) for %" PRIu64 " (main thread)", whence, enabled, id.value);
- if (const auto display = getDisplayDeviceLocked(id); display && display->isPoweredOn()) {
- setHWCVsyncEnabled(id, enabled);
+ mHWCVsyncPendingState = enabled ? hal::Vsync::ENABLE : hal::Vsync::DISABLE;
+
+ if (const auto display = getDefaultDisplayDeviceLocked();
+ display && display->isPoweredOn()) {
+ setHWCVsyncEnabled(display->getPhysicalId(), mHWCVsyncPendingState);
}
}));
}
@@ -2127,13 +2121,13 @@
TimePoint SurfaceFlinger::calculateExpectedPresentTime(TimePoint frameTime) const {
const auto& schedule = mScheduler->getVsyncSchedule();
- const TimePoint vsyncDeadline = schedule->vsyncDeadlineAfter(frameTime);
+ const TimePoint vsyncDeadline = schedule.vsyncDeadlineAfter(frameTime);
if (mScheduler->vsyncModulator().getVsyncConfig().sfOffset > 0) {
return vsyncDeadline;
}
// Inflate the expected present time if we're targeting the next vsync.
- return vsyncDeadline + schedule->period();
+ return vsyncDeadline + schedule.period();
}
void SurfaceFlinger::configure() FTL_FAKE_GUARD(kMainThreadContext) {
@@ -2264,7 +2258,7 @@
ticks<std::milli, float>(mExpectedPresentTime - TimePoint::now()),
mExpectedPresentTime == expectedVsyncTime ? "" : " (adjusted)");
- const Period vsyncPeriod = mScheduler->getVsyncSchedule()->period();
+ const Period vsyncPeriod = mScheduler->getVsyncSchedule().period();
const FenceTimePtr& previousPresentFence = getPreviousPresentFence(frameTime, vsyncPeriod);
// When backpressure propagation is enabled, we want to give a small grace period of 1ms
@@ -2514,7 +2508,7 @@
refreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::milliseconds(mDebugFlashDelay);
}
- const auto prevVsyncTime = mExpectedPresentTime - mScheduler->getVsyncSchedule()->period();
+ const auto prevVsyncTime = mExpectedPresentTime - mScheduler->getVsyncSchedule().period();
const auto hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration;
refreshArgs.earliestPresentTime = prevVsyncTime - hwcMinWorkDuration;
@@ -2596,7 +2590,7 @@
// TODO(b/160583065): Enable skip validation when SF caches all client composition layers.
const bool hasGpuUseOrReuse =
mCompositionCoverage.any(CompositionCoverage::Gpu | CompositionCoverage::GpuReuse);
- mScheduler->modulateVsync({}, &VsyncModulator::onDisplayRefresh, hasGpuUseOrReuse);
+ mScheduler->modulateVsync(&VsyncModulator::onDisplayRefresh, hasGpuUseOrReuse);
mLayersWithQueuedFrames.clear();
if (mLayerTracingEnabled && mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) {
@@ -2740,9 +2734,9 @@
? mPresentLatencyTracker.trackPendingFrame(compositeTime, presentFenceTime)
: Duration::zero();
- const auto schedule = mScheduler->getVsyncSchedule();
- const TimePoint vsyncDeadline = schedule->vsyncDeadlineAfter(presentTime);
- const Period vsyncPeriod = schedule->period();
+ const auto& schedule = mScheduler->getVsyncSchedule();
+ const TimePoint vsyncDeadline = schedule.vsyncDeadlineAfter(presentTime);
+ const Period vsyncPeriod = schedule.period();
const nsecs_t vsyncPhase = mVsyncConfiguration->getCurrentConfigs().late.sfOffset;
const CompositorTiming compositorTiming(vsyncDeadline.ns(), vsyncPeriod.ns(), vsyncPhase,
@@ -2817,19 +2811,15 @@
mTimeStats->incrementTotalFrames();
mTimeStats->setPresentFenceGlobal(presentFenceTime);
- {
- ftl::FakeGuard guard(mStateLock);
- for (const auto& [id, physicalDisplay] : mPhysicalDisplays) {
- if (auto displayDevice = getDisplayDeviceLocked(id);
- displayDevice && displayDevice->isPoweredOn() && physicalDisplay.isInternal()) {
- auto presentFenceTimeI = defaultDisplay && defaultDisplay->getPhysicalId() == id
- ? std::move(presentFenceTime)
- : std::make_shared<FenceTime>(getHwComposer().getPresentFence(id));
- if (presentFenceTimeI->isValid()) {
- mScheduler->addPresentFence(id, std::move(presentFenceTimeI));
- }
- }
- }
+ const bool isInternalDisplay = defaultDisplay &&
+ FTL_FAKE_GUARD(mStateLock, mPhysicalDisplays)
+ .get(defaultDisplay->getPhysicalId())
+ .transform(&PhysicalDisplay::isInternal)
+ .value_or(false);
+
+ if (isInternalDisplay && defaultDisplay && defaultDisplay->getPowerMode() == hal::PowerMode::ON &&
+ presentFenceTime->isValid()) {
+ mScheduler->addPresentFence(std::move(presentFenceTime));
}
const bool isDisplayConnected =
@@ -2837,7 +2827,7 @@
if (!hasSyncFramework) {
if (isDisplayConnected && defaultDisplay->isPoweredOn()) {
- mScheduler->enableHardwareVsync(defaultDisplay->getPhysicalId());
+ mScheduler->enableHardwareVsync();
}
}
@@ -2948,7 +2938,7 @@
// so we can call commitTransactionsLocked unconditionally.
// We clear the flags with mStateLock held to guarantee that
// mCurrentState won't change until the transaction is committed.
- mScheduler->modulateVsync({}, &VsyncModulator::onTransactionCommit);
+ mScheduler->modulateVsync(&VsyncModulator::onTransactionCommit);
commitTransactionsLocked(clearTransactionFlags(eTransactionMask));
mDebugInTransaction = 0;
@@ -3787,9 +3777,10 @@
mScheduler = std::make_unique<Scheduler>(static_cast<ICompositor&>(*this),
static_cast<ISchedulerCallback&>(*this), features,
std::move(modulatorPtr));
+ mScheduler->createVsyncSchedule(features);
mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector());
- setVsyncEnabled(display->getPhysicalId(), false);
+ setVsyncEnabled(false);
mScheduler->startTimers();
const auto configs = mVsyncConfiguration->getCurrentConfigs();
@@ -3805,7 +3796,7 @@
/* workDuration */ activeRefreshRate.getPeriod(),
/* readyDuration */ configs.late.sfWorkDuration);
- mScheduler->initVsync(mScheduler->getVsyncSchedule()->getDispatch(),
+ mScheduler->initVsync(mScheduler->getVsyncSchedule().getDispatch(),
*mFrameTimeline->getTokenManager(), configs.late.sfWorkDuration);
mRegionSamplingThread =
@@ -4019,7 +4010,7 @@
void SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule schedule,
const sp<IBinder>& applyToken, FrameHint frameHint) {
- mScheduler->modulateVsync({}, &VsyncModulator::setTransactionSchedule, schedule, applyToken);
+ mScheduler->modulateVsync(&VsyncModulator::setTransactionSchedule, schedule, applyToken);
uint32_t transactionFlags = mTransactionFlags.fetch_or(mask);
ATRACE_INT("mTransactionFlags", transactionFlags);
@@ -4048,7 +4039,7 @@
return TransactionReadiness::NotReady;
}
- if (!mScheduler->isVsyncTargetForUid(mExpectedPresentTime, transaction.originUid)) {
+ if (!mScheduler->isVsyncValid(mExpectedPresentTime, transaction.originUid)) {
ATRACE_NAME("!isVsyncValid");
return TransactionReadiness::NotReady;
}
@@ -4192,7 +4183,7 @@
return false;
}
- const Duration earlyLatchVsyncThreshold = mScheduler->getVsyncSchedule()->period() / 2;
+ const Duration earlyLatchVsyncThreshold = mScheduler->getVsyncSchedule().period() / 2;
return predictedPresentTime >= expectedPresentTime &&
predictedPresentTime - expectedPresentTime >= earlyLatchVsyncThreshold;
@@ -5233,11 +5224,10 @@
ALOGW("Couldn't set SCHED_FIFO on display on: %s\n", strerror(errno));
}
getHwComposer().setPowerMode(displayId, mode);
- if (mode != hal::PowerMode::DOZE_SUSPEND) {
- if (isActiveDisplay) {
- mScheduler->onScreenAcquired(mAppConnectionHandle);
- }
- mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */, refreshRate);
+ if (isActiveDisplay && mode != hal::PowerMode::DOZE_SUSPEND) {
+ setHWCVsyncEnabled(displayId, mHWCVsyncPendingState);
+ mScheduler->onScreenAcquired(mAppConnectionHandle);
+ mScheduler->resyncToHardwareVsync(true, refreshRate);
}
mVisibleRegionsDirty = true;
@@ -5250,34 +5240,33 @@
if (SurfaceFlinger::setSchedAttr(false) != NO_ERROR) {
ALOGW("Couldn't set uclamp.min on display off: %s\n", strerror(errno));
}
- if (*currentModeOpt != hal::PowerMode::DOZE_SUSPEND) {
- mScheduler->disableHardwareVsync(displayId, true);
- if (isActiveDisplay) {
- mScheduler->onScreenReleased(mAppConnectionHandle);
- }
+ if (isActiveDisplay && *currentModeOpt != hal::PowerMode::DOZE_SUSPEND) {
+ mScheduler->disableHardwareVsync(true);
+ mScheduler->onScreenReleased(mAppConnectionHandle);
}
+ // Make sure HWVsync is disabled before turning off the display
+ setHWCVsyncEnabled(displayId, hal::Vsync::DISABLE);
+
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) {
// Update display while dozing
getHwComposer().setPowerMode(displayId, mode);
- if (*currentModeOpt == hal::PowerMode::DOZE_SUSPEND) {
- if (isActiveDisplay) {
- mScheduler->onScreenAcquired(mAppConnectionHandle);
- }
+ if (isActiveDisplay && *currentModeOpt == hal::PowerMode::DOZE_SUSPEND) {
ALOGI("Force repainting for DOZE_SUSPEND -> DOZE or ON.");
mVisibleRegionsDirty = true;
scheduleRepaint();
- mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */, refreshRate);
+ mScheduler->onScreenAcquired(mAppConnectionHandle);
+ mScheduler->resyncToHardwareVsync(true, refreshRate);
}
} else if (mode == hal::PowerMode::DOZE_SUSPEND) {
// Leave display going to doze
if (isActiveDisplay) {
+ mScheduler->disableHardwareVsync(true);
mScheduler->onScreenReleased(mAppConnectionHandle);
}
- mScheduler->disableHardwareVsync(displayId, true);
getHwComposer().setPowerMode(displayId, mode);
} else {
ALOGE("Attempting to set unknown power mode: %d\n", mode);
@@ -5287,8 +5276,8 @@
if (isActiveDisplay) {
mTimeStats->setPowerMode(mode);
mRefreshRateStats->setPowerMode(mode);
+ mScheduler->setDisplayPowerMode(mode);
}
- mScheduler->setDisplayPowerMode(displayId, mode);
ALOGD("Finished setting power mode %d on display %s", mode, to_string(displayId).c_str());
}
@@ -5466,6 +5455,14 @@
mScheduler->dump(dumper);
+ // TODO(b/241286146): Move to Scheduler.
+ {
+ utils::Dumper::Indent indent(dumper);
+ dumper.dump("lastHwcVsyncState"sv, mLastHWCVsyncState);
+ dumper.dump("pendingHwcVsyncState"sv, mHWCVsyncPendingState);
+ }
+ dumper.eol();
+
// TODO(b/241285876): Move to DisplayModeController.
dumper.dump("debugDisplayModeSetByBackdoor"sv, mDebugDisplayModeSetByBackdoor);
dumper.eol();