[SF] Adds callback from the VsyncPredictor
Hooks up the NotifyExpectedPresentIfRequired with
expectedPresentTime
BUG: 296636253
BUG: 284845445
Test: atest HWComposerTest
Change-Id: Idfd30929a0f4931b1a9f943340932c655ddd5903
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 1a8713d..d3db523 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -67,11 +67,12 @@
namespace android::scheduler {
Scheduler::Scheduler(ICompositor& compositor, ISchedulerCallback& callback, FeatureFlags features,
- sp<VsyncModulator> modulatorPtr)
+ sp<VsyncModulator> modulatorPtr, IVsyncTrackerCallback& vsyncTrackerCallback)
: impl::MessageQueue(compositor),
mFeatures(features),
mVsyncModulator(std::move(modulatorPtr)),
- mSchedulerCallback(callback) {}
+ mSchedulerCallback(callback),
+ mVsyncTrackerCallback(vsyncTrackerCallback) {}
Scheduler::~Scheduler() {
// MessageQueue depends on VsyncSchedule, so first destroy it.
@@ -116,10 +117,10 @@
}
void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr) {
- auto schedulePtr = std::make_shared<VsyncSchedule>(displayId, mFeatures,
- [this](PhysicalDisplayId id, bool enable) {
- onHardwareVsyncRequest(id, enable);
- });
+ auto schedulePtr = std::make_shared<VsyncSchedule>(
+ displayId, mFeatures,
+ [this](PhysicalDisplayId id, bool enable) { onHardwareVsyncRequest(id, enable); },
+ mVsyncTrackerCallback);
registerDisplayInternal(displayId, std::move(selectorPtr), std::move(schedulePtr));
}
@@ -562,7 +563,19 @@
ALOGV("%s %s (%s)", __func__, to_string(mode.fps).c_str(),
to_string(mode.modePtr->getVsyncRate()).c_str());
- display.schedulePtr->getTracker().setRenderRate(renderFrameRate);
+ display.schedulePtr->getTracker().setDisplayModeData(
+ {.renderRate = renderFrameRate,
+ .notifyExpectedPresentTimeoutOpt = getNotifyExpectedPresentTimeout(mode)});
+}
+
+std::optional<Period> Scheduler::getNotifyExpectedPresentTimeout(const FrameRateMode& mode) {
+ if (mode.modePtr->getVrrConfig() && mode.modePtr->getVrrConfig()->notifyExpectedPresentConfig) {
+ return Period::fromNs(
+ mode.modePtr->getVrrConfig()
+ ->notifyExpectedPresentConfig->notifyExpectedPresentTimeoutNs);
+ } else {
+ return std::nullopt;
+ }
}
void Scheduler::resync() {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index b0520a6..a5a5e8d 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -102,7 +102,8 @@
using Impl = android::impl::MessageQueue;
public:
- Scheduler(ICompositor&, ISchedulerCallback&, FeatureFlags, sp<VsyncModulator>);
+ Scheduler(ICompositor&, ISchedulerCallback&, FeatureFlags, sp<VsyncModulator>,
+ IVsyncTrackerCallback&);
virtual ~Scheduler();
void startTimers();
@@ -429,6 +430,9 @@
Period getVsyncPeriod(uid_t) override EXCLUDES(mDisplayLock);
void resync() override EXCLUDES(mDisplayLock);
+ std::optional<Period> getNotifyExpectedPresentTimeout(const FrameRateMode&)
+ REQUIRES(mDisplayLock);
+
// Stores EventThread associated with a given VSyncSource, and an initial EventThreadConnection.
struct Connection {
sp<EventThreadConnection> connection;
@@ -462,6 +466,8 @@
ISchedulerCallback& mSchedulerCallback;
+ IVsyncTrackerCallback& mVsyncTrackerCallback;
+
// mDisplayLock may be locked while under mPolicyLock.
mutable std::mutex mPolicyLock;
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index e969fdc..799466b 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -35,6 +35,7 @@
#include <gui/TraceUtils.h>
#include <utils/Log.h>
+#include "FlagManager.h"
#include "RefreshRateSelector.h"
#include "VSyncPredictor.h"
@@ -47,12 +48,14 @@
VSyncPredictor::~VSyncPredictor() = default;
VSyncPredictor::VSyncPredictor(PhysicalDisplayId id, nsecs_t idealPeriod, size_t historySize,
- size_t minimumSamplesForPrediction, uint32_t outlierTolerancePercent)
+ size_t minimumSamplesForPrediction, uint32_t outlierTolerancePercent,
+ IVsyncTrackerCallback& callback)
: mId(id),
mTraceOn(property_get_bool("debug.sf.vsp_trace", false)),
kHistorySize(historySize),
kMinimumSamplesForPrediction(minimumSamplesForPrediction),
kOutlierTolerancePercent(std::min(outlierTolerancePercent, kMaxPercent)),
+ mVsyncTrackerCallback(callback),
mIdealPeriod(idealPeriod) {
resetModel();
}
@@ -275,11 +278,11 @@
mLastVsyncSequence = getVsyncSequenceLocked(timePoint);
const auto renderRatePhase = [&]() REQUIRES(mMutex) -> int {
- if (!mRenderRate) return 0;
+ if (!mDisplayModeDataOpt) return 0;
const auto divisor =
RefreshRateSelector::getFrameRateDivisor(Fps::fromPeriodNsecs(mIdealPeriod),
- *mRenderRate);
+ mDisplayModeDataOpt->renderRate);
if (divisor <= 1) return 0;
const int mod = mLastVsyncSequence->seq % divisor;
@@ -289,12 +292,24 @@
}();
if (renderRatePhase == 0) {
- return mLastVsyncSequence->vsyncTime;
+ const auto vsyncTime = mLastVsyncSequence->vsyncTime;
+ if (FlagManager::getInstance().vrr_config() && mDisplayModeDataOpt) {
+ mVsyncTrackerCallback.onVsyncGenerated(mId, TimePoint::fromNs(vsyncTime),
+ *mDisplayModeDataOpt,
+ Period::fromNs(mIdealPeriod));
+ }
+ return vsyncTime;
}
auto const [slope, intercept] = getVSyncPredictionModelLocked();
const auto approximateNextVsync = mLastVsyncSequence->vsyncTime + slope * renderRatePhase;
- return nextAnticipatedVSyncTimeFromLocked(approximateNextVsync - slope / 2);
+ const auto nextAnticipatedVsyncTime =
+ nextAnticipatedVSyncTimeFromLocked(approximateNextVsync - slope / 2);
+ if (FlagManager::getInstance().vrr_config() && mDisplayModeDataOpt) {
+ mVsyncTrackerCallback.onVsyncGenerated(mId, TimePoint::fromNs(nextAnticipatedVsyncTime),
+ *mDisplayModeDataOpt, Period::fromNs(mIdealPeriod));
+ }
+ return nextAnticipatedVsyncTime;
}
/*
@@ -332,10 +347,14 @@
return vsyncSequence.seq % divisor == 0;
}
-void VSyncPredictor::setRenderRate(Fps fps) {
- ALOGV("%s %s: %s", __func__, to_string(mId).c_str(), to_string(fps).c_str());
+void VSyncPredictor::setDisplayModeData(const DisplayModeData& displayModeData) {
+ ALOGV("%s %s: RenderRate %s notifyExpectedPresentTimeout %s", __func__, to_string(mId).c_str(),
+ to_string(displayModeData.renderRate).c_str(),
+ displayModeData.notifyExpectedPresentTimeoutOpt
+ ? std::to_string(displayModeData.notifyExpectedPresentTimeoutOpt->ns()).c_str()
+ : "N/A");
std::lock_guard lock(mMutex);
- mRenderRate = fps;
+ mDisplayModeDataOpt = displayModeData;
}
VSyncPredictor::Model VSyncPredictor::getVSyncPredictionModel() const {
@@ -358,6 +377,7 @@
mRateMap.erase(mRateMap.begin());
}
+ // TODO(b/308610306) mIdealPeriod to be updated with setDisplayModeData
mIdealPeriod = period;
if (mRateMap.find(period) == mRateMap.end()) {
mRateMap[mIdealPeriod] = {period, 0};
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.h b/services/surfaceflinger/Scheduler/VSyncPredictor.h
index c01c44d..c271eb7 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.h
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.h
@@ -36,9 +36,11 @@
* \param [in] minimumSamplesForPrediction The minimum number of samples to collect before
* predicting. \param [in] outlierTolerancePercent a number 0 to 100 that will be used to filter
* samples that fall outlierTolerancePercent from an anticipated vsync event.
+ * \param [in] IVsyncTrackerCallback The callback for the VSyncTracker.
*/
VSyncPredictor(PhysicalDisplayId, nsecs_t idealPeriod, size_t historySize,
- size_t minimumSamplesForPrediction, uint32_t outlierTolerancePercent);
+ size_t minimumSamplesForPrediction, uint32_t outlierTolerancePercent,
+ IVsyncTrackerCallback&);
~VSyncPredictor();
bool addVsyncTimestamp(nsecs_t timestamp) final EXCLUDES(mMutex);
@@ -69,7 +71,7 @@
bool isVSyncInPhase(nsecs_t timePoint, Fps frameRate) const final EXCLUDES(mMutex);
- void setRenderRate(Fps) final EXCLUDES(mMutex);
+ void setDisplayModeData(const DisplayModeData&) final EXCLUDES(mMutex);
void dump(std::string& result) const final EXCLUDES(mMutex);
@@ -99,6 +101,7 @@
size_t const kHistorySize;
size_t const kMinimumSamplesForPrediction;
size_t const kOutlierTolerancePercent;
+ IVsyncTrackerCallback& mVsyncTrackerCallback;
std::mutex mutable mMutex;
nsecs_t mIdealPeriod GUARDED_BY(mMutex);
@@ -110,7 +113,7 @@
size_t mLastTimestampIndex GUARDED_BY(mMutex) = 0;
std::vector<nsecs_t> mTimestamps GUARDED_BY(mMutex);
- std::optional<Fps> mRenderRate GUARDED_BY(mMutex);
+ std::optional<DisplayModeData> mDisplayModeDataOpt GUARDED_BY(mMutex);
mutable std::optional<VsyncSequence> mLastVsyncSequence GUARDED_BY(mMutex);
};
diff --git a/services/surfaceflinger/Scheduler/VSyncTracker.h b/services/surfaceflinger/Scheduler/VSyncTracker.h
index bc0e3bc..7eedc31 100644
--- a/services/surfaceflinger/Scheduler/VSyncTracker.h
+++ b/services/surfaceflinger/Scheduler/VSyncTracker.h
@@ -16,6 +16,7 @@
#pragma once
+#include <ui/DisplayId.h>
#include <utils/Timers.h>
#include <scheduler/Fps.h>
@@ -23,6 +24,23 @@
#include "VSyncDispatch.h"
namespace android::scheduler {
+
+struct DisplayModeData {
+ Fps renderRate;
+ std::optional<Period> notifyExpectedPresentTimeoutOpt;
+
+ bool operator==(const DisplayModeData& other) const {
+ return isApproxEqual(renderRate, other.renderRate) &&
+ notifyExpectedPresentTimeoutOpt == other.notifyExpectedPresentTimeoutOpt;
+ }
+};
+
+struct IVsyncTrackerCallback {
+ virtual ~IVsyncTrackerCallback() = default;
+ virtual void onVsyncGenerated(PhysicalDisplayId, TimePoint expectedPresentTime,
+ const DisplayModeData&, Period vsyncPeriod) = 0;
+};
+
/*
* VSyncTracker is an interface for providing estimates on future Vsync signal times based on
* historical vsync timing data.
@@ -80,16 +98,20 @@
virtual bool isVSyncInPhase(nsecs_t timePoint, Fps frameRate) const = 0;
/*
- * Sets a render rate on the tracker. If the render rate is not a divisor
- * of the period, the render rate is ignored until the period changes.
+ * Sets the metadata about the currently active display mode such as VRR
+ * timeout period, vsyncPeriod and framework property such as render rate.
+ * If the render rate is not a divisor of the period, the render rate is
+ * ignored until the period changes.
* The tracker will continue to track the vsync timeline and expect it
* to match the current period, however, nextAnticipatedVSyncTimeFrom will
* return vsyncs according to the render rate set. Setting a render rate is useful
* when a display is running at 120Hz but the render frame rate is 60Hz.
+ * When IVsyncTrackerCallback::onVsyncGenerated callback is made we will pass along
+ * the vsyncPeriod, render rate and timeoutNs.
*
- * \param [in] Fps The render rate the tracker should operate at.
+ * \param [in] DisplayModeData The DisplayModeData the tracker will use.
*/
- virtual void setRenderRate(Fps) = 0;
+ virtual void setDisplayModeData(const DisplayModeData&) = 0;
virtual void dump(std::string& result) const = 0;
diff --git a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
index ff3f29d..5fb53f9 100644
--- a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
+++ b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
@@ -54,10 +54,11 @@
};
VsyncSchedule::VsyncSchedule(PhysicalDisplayId id, FeatureFlags features,
- RequestHardwareVsync requestHardwareVsync)
+ RequestHardwareVsync requestHardwareVsync,
+ IVsyncTrackerCallback& callback)
: mId(id),
mRequestHardwareVsync(std::move(requestHardwareVsync)),
- mTracker(createTracker(id)),
+ mTracker(createTracker(id, callback)),
mDispatch(createDispatch(mTracker)),
mController(createController(id, *mTracker, features)),
mTracer(features.test(Feature::kTracePredictedVsync)
@@ -100,7 +101,8 @@
mDispatch->dump(out);
}
-VsyncSchedule::TrackerPtr VsyncSchedule::createTracker(PhysicalDisplayId id) {
+VsyncSchedule::TrackerPtr VsyncSchedule::createTracker(PhysicalDisplayId id,
+ IVsyncTrackerCallback& callback) {
// TODO(b/144707443): Tune constants.
constexpr nsecs_t kInitialPeriod = (60_Hz).getPeriodNsecs();
constexpr size_t kHistorySize = 20;
@@ -108,7 +110,8 @@
constexpr uint32_t kDiscardOutlierPercent = 20;
return std::make_unique<VSyncPredictor>(id, kInitialPeriod, kHistorySize,
- kMinSamplesForPrediction, kDiscardOutlierPercent);
+ kMinSamplesForPrediction, kDiscardOutlierPercent,
+ callback);
}
VsyncSchedule::DispatchPtr VsyncSchedule::createDispatch(TrackerPtr tracker) {
diff --git a/services/surfaceflinger/Scheduler/VsyncSchedule.h b/services/surfaceflinger/Scheduler/VsyncSchedule.h
index 47e92e1..ca61f87 100644
--- a/services/surfaceflinger/Scheduler/VsyncSchedule.h
+++ b/services/surfaceflinger/Scheduler/VsyncSchedule.h
@@ -31,6 +31,7 @@
#include <scheduler/Time.h>
#include "ThreadContext.h"
+#include "VSyncTracker.h"
namespace android {
class EventThreadTest;
@@ -56,7 +57,7 @@
public:
using RequestHardwareVsync = std::function<void(PhysicalDisplayId, bool enabled)>;
- VsyncSchedule(PhysicalDisplayId, FeatureFlags, RequestHardwareVsync);
+ VsyncSchedule(PhysicalDisplayId, FeatureFlags, RequestHardwareVsync, IVsyncTrackerCallback&);
~VsyncSchedule();
// IVsyncSource overrides:
@@ -124,7 +125,7 @@
friend class android::VsyncScheduleTest;
friend class android::fuzz::SchedulerFuzzer;
- static TrackerPtr createTracker(PhysicalDisplayId);
+ static TrackerPtr createTracker(PhysicalDisplayId, IVsyncTrackerCallback&);
static DispatchPtr createDispatch(TrackerPtr);
static ControllerPtr createController(PhysicalDisplayId, VsyncTracker&, FeatureFlags);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 62eb17d..b1d8db5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4036,6 +4036,21 @@
}
}
+void SurfaceFlinger::onVsyncGenerated(PhysicalDisplayId displayId, TimePoint expectedPresentTime,
+ const scheduler::DisplayModeData& displayModeData,
+ Period vsyncPeriod) {
+ const auto status =
+ getHwComposer()
+ .notifyExpectedPresentIfRequired(displayId, vsyncPeriod, expectedPresentTime,
+ displayModeData.renderRate,
+ displayModeData
+ .notifyExpectedPresentTimeoutOpt);
+ if (status != NO_ERROR) {
+ ALOGE("%s failed to notifyExpectedPresentHint for display %" PRId64, __func__,
+ displayId.value);
+ }
+}
+
void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {
using namespace scheduler;
@@ -4074,8 +4089,12 @@
mScheduler = std::make_unique<Scheduler>(static_cast<ICompositor&>(*this),
static_cast<ISchedulerCallback&>(*this), features,
- std::move(modulatorPtr));
+ std::move(modulatorPtr),
+ static_cast<IVsyncTrackerCallback&>(*this));
mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector());
+ if (FlagManager::getInstance().vrr_config()) {
+ mScheduler->setRenderRate(display->getPhysicalId(), activeMode.fps);
+ }
mScheduler->startTimers();
const auto configs = mVsyncConfiguration->getCurrentConfigs();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 520bd22..94eedc8 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -195,7 +195,8 @@
private HWC2::ComposerCallback,
private ICompositor,
private scheduler::ISchedulerCallback,
- private compositionengine::ICEPowerCallback {
+ private compositionengine::ICEPowerCallback,
+ private scheduler::IVsyncTrackerCallback {
public:
struct SkipInitializationTag {};
@@ -656,6 +657,10 @@
// ICEPowerCallback overrides:
void notifyCpuLoadUp() override;
+ // IVsyncTrackerCallback overrides
+ void onVsyncGenerated(PhysicalDisplayId, TimePoint expectedPresentTime,
+ const scheduler::DisplayModeData&, Period vsyncPeriod) override;
+
// Toggles the kernel idle timer on or off depending the policy decisions around refresh rates.
void toggleKernelIdleTimer() REQUIRES(mStateLock);
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
index c4077df..70ce884 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
@@ -225,16 +225,19 @@
class TestableScheduler : public Scheduler, private ICompositor {
public:
TestableScheduler(const std::shared_ptr<scheduler::RefreshRateSelector>& selectorPtr,
- sp<VsyncModulator> modulatorPtr, ISchedulerCallback& callback)
+ sp<VsyncModulator> modulatorPtr, ISchedulerCallback& callback,
+ IVsyncTrackerCallback& vsyncTrackerCallback)
: TestableScheduler(std::make_unique<android::mock::VsyncController>(),
std::make_shared<android::mock::VSyncTracker>(), selectorPtr,
- std::move(modulatorPtr), callback) {}
+ std::move(modulatorPtr), callback, vsyncTrackerCallback) {}
TestableScheduler(std::unique_ptr<VsyncController> controller,
VsyncSchedule::TrackerPtr tracker,
std::shared_ptr<RefreshRateSelector> selectorPtr,
- sp<VsyncModulator> modulatorPtr, ISchedulerCallback& callback)
- : Scheduler(*this, callback, Feature::kContentDetection, std::move(modulatorPtr)) {
+ sp<VsyncModulator> modulatorPtr, ISchedulerCallback& callback,
+ IVsyncTrackerCallback& vsyncTrackerCallback)
+ : Scheduler(*this, callback, Feature::kContentDetection, std::move(modulatorPtr),
+ vsyncTrackerCallback) {
const auto displayId = selectorPtr->getActiveMode().modePtr->getPhysicalDisplayId();
registerDisplayInternal(displayId, std::move(selectorPtr),
std::shared_ptr<VsyncSchedule>(
@@ -400,7 +403,8 @@
} // namespace surfaceflinger::test
// TODO(b/189053744) : Create a common test/mock library for surfaceflinger
-class TestableSurfaceFlinger final : private scheduler::ISchedulerCallback {
+class TestableSurfaceFlinger final : private scheduler::ISchedulerCallback,
+ private scheduler::IVsyncTrackerCallback {
public:
using HotplugEvent = SurfaceFlinger::HotplugEvent;
@@ -656,6 +660,7 @@
std::unique_ptr<EventThread> appEventThread,
std::unique_ptr<EventThread> sfEventThread,
scheduler::ISchedulerCallback* callback = nullptr,
+ scheduler::IVsyncTrackerCallback* vsyncTrackerCallback = nullptr,
bool hasMultipleModes = false) {
constexpr DisplayModeId kModeId60{0};
DisplayModes modes = makeModes(mock::createDisplayMode(kModeId60, 60_Hz));
@@ -678,7 +683,8 @@
mScheduler = new scheduler::TestableScheduler(std::move(vsyncController),
std::move(vsyncTracker), mRefreshRateSelector,
- std::move(modulatorPtr), *(callback ?: this));
+ std::move(modulatorPtr), *(callback ?: this),
+ *(vsyncTrackerCallback ?: this));
mFlinger->mAppConnectionHandle = mScheduler->createConnection(std::move(appEventThread));
mFlinger->mSfConnectionHandle = mScheduler->createConnection(std::move(sfEventThread));
@@ -799,6 +805,10 @@
void triggerOnFrameRateOverridesChanged() override {}
void onChoreographerAttached() override {}
+ // IVsyncTrackerCallback overrides
+ void onVsyncGenerated(PhysicalDisplayId, TimePoint, const scheduler::DisplayModeData&,
+ Period) override {}
+
surfaceflinger::test::Factory mFactory;
sp<SurfaceFlinger> mFlinger =
sp<SurfaceFlinger>::make(mFactory, SurfaceFlinger::SkipInitialization);
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
index a8727f9..8fcfd81 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
@@ -178,14 +178,23 @@
dump<scheduler::VSyncDispatchTimerQueueEntry>(&entry, &mFdp);
}
+struct VsyncTrackerCallback : public scheduler::IVsyncTrackerCallback {
+ void onVsyncGenerated(PhysicalDisplayId, TimePoint, const scheduler::DisplayModeData&,
+ Period) override {}
+};
+
void SchedulerFuzzer::fuzzVSyncPredictor() {
uint16_t now = mFdp.ConsumeIntegral<uint16_t>();
uint16_t historySize = mFdp.ConsumeIntegralInRange<uint16_t>(1, UINT16_MAX);
uint16_t minimumSamplesForPrediction = mFdp.ConsumeIntegralInRange<uint16_t>(1, UINT16_MAX);
nsecs_t idealPeriod = mFdp.ConsumeIntegralInRange<nsecs_t>(1, UINT32_MAX);
- scheduler::VSyncPredictor tracker{kDisplayId, idealPeriod, historySize,
+ VsyncTrackerCallback callback;
+ scheduler::VSyncPredictor tracker{kDisplayId,
+ idealPeriod,
+ historySize,
minimumSamplesForPrediction,
- mFdp.ConsumeIntegral<uint32_t>() /*outlierTolerancePercent*/};
+ mFdp.ConsumeIntegral<uint32_t>() /*outlierTolerancePercent*/,
+ callback};
uint16_t period = mFdp.ConsumeIntegral<uint16_t>();
tracker.setPeriod(period);
for (uint16_t i = 0; i < minimumSamplesForPrediction; ++i) {
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
index 8061a8f..728708f 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
@@ -100,7 +100,7 @@
return true;
}
- void setRenderRate(Fps) override {}
+ void setDisplayModeData(const scheduler::DisplayModeData&) override {}
nsecs_t nextVSyncTime(nsecs_t timePoint) const {
if (timePoint % mPeriod == 0) {
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index fa31643..1379665 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -80,7 +80,8 @@
std::unique_ptr<EventThread>(mEventThread),
std::unique_ptr<EventThread>(mSFEventThread),
TestableSurfaceFlinger::DefaultDisplayMode{displayId},
- TestableSurfaceFlinger::SchedulerCallbackImpl::kMock);
+ TestableSurfaceFlinger::SchedulerCallbackImpl::kMock,
+ TestableSurfaceFlinger::VsyncTrackerCallbackImpl::kMock);
}
void DisplayTransactionTest::injectMockComposer(int virtualDisplayCount) {
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp
index 2f6058f..190c0e8 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp
@@ -165,8 +165,10 @@
DisplayModeId(0));
mock::SchedulerCallback mSchedulerCallback;
+ mock::VsyncTrackerCallback mVsyncTrackerCallback;
- TestableScheduler* mScheduler = new TestableScheduler(mSelector, mSchedulerCallback);
+ TestableScheduler* mScheduler =
+ new TestableScheduler(mSelector, mSchedulerCallback, mVsyncTrackerCallback);
TestableSurfaceFlinger mFlinger;
};
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
index e8831ab..5328fa3 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
@@ -144,7 +144,9 @@
mock::SchedulerCallback mSchedulerCallback;
- TestableScheduler* mScheduler = new TestableScheduler(mSelector, mSchedulerCallback);
+ mock::VsyncTrackerCallback mVsyncTrackerCallback;
+ TestableScheduler* mScheduler =
+ new TestableScheduler(mSelector, mSchedulerCallback, mVsyncTrackerCallback);
TestableSurfaceFlinger mFlinger;
};
diff --git a/services/surfaceflinger/tests/unittests/LayerInfoTest.cpp b/services/surfaceflinger/tests/unittests/LayerInfoTest.cpp
index 11072bc..830dcce 100644
--- a/services/surfaceflinger/tests/unittests/LayerInfoTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerInfoTest.cpp
@@ -61,7 +61,9 @@
HI_FPS)),
DisplayModeId(0));
mock::SchedulerCallback mSchedulerCallback;
- TestableScheduler* mScheduler = new TestableScheduler(mSelector, mSchedulerCallback);
+ mock::VsyncTrackerCallback mVsyncTrackerCallback;
+ TestableScheduler* mScheduler =
+ new TestableScheduler(mSelector, mSchedulerCallback, mVsyncTrackerCallback);
TestableSurfaceFlinger mFlinger;
};
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 87fae2c..b5eb777 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -89,7 +89,9 @@
kDisplay1Mode60->getId());
mock::SchedulerCallback mSchedulerCallback;
- TestableScheduler* mScheduler = new TestableScheduler{mSelector, mSchedulerCallback};
+ mock::VsyncTrackerCallback mVsyncTrackerCallback;
+ TestableScheduler* mScheduler =
+ new TestableScheduler{mSelector, mSchedulerCallback, mVsyncTrackerCallback};
surfaceflinger::frontend::LayerHierarchyBuilder mLayerHierarchyBuilder{{}};
ConnectionHandle mConnectionHandle;
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index 3d1c900..8b6f0f1 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -36,18 +36,21 @@
class TestableScheduler : public Scheduler, private ICompositor {
public:
- TestableScheduler(RefreshRateSelectorPtr selectorPtr, ISchedulerCallback& callback)
+ TestableScheduler(RefreshRateSelectorPtr selectorPtr, ISchedulerCallback& callback,
+ IVsyncTrackerCallback& vsyncTrackerCallback)
: TestableScheduler(std::make_unique<mock::VsyncController>(),
std::make_shared<mock::VSyncTracker>(), std::move(selectorPtr),
- sp<VsyncModulator>::make(VsyncConfigSet{}), callback) {}
+ sp<VsyncModulator>::make(VsyncConfigSet{}), callback,
+ vsyncTrackerCallback) {}
TestableScheduler(std::unique_ptr<VsyncController> controller,
std::shared_ptr<VSyncTracker> tracker, RefreshRateSelectorPtr selectorPtr,
- sp<VsyncModulator> modulatorPtr, ISchedulerCallback& callback)
- : Scheduler(*this, callback,
+ sp<VsyncModulator> modulatorPtr, ISchedulerCallback& schedulerCallback,
+ IVsyncTrackerCallback& vsyncTrackerCallback)
+ : Scheduler(*this, schedulerCallback,
(FeatureFlags)Feature::kContentDetection |
Feature::kSmallDirtyContentDetection,
- std::move(modulatorPtr)) {
+ std::move(modulatorPtr), vsyncTrackerCallback) {
const auto displayId = selectorPtr->getActiveMode().modePtr->getPhysicalDisplayId();
registerDisplay(displayId, std::move(selectorPtr), std::move(controller),
std::move(tracker));
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 03af56c..d0b2199 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -53,6 +53,7 @@
#include "mock/MockFrameTimeline.h"
#include "mock/MockFrameTracer.h"
#include "mock/MockSchedulerCallback.h"
+#include "mock/MockVsyncTrackerCallback.h"
#include "mock/system/window/MockNativeWindow.h"
#include "Scheduler/VSyncTracker.h"
@@ -204,6 +205,8 @@
enum class SchedulerCallbackImpl { kNoOp, kMock };
+ enum class VsyncTrackerCallbackImpl { kNoOp, kMock };
+
struct DefaultDisplayMode {
// The ID of the injected RefreshRateSelector and its default display mode.
PhysicalDisplayId displayId;
@@ -213,13 +216,14 @@
using DisplayModesVariant = std::variant<DefaultDisplayMode, RefreshRateSelectorPtr>;
- void setupScheduler(std::unique_ptr<scheduler::VsyncController> vsyncController,
- std::shared_ptr<scheduler::VSyncTracker> vsyncTracker,
- std::unique_ptr<EventThread> appEventThread,
- std::unique_ptr<EventThread> sfEventThread,
- DisplayModesVariant modesVariant,
- SchedulerCallbackImpl callbackImpl = SchedulerCallbackImpl::kNoOp,
- bool useNiceMock = false) {
+ void setupScheduler(
+ std::unique_ptr<scheduler::VsyncController> vsyncController,
+ std::shared_ptr<scheduler::VSyncTracker> vsyncTracker,
+ std::unique_ptr<EventThread> appEventThread, std::unique_ptr<EventThread> sfEventThread,
+ DisplayModesVariant modesVariant,
+ SchedulerCallbackImpl callbackImpl = SchedulerCallbackImpl::kNoOp,
+ VsyncTrackerCallbackImpl vsyncTrackerCallbackImpl = VsyncTrackerCallbackImpl::kNoOp,
+ bool useNiceMock = false) {
RefreshRateSelectorPtr selectorPtr = ftl::match(
modesVariant,
[](DefaultDisplayMode arg) {
@@ -239,10 +243,16 @@
mTokenManager = std::make_unique<frametimeline::impl::TokenManager>();
- using Callback = scheduler::ISchedulerCallback;
- Callback& callback = callbackImpl == SchedulerCallbackImpl::kNoOp
- ? static_cast<Callback&>(mNoOpSchedulerCallback)
- : static_cast<Callback&>(mSchedulerCallback);
+ using ISchedulerCallback = scheduler::ISchedulerCallback;
+ ISchedulerCallback& schedulerCallback = callbackImpl == SchedulerCallbackImpl::kNoOp
+ ? static_cast<ISchedulerCallback&>(mNoOpSchedulerCallback)
+ : static_cast<ISchedulerCallback&>(mSchedulerCallback);
+
+ using VsyncTrackerCallback = scheduler::IVsyncTrackerCallback;
+ VsyncTrackerCallback& vsyncTrackerCallback =
+ vsyncTrackerCallbackImpl == VsyncTrackerCallbackImpl::kNoOp
+ ? static_cast<VsyncTrackerCallback&>(mNoOpVsyncTrackerCallback)
+ : static_cast<VsyncTrackerCallback&>(mVsyncTrackerCallback);
auto modulatorPtr = sp<scheduler::VsyncModulator>::make(
mFlinger->mVsyncConfiguration->getCurrentConfigs());
@@ -253,12 +263,14 @@
std::move(vsyncTracker),
std::move(selectorPtr),
std::move(modulatorPtr),
- callback);
+ schedulerCallback,
+ vsyncTrackerCallback);
} else {
mScheduler = new scheduler::TestableScheduler(std::move(vsyncController),
std::move(vsyncTracker),
std::move(selectorPtr),
- std::move(modulatorPtr), callback);
+ std::move(modulatorPtr),
+ schedulerCallback, vsyncTrackerCallback);
}
mScheduler->initVsync(mScheduler->getVsyncSchedule()->getDispatch(), *mTokenManager, 0ms);
@@ -297,7 +309,8 @@
EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
setupScheduler(std::move(vsyncController), std::move(vsyncTracker), std::move(eventThread),
std::move(sfEventThread), DefaultDisplayMode{options.displayId},
- SchedulerCallbackImpl::kNoOp, options.useNiceMock);
+ SchedulerCallbackImpl::kNoOp, VsyncTrackerCallbackImpl::kNoOp,
+ options.useNiceMock);
}
void resetScheduler(scheduler::Scheduler* scheduler) { mFlinger->mScheduler.reset(scheduler); }
@@ -1071,6 +1084,8 @@
sp<SurfaceFlinger> mFlinger;
scheduler::mock::SchedulerCallback mSchedulerCallback;
scheduler::mock::NoOpSchedulerCallback mNoOpSchedulerCallback;
+ scheduler::mock::VsyncTrackerCallback mVsyncTrackerCallback;
+ scheduler::mock::NoOpVsyncTrackerCallback mNoOpVsyncTrackerCallback;
std::unique_ptr<frametimeline::impl::TokenManager> mTokenManager;
scheduler::TestableScheduler* mScheduler = nullptr;
Hwc2::mock::PowerAdvisor mPowerAdvisor;
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
index 41866a1..4be07a1 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
@@ -54,7 +54,7 @@
void resetModel() final {}
bool needsMoreSamples() const final { return false; }
bool isVSyncInPhase(nsecs_t, Fps) const final { return false; }
- void setRenderRate(Fps) final {}
+ void setDisplayModeData(const DisplayModeData&) final {}
void dump(std::string&) const final {}
private:
@@ -92,7 +92,7 @@
void resetModel() final {}
bool needsMoreSamples() const final { return false; }
bool isVSyncInPhase(nsecs_t, Fps) const final { return false; }
- void setRenderRate(Fps) final {}
+ void setDisplayModeData(const DisplayModeData&) final {}
void dump(std::string&) const final {}
private:
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
index 1dc5498..fbbb4a2 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
@@ -59,7 +59,7 @@
MOCK_METHOD0(resetModel, void());
MOCK_CONST_METHOD0(needsMoreSamples, bool());
MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
- MOCK_METHOD(void, setRenderRate, (Fps), (override));
+ MOCK_METHOD(void, setDisplayModeData, (const DisplayModeData&), (override));
MOCK_CONST_METHOD1(dump, void(std::string&));
nsecs_t nextVSyncTime(nsecs_t timePoint) const {
diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
index 43d683d..30a2855 100644
--- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
@@ -23,7 +23,9 @@
#define LOG_TAG "LibSurfaceFlingerUnittests"
#define LOG_NDEBUG 0
+#include "FlagUtils.h"
#include "Scheduler/VSyncPredictor.h"
+#include "mock/MockVsyncTrackerCallback.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -31,8 +33,11 @@
#include <chrono>
#include <utility>
+#include <com_android_graphics_surfaceflinger_flags.h>
+
using namespace testing;
using namespace std::literals;
+using namespace com::android::graphics::surfaceflinger;
namespace android::scheduler {
@@ -52,13 +57,18 @@
struct VSyncPredictorTest : testing::Test {
nsecs_t mNow = 0;
nsecs_t mPeriod = 1000;
+ scheduler::mock::VsyncTrackerCallback mVsyncTrackerCallback;
static constexpr size_t kHistorySize = 10;
static constexpr size_t kMinimumSamplesForPrediction = 6;
static constexpr size_t kOutlierTolerancePercent = 25;
static constexpr nsecs_t mMaxRoundingError = 100;
- VSyncPredictor tracker{DEFAULT_DISPLAY_ID, mPeriod, kHistorySize, kMinimumSamplesForPrediction,
- kOutlierTolerancePercent};
+ VSyncPredictor tracker{DEFAULT_DISPLAY_ID,
+ mPeriod,
+ kHistorySize,
+ kMinimumSamplesForPrediction,
+ kOutlierTolerancePercent,
+ mVsyncTrackerCallback};
};
TEST_F(VSyncPredictorTest, reportsAnticipatedPeriod) {
@@ -378,8 +388,12 @@
// See b/151146131
TEST_F(VSyncPredictorTest, hasEnoughPrecision) {
- VSyncPredictor tracker{DEFAULT_DISPLAY_ID, mPeriod, 20, kMinimumSamplesForPrediction,
- kOutlierTolerancePercent};
+ VSyncPredictor tracker{DEFAULT_DISPLAY_ID,
+ mPeriod,
+ 20,
+ kMinimumSamplesForPrediction,
+ kOutlierTolerancePercent,
+ mVsyncTrackerCallback};
std::vector<nsecs_t> const simulatedVsyncs{840873348817, 840890049444, 840906762675,
840923581635, 840940161584, 840956868096,
840973702473, 840990256277, 841007116851,
@@ -566,7 +580,7 @@
tracker.addVsyncTimestamp(mNow);
}
- tracker.setRenderRate(Fps::fromPeriodNsecs(3 * mPeriod));
+ tracker.setDisplayModeData({.renderRate = Fps::fromPeriodNsecs(3 * mPeriod)});
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 100), Eq(mNow + mPeriod));
@@ -588,12 +602,12 @@
const auto refreshRate = Fps::fromPeriodNsecs(mPeriod);
- tracker.setRenderRate(refreshRate / 4);
+ tracker.setDisplayModeData({.renderRate = refreshRate / 4});
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + 3 * mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 3 * mPeriod), Eq(mNow + 7 * mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 7 * mPeriod), Eq(mNow + 11 * mPeriod));
- tracker.setRenderRate(refreshRate / 2);
+ tracker.setDisplayModeData({.renderRate = refreshRate / 2});
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + 1 * mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 1 * mPeriod), Eq(mNow + 3 * mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 3 * mPeriod), Eq(mNow + 5 * mPeriod));
@@ -601,7 +615,7 @@
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 7 * mPeriod), Eq(mNow + 9 * mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 9 * mPeriod), Eq(mNow + 11 * mPeriod));
- tracker.setRenderRate(refreshRate / 6);
+ tracker.setDisplayModeData({.renderRate = refreshRate / 6});
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + 1 * mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 1 * mPeriod), Eq(mNow + 7 * mPeriod));
}
@@ -615,7 +629,7 @@
tracker.addVsyncTimestamp(mNow);
}
- tracker.setRenderRate(Fps::fromPeriodNsecs(3.5f * mPeriod));
+ tracker.setDisplayModeData({.renderRate = Fps::fromPeriodNsecs(3.5f * mPeriod)});
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 100), Eq(mNow + mPeriod));
@@ -626,6 +640,39 @@
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 5100), Eq(mNow + 6 * mPeriod));
}
+TEST_F(VSyncPredictorTest, vsyncTrackerCallback) {
+ SET_FLAG_FOR_TEST(flags::vrr_config, true);
+ const auto refreshRate = Fps::fromPeriodNsecs(mPeriod);
+ DisplayModeData displayModeData =
+ DisplayModeData{.renderRate = refreshRate,
+ .notifyExpectedPresentTimeoutOpt = Period::fromNs(30)};
+ tracker.setDisplayModeData(displayModeData);
+ auto last = mNow;
+ for (auto i = 0u; i < kMinimumSamplesForPrediction; i++) {
+ EXPECT_CALL(mVsyncTrackerCallback,
+ onVsyncGenerated(DEFAULT_DISPLAY_ID, TimePoint::fromNs(last + mPeriod),
+ displayModeData, Period::fromNs(mPeriod)))
+ .Times(1);
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(last + mPeriod));
+ mNow += mPeriod;
+ last = mNow;
+ tracker.addVsyncTimestamp(mNow);
+ }
+
+ displayModeData = DisplayModeData{.renderRate = refreshRate / 2,
+ .notifyExpectedPresentTimeoutOpt = Period::fromNs(30)};
+ tracker.setDisplayModeData(displayModeData);
+ {
+ // out of render rate phase
+ EXPECT_CALL(mVsyncTrackerCallback,
+ onVsyncGenerated(DEFAULT_DISPLAY_ID, TimePoint::fromNs(mNow + 3 * mPeriod),
+ displayModeData, Period::fromNs(mPeriod)))
+ .Times(1);
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 1 * mPeriod),
+ Eq(mNow + 3 * mPeriod));
+ }
+}
+
} // namespace android::scheduler
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
index 122192b..aca3ccc 100644
--- a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
@@ -50,7 +50,7 @@
MOCK_METHOD0(resetModel, void());
MOCK_CONST_METHOD0(needsMoreSamples, bool());
MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
- MOCK_METHOD(void, setRenderRate, (Fps), (override));
+ MOCK_METHOD(void, setDisplayModeData, (const DisplayModeData&), (override));
MOCK_CONST_METHOD1(dump, void(std::string&));
};
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
index dcf25e1..31eb86e 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
@@ -34,7 +34,7 @@
MOCK_METHOD0(resetModel, void());
MOCK_CONST_METHOD0(needsMoreSamples, bool());
MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
- MOCK_METHOD(void, setRenderRate, (Fps), (override));
+ MOCK_METHOD(void, setDisplayModeData, (const scheduler::DisplayModeData&), (override));
MOCK_CONST_METHOD1(dump, void(std::string&));
};
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVsyncTrackerCallback.h b/services/surfaceflinger/tests/unittests/mock/MockVsyncTrackerCallback.h
new file mode 100644
index 0000000..b8e24e0
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/mock/MockVsyncTrackerCallback.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2023 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 <gmock/gmock.h>
+
+#include "Scheduler/VSyncTracker.h"
+
+namespace android::scheduler::mock {
+
+struct VsyncTrackerCallback final : IVsyncTrackerCallback {
+ MOCK_METHOD(void, onVsyncGenerated,
+ (PhysicalDisplayId, TimePoint, const scheduler::DisplayModeData&, Period),
+ (override));
+};
+
+struct NoOpVsyncTrackerCallback final : IVsyncTrackerCallback {
+ void onVsyncGenerated(PhysicalDisplayId, TimePoint, const scheduler::DisplayModeData&,
+ Period) override{};
+};
+} // namespace android::scheduler::mock