SurfaceFlinger: DispSync -> VsyncController
Refactor the old DispSync to separate between Vsync math (VsyncTracker)
and fence / vsync callback management (VsyncController)
Bug: 162888874
Test: examine systraces
Test: SF unit tests
Change-Id: Id275620380a21aeb0017e966910cbf24860cecef
diff --git a/services/surfaceflinger/Scheduler/DispSync.h b/services/surfaceflinger/Scheduler/DispSync.h
deleted file mode 100644
index f34aabc..0000000
--- a/services/surfaceflinger/Scheduler/DispSync.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stddef.h>
-
-#include <utils/Mutex.h>
-#include <utils/RefBase.h>
-#include <utils/Timers.h>
-
-#include <ui/FenceTime.h>
-
-#include <memory>
-
-namespace android {
-
-class FenceTime;
-
-class DispSync {
-public:
- DispSync() = default;
- virtual ~DispSync() = default;
-
- virtual bool addPresentFence(const std::shared_ptr<FenceTime>&) = 0;
- virtual void beginResync() = 0;
- virtual bool addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
- bool* periodFlushed) = 0;
- virtual void setPeriod(nsecs_t period) = 0;
- virtual nsecs_t getPeriod() = 0;
- virtual nsecs_t computeNextRefresh(int periodOffset, nsecs_t now) const = 0;
- virtual void setIgnorePresentFences(bool ignore) = 0;
- virtual nsecs_t expectedPresentTime(nsecs_t now) = 0;
-
- virtual void dump(std::string& result) const = 0;
-
-protected:
- DispSync(DispSync const&) = delete;
- DispSync& operator=(DispSync const&) = delete;
-};
-
-} // namespace android
diff --git a/services/surfaceflinger/Scheduler/DispSyncSource.cpp b/services/surfaceflinger/Scheduler/DispSyncSource.cpp
index 75f072d..ce5c31a 100644
--- a/services/surfaceflinger/Scheduler/DispSyncSource.cpp
+++ b/services/surfaceflinger/Scheduler/DispSyncSource.cpp
@@ -22,16 +22,13 @@
#include <utils/Trace.h>
#include <mutex>
-#include "DispSync.h"
#include "EventThread.h"
+#include "VsyncController.h"
namespace android::scheduler {
using base::StringAppendF;
using namespace std::chrono_literals;
-// The DispSync interface has a 'repeat this callback at rate' semantic. This object adapts
-// VSyncDispatch's individually-scheduled callbacks so as to meet DispSync's existing semantic
-// for now.
class CallbackRepeater {
public:
CallbackRepeater(VSyncDispatch& dispatch, VSyncDispatch::Callback cb, const char* name,
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 559626b..f513535 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -98,11 +98,13 @@
}
DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t timestamp,
- uint32_t count, nsecs_t expectedVSyncTimestamp) {
+ uint32_t count, nsecs_t expectedVSyncTimestamp,
+ nsecs_t deadlineTimestamp) {
DisplayEventReceiver::Event event;
event.header = {DisplayEventReceiver::DISPLAY_EVENT_VSYNC, displayId, timestamp};
event.vsync.count = count;
event.vsync.expectedVSyncTimestamp = expectedVSyncTimestamp;
+ event.vsync.deadlineTimestamp = deadlineTimestamp;
return event;
}
@@ -285,12 +287,12 @@
}
void EventThread::onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp,
- nsecs_t /*deadlineTimestamp*/) {
+ nsecs_t deadlineTimestamp) {
std::lock_guard<std::mutex> lock(mMutex);
LOG_FATAL_IF(!mVSyncState);
mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
- expectedVSyncTimestamp));
+ expectedVSyncTimestamp, deadlineTimestamp));
mCondition.notify_all();
}
@@ -412,9 +414,11 @@
LOG_FATAL_IF(!mVSyncState);
const auto now = systemTime(SYSTEM_TIME_MONOTONIC);
- const auto expectedVSyncTime = now + timeout.count();
+ const auto deadlineTimestamp = now + timeout.count();
+ const auto expectedVSyncTime = deadlineTimestamp + timeout.count();
mPendingEvents.push_back(makeVSync(mVSyncState->displayId, now,
- ++mVSyncState->count, expectedVSyncTime));
+ ++mVSyncState->count, expectedVSyncTime,
+ deadlineTimestamp));
}
}
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index b0b5e2e..5271ccc 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -39,7 +39,6 @@
#include <numeric>
#include "../Layer.h"
-#include "DispSync.h"
#include "DispSyncSource.h"
#include "EventThread.h"
#include "InjectVSyncSource.h"
@@ -50,6 +49,7 @@
#include "VSyncDispatchTimerQueue.h"
#include "VSyncPredictor.h"
#include "VSyncReactor.h"
+#include "VsyncController.h"
#define RETURN_IF_INVALID_HANDLE(handle, ...) \
do { \
@@ -124,7 +124,7 @@
Scheduler::Scheduler(const scheduler::RefreshRateConfigs& configs, ISchedulerCallback& callback,
Options options)
- : Scheduler(createVsyncSchedule(options), configs, callback,
+ : Scheduler(createVsyncSchedule(options.supportKernelTimer), configs, callback,
createLayerHistory(configs, options.useContentDetectionV2), options) {
using namespace sysprop;
@@ -180,17 +180,17 @@
mIdleTimer.reset();
}
-Scheduler::VsyncSchedule Scheduler::createVsyncSchedule(Options options) {
+Scheduler::VsyncSchedule Scheduler::createVsyncSchedule(bool supportKernelTimer) {
auto clock = std::make_unique<scheduler::SystemClock>();
auto tracker = createVSyncTracker();
auto dispatch = createVSyncDispatch(*tracker);
// TODO(b/144707443): Tune constants.
constexpr size_t pendingFenceLimit = 20;
- auto sync =
+ auto controller =
std::make_unique<scheduler::VSyncReactor>(std::move(clock), *tracker, pendingFenceLimit,
- options.supportKernelTimer);
- return {std::move(sync), std::move(tracker), std::move(dispatch)};
+ supportKernelTimer);
+ return {std::move(controller), std::move(tracker), std::move(dispatch)};
}
std::unique_ptr<LayerHistory> Scheduler::createLayerHistory(
@@ -204,10 +204,6 @@
return std::make_unique<scheduler::impl::LayerHistory>();
}
-DispSync& Scheduler::getPrimaryDispSync() {
- return *mVsyncSchedule.sync;
-}
-
std::unique_ptr<VSyncSource> Scheduler::makePrimaryDispSyncSource(
const char* name, std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration, bool traceVsync) {
@@ -318,9 +314,9 @@
mConnections[handle].thread->setDuration(workDuration, readyDuration);
}
-void Scheduler::getDisplayStatInfo(DisplayStatInfo* stats) {
- stats->vsyncTime = getPrimaryDispSync().computeNextRefresh(0, systemTime());
- stats->vsyncPeriod = getPrimaryDispSync().getPeriod();
+void Scheduler::getDisplayStatInfo(DisplayStatInfo* stats, nsecs_t now) {
+ stats->vsyncTime = mVsyncSchedule.tracker->nextAnticipatedVSyncTimeFrom(now);
+ stats->vsyncPeriod = mVsyncSchedule.tracker->currentPeriod();
}
Scheduler::ConnectionHandle Scheduler::enableVSyncInjection(bool enable) {
@@ -357,7 +353,7 @@
void Scheduler::enableHardwareVsync() {
std::lock_guard<std::mutex> lock(mHWVsyncLock);
if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
- getPrimaryDispSync().beginResync();
+ mVsyncSchedule.tracker->resetModel();
mSchedulerCallback.setVsyncEnabled(true);
mPrimaryHWVsyncEnabled = true;
}
@@ -406,10 +402,10 @@
void Scheduler::setVsyncPeriod(nsecs_t period) {
std::lock_guard<std::mutex> lock(mHWVsyncLock);
- getPrimaryDispSync().setPeriod(period);
+ mVsyncSchedule.controller->startPeriodTransition(period);
if (!mPrimaryHWVsyncEnabled) {
- getPrimaryDispSync().beginResync();
+ mVsyncSchedule.tracker->resetModel();
mSchedulerCallback.setVsyncEnabled(true);
mPrimaryHWVsyncEnabled = true;
}
@@ -422,8 +418,8 @@
{ // Scope for the lock
std::lock_guard<std::mutex> lock(mHWVsyncLock);
if (mPrimaryHWVsyncEnabled) {
- needsHwVsync =
- getPrimaryDispSync().addResyncSample(timestamp, hwcVsyncPeriod, periodFlushed);
+ needsHwVsync = mVsyncSchedule.controller->addHwVsyncTimestamp(timestamp, hwcVsyncPeriod,
+ periodFlushed);
}
}
@@ -435,7 +431,7 @@
}
void Scheduler::addPresentFence(const std::shared_ptr<FenceTime>& fenceTime) {
- if (getPrimaryDispSync().addPresentFence(fenceTime)) {
+ if (mVsyncSchedule.controller->addPresentFence(fenceTime)) {
enableHardwareVsync();
} else {
disableHardwareVsync(false);
@@ -443,11 +439,7 @@
}
void Scheduler::setIgnorePresentFences(bool ignore) {
- getPrimaryDispSync().setIgnorePresentFences(ignore);
-}
-
-nsecs_t Scheduler::getDispSyncExpectedPresentTime(nsecs_t now) {
- return getPrimaryDispSync().expectedPresentTime(now);
+ mVsyncSchedule.controller->setIgnorePresentFences(ignore);
}
void Scheduler::registerLayer(Layer* layer) {
@@ -581,7 +573,7 @@
refreshRate.getFps() <= FPS_THRESHOLD_FOR_KERNEL_TIMER) {
// Disable HW VSYNC if the timer expired, as we don't need it enabled if
// we're not pushing frames, and if we're in PERFORMANCE mode then we'll
- // need to update the DispSync model anyway.
+ // need to update the VsyncController model anyway.
disableHardwareVsync(false /* makeUnavailable */);
}
@@ -624,11 +616,11 @@
mLayerHistory ? mLayerHistory->dump().c_str() : "(no layer history)");
}
-void Scheduler::dumpVSync(std::string& s) const {
+void Scheduler::dumpVsync(std::string& s) const {
using base::StringAppendF;
StringAppendF(&s, "VSyncReactor:\n");
- mVsyncSchedule.sync->dump(s);
+ mVsyncSchedule.controller->dump(s);
StringAppendF(&s, "VSyncDispatch:\n");
mVsyncSchedule.dispatch->dump(s);
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 9a4ac36..0b5c9d2 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -40,12 +40,12 @@
using namespace std::chrono_literals;
using scheduler::LayerHistory;
-class DispSync;
class FenceTime;
class InjectVSyncSource;
class PredictedVsyncTracer;
namespace scheduler {
+class VsyncController;
class VSyncDispatch;
class VSyncTracker;
} // namespace scheduler
@@ -69,8 +69,6 @@
Scheduler(const scheduler::RefreshRateConfigs&, ISchedulerCallback&);
~Scheduler();
- DispSync& getPrimaryDispSync();
-
using ConnectionHandle = scheduler::ConnectionHandle;
ConnectionHandle createConnection(const char* connectionName,
std::chrono::nanoseconds workDuration,
@@ -95,7 +93,7 @@
void setDuration(ConnectionHandle, std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration);
- void getDisplayStatInfo(DisplayStatInfo* stats);
+ void getDisplayStatInfo(DisplayStatInfo* stats, nsecs_t now);
// Returns injector handle if injection has toggled, or an invalid handle otherwise.
ConnectionHandle enableVSyncInjection(bool enable);
@@ -112,13 +110,12 @@
void resyncToHardwareVsync(bool makeAvailable, nsecs_t period);
void resync();
- // Passes a vsync sample to DispSync. periodFlushed will be true if
- // DispSync detected that the vsync period changed, and false otherwise.
+ // Passes a vsync sample to VsyncController. periodFlushed will be true if
+ // VsyncController detected that the vsync period changed, and false otherwise.
void addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
bool* periodFlushed);
void addPresentFence(const std::shared_ptr<FenceTime>&);
void setIgnorePresentFences(bool ignore);
- nsecs_t getDispSyncExpectedPresentTime(nsecs_t now);
// Layers are registered on creation, and unregistered when the weak reference expires.
void registerLayer(Layer*);
@@ -138,7 +135,7 @@
void dump(std::string&) const;
void dump(ConnectionHandle, std::string&) const;
- void dumpVSync(std::string&) const;
+ void dumpVsync(std::string&) const;
// Get the appropriate refresh for current conditions.
std::optional<HwcConfigIndexType> getPreferredConfigId();
@@ -178,7 +175,7 @@
};
struct VsyncSchedule {
- std::unique_ptr<DispSync> sync;
+ std::unique_ptr<scheduler::VsyncController> controller;
std::unique_ptr<scheduler::VSyncTracker> tracker;
std::unique_ptr<scheduler::VSyncDispatch> dispatch;
};
@@ -190,7 +187,7 @@
Scheduler(VsyncSchedule, const scheduler::RefreshRateConfigs&, ISchedulerCallback&,
std::unique_ptr<LayerHistory>, Options);
- static VsyncSchedule createVsyncSchedule(Options);
+ static VsyncSchedule createVsyncSchedule(bool supportKernelIdleTimer);
static std::unique_ptr<LayerHistory> createLayerHistory(const scheduler::RefreshRateConfigs&,
bool useContentDetectionV2);
diff --git a/services/surfaceflinger/Scheduler/Timer.cpp b/services/surfaceflinger/Scheduler/Timer.cpp
index 59c336a..c9c2d84 100644
--- a/services/surfaceflinger/Scheduler/Timer.cpp
+++ b/services/surfaceflinger/Scheduler/Timer.cpp
@@ -89,7 +89,7 @@
}
void Timer::alarmAt(std::function<void()> const& cb, nsecs_t time) {
- std::lock_guard<decltype(mMutex)> lk(mMutex);
+ std::lock_guard lock(mMutex);
using namespace std::literals;
static constexpr int ns_per_s =
std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
@@ -109,7 +109,7 @@
}
void Timer::alarmCancel() {
- std::lock_guard<decltype(mMutex)> lk(mMutex);
+ std::lock_guard lock(mMutex);
struct itimerspec old_timer;
struct itimerspec new_timer {
@@ -192,7 +192,7 @@
setDebugState(DebugState::Running);
std::function<void()> cb;
{
- std::lock_guard<decltype(mMutex)> lk(mMutex);
+ std::lock_guard lock(mMutex);
cb = mCallback;
}
if (cb) {
@@ -211,7 +211,7 @@
}
void Timer::setDebugState(DebugState state) {
- std::lock_guard lk(mMutex);
+ std::lock_guard lock(mMutex);
mDebugState = state;
}
@@ -233,7 +233,7 @@
}
void Timer::dump(std::string& result) const {
- std::lock_guard lk(mMutex);
+ std::lock_guard lock(mMutex);
StringAppendF(&result, "\t\tDebugState: %s\n", strDebugState(mDebugState));
}
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
index 2154a40..ca6ea27 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
@@ -185,7 +185,7 @@
mMinVsyncDistance(minVsyncDistance) {}
VSyncDispatchTimerQueue::~VSyncDispatchTimerQueue() {
- std::lock_guard<decltype(mMutex)> lk(mMutex);
+ std::lock_guard lock(mMutex);
cancelTimer();
}
@@ -257,7 +257,7 @@
};
std::vector<Invocation> invocations;
{
- std::lock_guard<decltype(mMutex)> lk(mMutex);
+ std::lock_guard lock(mMutex);
auto const now = mTimeKeeper->now();
mLastTimerCallback = now;
for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) {
@@ -289,7 +289,7 @@
VSyncDispatchTimerQueue::CallbackToken VSyncDispatchTimerQueue::registerCallback(
Callback const& callbackFn, std::string callbackName) {
- std::lock_guard<decltype(mMutex)> lk(mMutex);
+ std::lock_guard lock(mMutex);
return CallbackToken{
mCallbacks
.emplace(++mCallbackToken,
@@ -302,7 +302,7 @@
void VSyncDispatchTimerQueue::unregisterCallback(CallbackToken token) {
std::shared_ptr<VSyncDispatchTimerQueueEntry> entry = nullptr;
{
- std::lock_guard<decltype(mMutex)> lk(mMutex);
+ std::lock_guard lock(mMutex);
auto it = mCallbacks.find(token);
if (it != mCallbacks.end()) {
entry = it->second;
@@ -319,7 +319,7 @@
ScheduleTiming scheduleTiming) {
auto result = ScheduleResult::Error;
{
- std::lock_guard<decltype(mMutex)> lk(mMutex);
+ std::lock_guard lock(mMutex);
auto it = mCallbacks.find(token);
if (it == mCallbacks.end()) {
@@ -350,7 +350,7 @@
}
CancelResult VSyncDispatchTimerQueue::cancel(CallbackToken token) {
- std::lock_guard<decltype(mMutex)> lk(mMutex);
+ std::lock_guard lock(mMutex);
auto it = mCallbacks.find(token);
if (it == mCallbacks.end()) {
@@ -372,7 +372,7 @@
}
void VSyncDispatchTimerQueue::dump(std::string& result) const {
- std::lock_guard<decltype(mMutex)> lk(mMutex);
+ std::lock_guard lock(mMutex);
StringAppendF(&result, "\tTimer:\n");
mTimeKeeper->dump(result);
StringAppendF(&result, "\tmTimerSlack: %.2fms mMinVsyncDistance: %.2fms\n", mTimerSlack / 1e6f,
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index 3c5b3f1..7b5d462 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -30,6 +30,8 @@
namespace android::scheduler {
using base::StringAppendF;
+VsyncController::~VsyncController() = default;
+
Clock::~Clock() = default;
nsecs_t SystemClock::now() const {
return systemTime(SYSTEM_TIME_MONOTONIC);
@@ -44,7 +46,7 @@
VSyncReactor::~VSyncReactor() = default;
-bool VSyncReactor::addPresentFence(const std::shared_ptr<FenceTime>& fence) {
+bool VSyncReactor::addPresentFence(const std::shared_ptr<android::FenceTime>& fence) {
if (!fence) {
return false;
}
@@ -91,14 +93,14 @@
return mMoreSamplesNeeded;
}
-void VSyncReactor::setIgnorePresentFences(bool ignoration) {
+void VSyncReactor::setIgnorePresentFences(bool ignore) {
std::lock_guard lock(mMutex);
- mExternalIgnoreFences = ignoration;
+ mExternalIgnoreFences = ignore;
updateIgnorePresentFencesInternal();
}
-void VSyncReactor::setIgnorePresentFencesInternal(bool ignoration) {
- mInternalIgnoreFences = ignoration;
+void VSyncReactor::setIgnorePresentFencesInternal(bool ignore) {
+ mInternalIgnoreFences = ignore;
updateIgnorePresentFencesInternal();
}
@@ -108,16 +110,7 @@
}
}
-nsecs_t VSyncReactor::computeNextRefresh(int periodOffset, nsecs_t now) const {
- auto const currentPeriod = periodOffset ? mTracker.currentPeriod() : 0;
- return mTracker.nextAnticipatedVSyncTimeFrom(now + periodOffset * currentPeriod);
-}
-
-nsecs_t VSyncReactor::expectedPresentTime(nsecs_t now) {
- return mTracker.nextAnticipatedVSyncTimeFrom(now);
-}
-
-void VSyncReactor::startPeriodTransition(nsecs_t newPeriod) {
+void VSyncReactor::startPeriodTransitionInternal(nsecs_t newPeriod) {
ATRACE_CALL();
mPeriodConfirmationInProgress = true;
mPeriodTransitioningTo = newPeriod;
@@ -132,28 +125,20 @@
mLastHwVsync.reset();
}
-void VSyncReactor::setPeriod(nsecs_t period) {
+void VSyncReactor::startPeriodTransition(nsecs_t period) {
ATRACE_INT64("VSR-setPeriod", period);
- std::lock_guard lk(mMutex);
+ std::lock_guard lock(mMutex);
mLastHwVsync.reset();
- if (!mSupportKernelIdleTimer && period == getPeriod()) {
+ if (!mSupportKernelIdleTimer && period == mTracker.currentPeriod()) {
endPeriodTransition();
setIgnorePresentFencesInternal(false);
mMoreSamplesNeeded = false;
} else {
- startPeriodTransition(period);
+ startPeriodTransitionInternal(period);
}
}
-nsecs_t VSyncReactor::getPeriod() {
- return mTracker.currentPeriod();
-}
-
-void VSyncReactor::beginResync() {
- mTracker.resetModel();
-}
-
bool VSyncReactor::periodConfirmed(nsecs_t vsync_timestamp, std::optional<nsecs_t> HwcVsyncPeriod) {
if (!mPeriodConfirmationInProgress) {
return false;
@@ -164,13 +149,13 @@
}
const bool periodIsChanging =
- mPeriodTransitioningTo && (*mPeriodTransitioningTo != getPeriod());
+ mPeriodTransitioningTo && (*mPeriodTransitioningTo != mTracker.currentPeriod());
if (mSupportKernelIdleTimer && !periodIsChanging) {
// Clear out the Composer-provided period and use the allowance logic below
HwcVsyncPeriod = {};
}
- auto const period = mPeriodTransitioningTo ? *mPeriodTransitioningTo : getPeriod();
+ auto const period = mPeriodTransitioningTo ? *mPeriodTransitioningTo : mTracker.currentPeriod();
static constexpr int allowancePercent = 10;
static constexpr std::ratio<allowancePercent, 100> allowancePercentRatio;
auto const allowance = period * allowancePercentRatio.num / allowancePercentRatio.den;
@@ -182,8 +167,8 @@
return std::abs(distance - period) < allowance;
}
-bool VSyncReactor::addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
- bool* periodFlushed) {
+bool VSyncReactor::addHwVsyncTimestamp(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
+ bool* periodFlushed) {
assert(periodFlushed);
std::lock_guard lock(mMutex);
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.h b/services/surfaceflinger/Scheduler/VSyncReactor.h
index 80b5232..449d4c3 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.h
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.h
@@ -22,8 +22,8 @@
#include <mutex>
#include <unordered_map>
#include <vector>
-#include "DispSync.h"
#include "TimeKeeper.h"
+#include "VsyncController.h"
namespace android::scheduler {
class Clock;
@@ -31,32 +31,26 @@
class VSyncTracker;
// TODO (b/145217110): consider renaming.
-class VSyncReactor : public android::DispSync {
+class VSyncReactor : public VsyncController {
public:
VSyncReactor(std::unique_ptr<Clock> clock, VSyncTracker& tracker, size_t pendingFenceLimit,
bool supportKernelIdleTimer);
~VSyncReactor();
- bool addPresentFence(const std::shared_ptr<FenceTime>& fence) final;
- void setIgnorePresentFences(bool ignoration) final;
+ bool addPresentFence(const std::shared_ptr<android::FenceTime>& fence) final;
+ void setIgnorePresentFences(bool ignore) final;
- nsecs_t computeNextRefresh(int periodOffset, nsecs_t now) const final;
- nsecs_t expectedPresentTime(nsecs_t now) final;
+ void startPeriodTransition(nsecs_t period) final;
- 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() final;
- bool addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
- bool* periodFlushed) final;
+ bool addHwVsyncTimestamp(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
+ bool* periodFlushed) final;
void dump(std::string& result) const final;
private:
- void setIgnorePresentFencesInternal(bool ignoration) REQUIRES(mMutex);
+ void setIgnorePresentFencesInternal(bool ignore) REQUIRES(mMutex);
void updateIgnorePresentFencesInternal() REQUIRES(mMutex);
- void startPeriodTransition(nsecs_t newPeriod) REQUIRES(mMutex);
+ void startPeriodTransitionInternal(nsecs_t newPeriod) REQUIRES(mMutex);
void endPeriodTransition() REQUIRES(mMutex);
bool periodConfirmed(nsecs_t vsync_timestamp, std::optional<nsecs_t> hwcVsyncPeriod)
REQUIRES(mMutex);
@@ -68,7 +62,7 @@
mutable std::mutex mMutex;
bool mInternalIgnoreFences GUARDED_BY(mMutex) = false;
bool mExternalIgnoreFences GUARDED_BY(mMutex) = false;
- std::vector<std::shared_ptr<FenceTime>> mUnfiredFences GUARDED_BY(mMutex);
+ std::vector<std::shared_ptr<android::FenceTime>> mUnfiredFences GUARDED_BY(mMutex);
bool mMoreSamplesNeeded GUARDED_BY(mMutex) = false;
bool mPeriodConfirmationInProgress GUARDED_BY(mMutex) = false;
diff --git a/services/surfaceflinger/Scheduler/VsyncController.h b/services/surfaceflinger/Scheduler/VsyncController.h
new file mode 100644
index 0000000..0f0df22
--- /dev/null
+++ b/services/surfaceflinger/Scheduler/VsyncController.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstddef>
+
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+#include <ui/FenceTime.h>
+
+#include <memory>
+
+namespace android::scheduler {
+
+class FenceTime;
+
+class VsyncController {
+public:
+ virtual ~VsyncController();
+
+ /*
+ * Adds a present fence to the model. The controller will use the fence time as
+ * a vsync signal.
+ *
+ * \param [in] fence The present fence given from the display
+ * \return True if the model needs more vsync signals to make
+ * an accurate prediction,
+ * False otherwise
+ */
+ virtual bool addPresentFence(const std::shared_ptr<android::FenceTime>&) = 0;
+
+ /*
+ * Adds a hw sync timestamp to the model. The controller will use the timestamp
+ * time as a vsync signal.
+ *
+ * \param [in] timestamp The HW Vsync timestamp
+ * \param [in] hwcVsyncPeriod The Vsync period reported by composer, if available
+ * \param [out] periodFlushed True if the vsync period changed is completed
+ * \return True if the model needs more vsync signals to make
+ * an accurate prediction,
+ * False otherwise
+ */
+ virtual bool addHwVsyncTimestamp(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
+ bool* periodFlushed) = 0;
+
+ /*
+ * Inform the controller that the period is changing and the controller needs to recalibrate
+ * itself. The controller will end the period transition internally.
+ *
+ * \param [in] period The period that the system is changing into.
+ */
+ virtual void startPeriodTransition(nsecs_t period) = 0;
+
+ /*
+ * Tells the tracker to stop using present fences to get a vsync signal.
+ *
+ * \param [in] ignore Whether to ignore the present fences or not
+ */
+ virtual void setIgnorePresentFences(bool ignore) = 0;
+
+ virtual void dump(std::string& result) const = 0;
+
+protected:
+ VsyncController() = default;
+ VsyncController(VsyncController const&) = delete;
+ VsyncController& operator=(VsyncController const&) = delete;
+};
+
+} // namespace android::scheduler