SF: move VSyncTracker and VSyncDispatch ownership to Scheduler
This is a first change towards removing the old DispSync interface
for VSyncReactor. This change allows Scheduler to use VSyncTracker and
VSyncDispatch directly to schedule work-based vsync callback rather than
periodic, to get better control on scheduling app / sf vsync callbacks.
Test: adb shell /data/nativetest64/libsurfaceflinger_unittest/libsurfaceflinger_unittest
Change-Id: I81637bf458337b03489faa580a79afa05f47c6c8
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index ab63d64..98d2478 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -61,36 +61,46 @@
} while (false)
namespace android {
+
namespace {
-std::unique_ptr<DispSync> createDispSync(bool supportKernelTimer) {
- // TODO (140302863) remove this and use the vsync_reactor system.
- if (property_get_bool("debug.sf.vsync_reactor", true)) {
+std::unique_ptr<scheduler::VSyncTracker> createVSyncTracker() {
+ // TODO (144707443) tune Predictor tunables.
+ static constexpr int default_rate = 60;
+ static constexpr auto initial_period =
+ std::chrono::duration<nsecs_t, std::ratio<1, default_rate>>(1);
+ static constexpr size_t vsyncTimestampHistorySize = 20;
+ static constexpr size_t minimumSamplesForPrediction = 6;
+ static constexpr uint32_t discardOutlierPercent = 20;
+ return std::make_unique<
+ scheduler::VSyncPredictor>(std::chrono::duration_cast<std::chrono::nanoseconds>(
+ initial_period)
+ .count(),
+ vsyncTimestampHistorySize, minimumSamplesForPrediction,
+ discardOutlierPercent);
+}
+
+std::unique_ptr<scheduler::VSyncDispatch> createVSyncDispatch(
+ const std::unique_ptr<scheduler::VSyncTracker>& vSyncTracker) {
+ if (!vSyncTracker) return {};
+
+ // TODO (144707443) tune Predictor tunables.
+ static constexpr auto vsyncMoveThreshold =
+ std::chrono::duration_cast<std::chrono::nanoseconds>(3ms);
+ static constexpr auto timerSlack = std::chrono::duration_cast<std::chrono::nanoseconds>(500us);
+ return std::make_unique<
+ scheduler::VSyncDispatchTimerQueue>(std::make_unique<scheduler::Timer>(), *vSyncTracker,
+ timerSlack.count(), vsyncMoveThreshold.count());
+}
+
+std::unique_ptr<DispSync> createDispSync(
+ const std::unique_ptr<scheduler::VSyncTracker>& vSyncTracker,
+ const std::unique_ptr<scheduler::VSyncDispatch>& vSyncDispatch, bool supportKernelTimer) {
+ if (vSyncTracker && vSyncDispatch) {
// TODO (144707443) tune Predictor tunables.
- static constexpr int defaultRate = 60;
- static constexpr auto initialPeriod =
- std::chrono::duration<nsecs_t, std::ratio<1, defaultRate>>(1);
- static constexpr size_t vsyncTimestampHistorySize = 20;
- static constexpr size_t minimumSamplesForPrediction = 6;
- static constexpr uint32_t discardOutlierPercent = 20;
- auto tracker = std::make_unique<
- scheduler::VSyncPredictor>(std::chrono::duration_cast<std::chrono::nanoseconds>(
- initialPeriod)
- .count(),
- vsyncTimestampHistorySize, minimumSamplesForPrediction,
- discardOutlierPercent);
-
- static constexpr auto vsyncMoveThreshold =
- std::chrono::duration_cast<std::chrono::nanoseconds>(3ms);
- static constexpr auto timerSlack =
- std::chrono::duration_cast<std::chrono::nanoseconds>(500us);
- auto dispatch = std::make_unique<
- scheduler::VSyncDispatchTimerQueue>(std::make_unique<scheduler::Timer>(), *tracker,
- timerSlack.count(), vsyncMoveThreshold.count());
-
static constexpr size_t pendingFenceLimit = 20;
return std::make_unique<scheduler::VSyncReactor>(std::make_unique<scheduler::SystemClock>(),
- std::move(dispatch), std::move(tracker),
+ *vSyncDispatch, *vSyncTracker,
pendingFenceLimit, supportKernelTimer);
} else {
return std::make_unique<impl::DispSync>("SchedulerDispSync",
@@ -110,7 +120,11 @@
ISchedulerCallback& schedulerCallback, bool useContentDetectionV2,
bool useContentDetection)
: mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)),
- mPrimaryDispSync(createDispSync(mSupportKernelTimer)),
+ // TODO (140302863) remove this and use the vsync_reactor system.
+ mUseVsyncPredictor(property_get_bool("debug.sf.vsync_reactor", true)),
+ mVSyncTracker(mUseVsyncPredictor ? createVSyncTracker() : nullptr),
+ mVSyncDispatch(createVSyncDispatch(mVSyncTracker)),
+ mPrimaryDispSync(createDispSync(mVSyncTracker, mVSyncDispatch, mSupportKernelTimer)),
mEventControlThread(new impl::EventControlThread(std::move(function))),
mLayerHistory(createLayerHistory(refreshRateConfigs, useContentDetectionV2)),
mSchedulerCallback(schedulerCallback),
@@ -156,6 +170,7 @@
std::unique_ptr<LayerHistory> layerHistory, bool useContentDetectionV2,
bool useContentDetection)
: mSupportKernelTimer(false),
+ mUseVsyncPredictor(true),
mPrimaryDispSync(std::move(primaryDispSync)),
mEventControlThread(std::move(eventControlThread)),
mLayerHistory(std::move(layerHistory)),
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 5fee4b4..2fe5629 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -44,7 +44,11 @@
class DispSync;
class FenceTime;
class InjectVSyncSource;
-struct DisplayStateInfo;
+
+namespace scheduler {
+class VSyncDispatch;
+class VSyncTracker;
+} // namespace scheduler
class ISchedulerCallback {
public:
@@ -230,6 +234,9 @@
// Whether to use idle timer callbacks that support the kernel timer.
const bool mSupportKernelTimer;
+ const bool mUseVsyncPredictor;
+ const std::unique_ptr<scheduler::VSyncTracker> mVSyncTracker;
+ const std::unique_ptr<scheduler::VSyncDispatch> mVSyncDispatch;
std::unique_ptr<DispSync> mPrimaryDispSync;
std::unique_ptr<EventControlThread> mEventControlThread;
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index efa8bab..a2b279b 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -55,15 +55,15 @@
}
};
-VSyncReactor::VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch,
- std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit,
+VSyncReactor::VSyncReactor(std::unique_ptr<Clock> clock, VSyncDispatch& dispatch,
+ VSyncTracker& tracker, size_t pendingFenceLimit,
bool supportKernelIdleTimer)
: mClock(std::move(clock)),
- mTracker(std::move(tracker)),
- mDispatch(std::move(dispatch)),
+ mTracker(tracker),
+ mDispatch(dispatch),
mPendingLimit(pendingFenceLimit),
mPredictedVsyncTracer(property_get_bool("debug.sf.show_predicted_vsync", false)
- ? std::make_unique<PredictedVsyncTracer>(*mDispatch)
+ ? std::make_unique<PredictedVsyncTracer>(mDispatch)
: nullptr),
mSupportKernelIdleTimer(supportKernelIdleTimer) {}
@@ -182,7 +182,7 @@
} else if (time == Fence::SIGNAL_TIME_INVALID) {
it = mUnfiredFences.erase(it);
} else {
- timestampAccepted &= mTracker->addVsyncTimestamp(time);
+ timestampAccepted &= mTracker.addVsyncTimestamp(time);
it = mUnfiredFences.erase(it);
}
@@ -194,7 +194,7 @@
}
mUnfiredFences.push_back(fence);
} else {
- timestampAccepted &= mTracker->addVsyncTimestamp(signalTime);
+ timestampAccepted &= mTracker.addVsyncTimestamp(signalTime);
}
if (!timestampAccepted) {
@@ -224,12 +224,12 @@
}
nsecs_t VSyncReactor::computeNextRefresh(int periodOffset, nsecs_t now) const {
- auto const currentPeriod = periodOffset ? mTracker->currentPeriod() : 0;
- return mTracker->nextAnticipatedVSyncTimeFrom(now + periodOffset * currentPeriod);
+ auto const currentPeriod = periodOffset ? mTracker.currentPeriod() : 0;
+ return mTracker.nextAnticipatedVSyncTimeFrom(now + periodOffset * currentPeriod);
}
nsecs_t VSyncReactor::expectedPresentTime(nsecs_t now) {
- return mTracker->nextAnticipatedVSyncTimeFrom(now);
+ return mTracker.nextAnticipatedVSyncTimeFrom(now);
}
void VSyncReactor::startPeriodTransition(nsecs_t newPeriod) {
@@ -262,11 +262,11 @@
}
nsecs_t VSyncReactor::getPeriod() {
- return mTracker->currentPeriod();
+ return mTracker.currentPeriod();
}
void VSyncReactor::beginResync() {
- mTracker->resetModel();
+ mTracker.resetModel();
}
void VSyncReactor::endResync() {}
@@ -307,7 +307,7 @@
if (periodConfirmed(timestamp, hwcVsyncPeriod)) {
ATRACE_NAME("VSR: period confirmed");
if (mPeriodTransitioningTo) {
- mTracker->setPeriod(*mPeriodTransitioningTo);
+ mTracker.setPeriod(*mPeriodTransitioningTo);
for (auto& entry : mCallbacks) {
entry.second->setPeriod(*mPeriodTransitioningTo);
}
@@ -315,12 +315,12 @@
}
if (mLastHwVsync) {
- mTracker->addVsyncTimestamp(*mLastHwVsync);
+ mTracker.addVsyncTimestamp(*mLastHwVsync);
}
- mTracker->addVsyncTimestamp(timestamp);
+ mTracker.addVsyncTimestamp(timestamp);
endPeriodTransition();
- mMoreSamplesNeeded = mTracker->needsMoreSamples();
+ mMoreSamplesNeeded = mTracker.needsMoreSamples();
} else if (mPeriodConfirmationInProgress) {
ATRACE_NAME("VSR: still confirming period");
mLastHwVsync = timestamp;
@@ -329,8 +329,8 @@
} else {
ATRACE_NAME("VSR: adding sample");
*periodFlushed = false;
- mTracker->addVsyncTimestamp(timestamp);
- mMoreSamplesNeeded = mTracker->needsMoreSamples();
+ mTracker.addVsyncTimestamp(timestamp);
+ mMoreSamplesNeeded = mTracker.needsMoreSamples();
}
if (!mMoreSamplesNeeded) {
@@ -353,9 +353,9 @@
return NO_MEMORY;
}
- auto const period = mTracker->currentPeriod();
- auto repeater = std::make_unique<CallbackRepeater>(*mDispatch, callback, name, period,
- phase, mClock->now());
+ auto const period = mTracker.currentPeriod();
+ auto repeater = std::make_unique<CallbackRepeater>(mDispatch, callback, name, period, phase,
+ mClock->now());
it = mCallbacks.emplace(std::pair(callback, std::move(repeater))).first;
}
@@ -409,9 +409,9 @@
}
StringAppendF(&result, "VSyncTracker:\n");
- mTracker->dump(result);
+ mTracker.dump(result);
StringAppendF(&result, "VSyncDispatch:\n");
- mDispatch->dump(result);
+ mDispatch.dump(result);
}
void VSyncReactor::reset() {}
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.h b/services/surfaceflinger/Scheduler/VSyncReactor.h
index 265d89c..22ceb39 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.h
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.h
@@ -35,9 +35,8 @@
// TODO (b/145217110): consider renaming.
class VSyncReactor : public android::DispSync {
public:
- VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch,
- std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit,
- bool supportKernelIdleTimer);
+ VSyncReactor(std::unique_ptr<Clock> clock, VSyncDispatch& dispatch, VSyncTracker& tracker,
+ size_t pendingFenceLimit, bool supportKernelIdleTimer);
~VSyncReactor();
bool addPresentFence(const std::shared_ptr<FenceTime>& fence) final;
@@ -72,8 +71,8 @@
REQUIRES(mMutex);
std::unique_ptr<Clock> const mClock;
- std::unique_ptr<VSyncTracker> const mTracker;
- std::unique_ptr<VSyncDispatch> const mDispatch;
+ VSyncTracker& mTracker;
+ VSyncDispatch& mDispatch;
size_t const mPendingLimit;
mutable std::mutex mMutex;