SF: add disabled VRR DispSync impl (VSyncReactor)
Adds a DispSync implementation called VSyncReactor that
is built on better tested components that should be
capable of evolving with the MRR and VRR plans in R and S.
Implementation is currently disabled, but can be enabled
by failsafe switch:
ENABLE:
setprop debug.sf.vsync_reactor 1
stop;start
DISABLE:
debug.sf.vsync_reactor not set, OR
setprop debug.sf.vsync_reactor 0
stop;start
while testing is being conducted (still flushing out bugs).
Fixes: 140303479
Test: check that DispSync1.0 is still active
Test: set property and check that DispSync2.0 turns on
Change-Id: I668e34e8880d0aa08222d1028bc874a2ab6a7339
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 71a6a2f..3119bde 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -47,6 +47,10 @@
#include "OneShotTimer.h"
#include "SchedulerUtils.h"
#include "SurfaceFlingerProperties.h"
+#include "Timer.h"
+#include "VSyncDispatchTimerQueue.h"
+#include "VSyncPredictor.h"
+#include "VSyncReactor.h"
#define RETURN_IF_INVALID_HANDLE(handle, ...) \
do { \
@@ -58,11 +62,45 @@
namespace android {
+std::unique_ptr<DispSync> createDispSync() {
+ // TODO (140302863) remove this and use the vsync_reactor system.
+ if (property_get_bool("debug.sf.vsync_reactor", false)) {
+ // 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;
+ auto tracker = std::make_unique<
+ scheduler::VSyncPredictor>(std::chrono::duration_cast<std::chrono::nanoseconds>(
+ initial_period)
+ .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),
+ pendingFenceLimit);
+ } else {
+ return std::make_unique<impl::DispSync>("SchedulerDispSync",
+ sysprop::running_without_sync_framework(true));
+ }
+}
+
Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function,
const scheduler::RefreshRateConfigs& refreshRateConfig,
ISchedulerCallback& schedulerCallback)
- : mPrimaryDispSync(new impl::DispSync("SchedulerDispSync",
- sysprop::running_without_sync_framework(true))),
+ : mPrimaryDispSync(createDispSync()),
mEventControlThread(new impl::EventControlThread(std::move(function))),
mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)),
mSchedulerCallback(schedulerCallback),
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index 47e3f4f..c471e49 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -26,12 +26,15 @@
namespace android::scheduler {
Clock::~Clock() = default;
+nsecs_t SystemClock::now() const {
+ return systemTime(SYSTEM_TIME_MONOTONIC);
+}
VSyncReactor::VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch,
std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit)
: mClock(std::move(clock)),
- mDispatch(std::move(dispatch)),
mTracker(std::move(tracker)),
+ mDispatch(std::move(dispatch)),
mPendingLimit(pendingFenceLimit) {}
VSyncReactor::~VSyncReactor() = default;
@@ -245,4 +248,10 @@
return NO_ERROR;
}
+void VSyncReactor::dump(std::string& result) const {
+ result += "VsyncReactor in use\n"; // TODO (b/144927823): add more information!
+}
+
+void VSyncReactor::reset() {}
+
} // namespace android::scheduler
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.h b/services/surfaceflinger/Scheduler/VSyncReactor.h
index 837eb75..29a0a11 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.h
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.h
@@ -23,7 +23,7 @@
#include <unordered_map>
#include <vector>
#include "DispSync.h"
-
+#include "TimeKeeper.h"
namespace android::scheduler {
class Clock;
@@ -32,35 +32,38 @@
class CallbackRepeater;
// TODO (b/145217110): consider renaming.
-class VSyncReactor /* TODO (b/140201379): : public android::DispSync */ {
+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);
~VSyncReactor();
- bool addPresentFence(const std::shared_ptr<FenceTime>& fence);
- void setIgnorePresentFences(bool ignoration);
+ bool addPresentFence(const std::shared_ptr<FenceTime>& fence) final;
+ void setIgnorePresentFences(bool ignoration) final;
- nsecs_t computeNextRefresh(int periodOffset) const;
- nsecs_t expectedPresentTime();
+ nsecs_t computeNextRefresh(int periodOffset) const final;
+ nsecs_t expectedPresentTime() final;
- void setPeriod(nsecs_t period);
- nsecs_t getPeriod();
+ void setPeriod(nsecs_t period) final;
+ nsecs_t getPeriod() final;
// TODO: (b/145626181) remove begin,endResync functions from DispSync i/f when possible.
- void beginResync();
- bool addResyncSample(nsecs_t timestamp, bool* periodFlushed);
- void endResync();
+ void beginResync() final;
+ bool addResyncSample(nsecs_t timestamp, bool* periodFlushed) final;
+ void endResync() final;
status_t addEventListener(const char* name, nsecs_t phase, DispSync::Callback* callback,
- nsecs_t lastCallbackTime);
- status_t removeEventListener(DispSync::Callback* callback, nsecs_t* outLastCallback);
- status_t changePhaseOffset(DispSync::Callback* callback, nsecs_t phase);
+ nsecs_t lastCallbackTime) final;
+ status_t removeEventListener(DispSync::Callback* callback, nsecs_t* outLastCallback) final;
+ status_t changePhaseOffset(DispSync::Callback* callback, nsecs_t phase) final;
+
+ void dump(std::string& result) const final;
+ void reset() final;
private:
std::unique_ptr<Clock> const mClock;
- std::unique_ptr<VSyncDispatch> const mDispatch;
std::unique_ptr<VSyncTracker> const mTracker;
+ std::unique_ptr<VSyncDispatch> const mDispatch;
size_t const mPendingLimit;
std::mutex mMutex;
@@ -71,4 +74,8 @@
GUARDED_BY(mMutex);
};
+class SystemClock : public Clock {
+ nsecs_t now() const final;
+};
+
} // namespace android::scheduler