Move HwVsyncState into VsyncSchedule
In preparation for having a separate schedule per display, pull state
which is logically for a single display into VsyncSchedule. This should
be a pure refactor.
Consolidate mPrimaryHWVsyncEnabled and mHWVsyncAvailable (now in
VsyncSchedule) into a single enum which better captures the possible
states. Move SF's record of the pending HWC VSYNC state into the same
place, so it sits with other related logic. Remove the last HWC
VSYNC state, which did not affect behavior.
Move ISchedulerCallback into its own file, so that VsyncSchedule.cpp
doesn't need to depend on Scheduler.h.
Rename variables `makeUnavailable` and `makeAvailable` for clarity.
Make addResyncSample return a boolean, instead of void with an out
parameter.
Remove VsyncSchedule's move constructor. Now that it has a mutex, it is
no longer thread-safe. We don't actually need to move it anyway. Replace
std::optional with std::unique_ptr for owning a VsyncSchedule.
Factored out of If60218e85292c786b9fa70ecb33ee374d3a385e0. Relevant
differences from that patch:
- There is still only one VsyncSchedule.
- When SF turns off a display, we still disable vsync on that display.
In If60218e85292c786b9fa70ecb33ee374d3a385e0, this was redundant with
the call to disableHardwareVsync shortly before it, but right now we
only call disableHardwareVsync for the active display.
- Hold the VSYNC lock for more time in resyncToHaredwareVsync. This
better matches the original behavior.
- Remove mLastHwVsyncState.
- Recreate the code for storing and setting the pending VSYNC state.
- Inline setVsyncPeriod at its only call-site.
Bug: 255601557
Bug: 256196556
Bug: 241286146
Fixes: 266712910
Test: libsurfaceflinger_unittest
Change-Id: I54a1304a3428968134cc707b24d5b325927c31df
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 5fc250b..d1f6e87 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -155,7 +155,7 @@
}
void Scheduler::createVsyncSchedule(FeatureFlags features) {
- mVsyncSchedule.emplace(features);
+ mVsyncSchedule = std::make_unique<VsyncSchedule>(features);
}
std::optional<Fps> Scheduler::getFrameRateOverride(uid_t uid) const {
@@ -393,38 +393,17 @@
}
void Scheduler::enableHardwareVsync() {
- std::lock_guard<std::mutex> lock(mHWVsyncLock);
- if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
- mVsyncSchedule->getTracker().resetModel();
- mSchedulerCallback.setVsyncEnabled(true);
- mPrimaryHWVsyncEnabled = true;
- }
+ mVsyncSchedule->enableHardwareVsync(mSchedulerCallback);
}
-void Scheduler::disableHardwareVsync(bool makeUnavailable) {
- std::lock_guard<std::mutex> lock(mHWVsyncLock);
- if (mPrimaryHWVsyncEnabled) {
- mSchedulerCallback.setVsyncEnabled(false);
- mPrimaryHWVsyncEnabled = false;
- }
- if (makeUnavailable) {
- mHWVsyncAvailable = false;
- }
+void Scheduler::disableHardwareVsync(bool disallow) {
+ mVsyncSchedule->disableHardwareVsync(mSchedulerCallback, disallow);
}
-void Scheduler::resyncToHardwareVsync(bool makeAvailable, Fps refreshRate) {
- {
- std::lock_guard<std::mutex> lock(mHWVsyncLock);
- if (makeAvailable) {
- mHWVsyncAvailable = makeAvailable;
- } else if (!mHWVsyncAvailable) {
- // Hardware vsync is not currently available, so abort the resync
- // attempt for now
- return;
- }
+void Scheduler::resyncToHardwareVsync(bool allowToEnable, Fps refreshRate) {
+ if (mVsyncSchedule->isHardwareVsyncAllowed(allowToEnable) && refreshRate.isValid()) {
+ mVsyncSchedule->startPeriodTransition(mSchedulerCallback, refreshRate.getPeriod());
}
-
- setVsyncPeriod(refreshRate.getPeriodNsecs());
}
void Scheduler::setRenderRate(Fps renderFrameRate) {
@@ -457,37 +436,12 @@
}
}
-void Scheduler::setVsyncPeriod(nsecs_t period) {
- if (period <= 0) return;
-
- std::lock_guard<std::mutex> lock(mHWVsyncLock);
- mVsyncSchedule->getController().startPeriodTransition(period);
-
- if (!mPrimaryHWVsyncEnabled) {
- mVsyncSchedule->getTracker().resetModel();
- mSchedulerCallback.setVsyncEnabled(true);
- mPrimaryHWVsyncEnabled = true;
- }
-}
-
-void Scheduler::addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
- bool* periodFlushed) {
- bool needsHwVsync = false;
- *periodFlushed = false;
- { // Scope for the lock
- std::lock_guard<std::mutex> lock(mHWVsyncLock);
- if (mPrimaryHWVsyncEnabled) {
- needsHwVsync =
- mVsyncSchedule->getController().addHwVsyncTimestamp(timestamp, hwcVsyncPeriod,
- periodFlushed);
- }
- }
-
- if (needsHwVsync) {
- enableHardwareVsync();
- } else {
- disableHardwareVsync(false);
- }
+bool Scheduler::addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriodIn) {
+ const auto hwcVsyncPeriod = ftl::Optional(hwcVsyncPeriodIn).transform([](nsecs_t nanos) {
+ return Period::fromNs(nanos);
+ });
+ return mVsyncSchedule->addResyncSample(mSchedulerCallback, TimePoint::fromNs(timestamp),
+ hwcVsyncPeriod);
}
void Scheduler::addPresentFence(std::shared_ptr<FenceTime> fence) {
@@ -635,14 +589,6 @@
mFrameRateOverrideMappings.dump(dumper);
dumper.eol();
-
- {
- utils::Dumper::Section section(dumper, "Hardware VSYNC"sv);
-
- std::lock_guard lock(mHWVsyncLock);
- dumper.dump("hwVsyncAvailable"sv, mHWVsyncAvailable);
- dumper.dump("hwVsyncEnabled"sv, mPrimaryHWVsyncEnabled);
- }
}
void Scheduler::dumpVsync(std::string& out) const {