summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdy Abraham <adyabr@google.com>2023-11-15 18:41:35 -0800
committerAdy Abraham <adyabr@google.com>2023-11-21 15:22:34 -0800
commitc585dbac703f85d2febc9b7f31dd797bc2b04d81 (patch)
tree5f0bb60ce1e08b48e1f10985493586976b28a099
parent43881b0fa27a23422041337c89d95098a2d4b618 (diff)
downloadnative-c585dbac703f85d2febc9b7f31dd797bc2b04d81.tar.gz
SF: pass DisplayMode to VsyncTracker
This will be used later to get the peak refresh rate from the predictor for sub-frame jank recover in VRR case. Bug: 296635687 Test: presubmit Change-Id: I1e108223b6ae4872bb48a38e4af743da565749cd
-rw-r--r--services/surfaceflinger/Scheduler/Android.bp1
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.cpp30
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.h12
-rw-r--r--services/surfaceflinger/Scheduler/VSyncPredictor.cpp116
-rw-r--r--services/surfaceflinger/Scheduler/VSyncPredictor.h22
-rw-r--r--services/surfaceflinger/Scheduler/VSyncReactor.cpp35
-rw-r--r--services/surfaceflinger/Scheduler/VSyncReactor.h7
-rw-r--r--services/surfaceflinger/Scheduler/VSyncTracker.h43
-rw-r--r--services/surfaceflinger/Scheduler/VsyncController.h10
-rw-r--r--services/surfaceflinger/Scheduler/VsyncSchedule.cpp22
-rw-r--r--services/surfaceflinger/Scheduler/VsyncSchedule.h15
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp38
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h4
-rw-r--r--services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h3
-rw-r--r--services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp19
-rw-r--r--services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h6
-rw-r--r--services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp8
-rw-r--r--services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp8
-rw-r--r--services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp13
-rw-r--r--services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp111
-rw-r--r--services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp83
-rw-r--r--services/surfaceflinger/tests/unittests/VsyncScheduleTest.cpp20
-rw-r--r--services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplayMode.h1
-rw-r--r--services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h18
-rw-r--r--services/surfaceflinger/tests/unittests/mock/MockVsyncController.h2
-rw-r--r--services/surfaceflinger/tests/unittests/mock/MockVsyncTrackerCallback.h7
26 files changed, 341 insertions, 313 deletions
diff --git a/services/surfaceflinger/Scheduler/Android.bp b/services/surfaceflinger/Scheduler/Android.bp
index 6d2586ae9c..db247aaebc 100644
--- a/services/surfaceflinger/Scheduler/Android.bp
+++ b/services/surfaceflinger/Scheduler/Android.bp
@@ -21,6 +21,7 @@ cc_defaults {
"libui",
"libutils",
],
+ static_libs: ["libsurfaceflinger_common"],
}
cc_library_headers {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index b54f33451b..29b1d62956 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -118,7 +118,7 @@ void Scheduler::setPacesetterDisplay(std::optional<PhysicalDisplayId> pacesetter
void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr) {
auto schedulePtr = std::make_shared<VsyncSchedule>(
- displayId, mFeatures,
+ selectorPtr->getActiveMode().modePtr, mFeatures,
[this](PhysicalDisplayId id, bool enable) { onHardwareVsyncRequest(id, enable); },
mVsyncTrackerCallback);
@@ -503,7 +503,7 @@ void Scheduler::resyncAllToHardwareVsync(bool allowToEnable) {
}
void Scheduler::resyncToHardwareVsyncLocked(PhysicalDisplayId id, bool allowToEnable,
- std::optional<Fps> refreshRate) {
+ DisplayModePtr modePtr) {
const auto displayOpt = mDisplays.get(id);
if (!displayOpt) {
ALOGW("%s: Invalid display %s!", __func__, to_string(id).c_str());
@@ -512,12 +512,12 @@ void Scheduler::resyncToHardwareVsyncLocked(PhysicalDisplayId id, bool allowToEn
const Display& display = *displayOpt;
if (display.schedulePtr->isHardwareVsyncAllowed(allowToEnable)) {
- if (!refreshRate) {
- refreshRate = display.selectorPtr->getActiveMode().modePtr->getVsyncRate();
+ if (!modePtr) {
+ modePtr = display.selectorPtr->getActiveMode().modePtr.get();
}
- if (refreshRate->isValid()) {
+ if (modePtr->getVsyncRate().isValid()) {
constexpr bool kForce = false;
- display.schedulePtr->startPeriodTransition(refreshRate->getPeriod(), kForce);
+ display.schedulePtr->onDisplayModeChanged(ftl::as_non_null(modePtr), kForce);
}
}
}
@@ -563,19 +563,7 @@ void Scheduler::setRenderRate(PhysicalDisplayId id, Fps renderFrameRate) {
ALOGV("%s %s (%s)", __func__, to_string(mode.fps).c_str(),
to_string(mode.modePtr->getVsyncRate()).c_str());
- 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;
- }
+ display.schedulePtr->getTracker().setRenderRate(renderFrameRate);
}
void Scheduler::resync() {
@@ -913,9 +901,9 @@ std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked(
newVsyncSchedulePtr = pacesetter.schedulePtr;
- const Fps refreshRate = pacesetter.selectorPtr->getActiveMode().modePtr->getVsyncRate();
constexpr bool kForce = true;
- newVsyncSchedulePtr->startPeriodTransition(refreshRate.getPeriod(), kForce);
+ newVsyncSchedulePtr->onDisplayModeChanged(pacesetter.selectorPtr->getActiveMode().modePtr,
+ kForce);
}
return newVsyncSchedulePtr;
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index c78051a278..0615b31c10 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -210,13 +210,12 @@ public:
// If allowToEnable is true, then hardware vsync will be turned on.
// Otherwise, if hardware vsync is not already enabled then this method will
// no-op.
- // If refreshRate is nullopt, use the existing refresh rate of the display.
+ // If modePtr is nullopt, use the active display mode.
void resyncToHardwareVsync(PhysicalDisplayId id, bool allowToEnable,
- std::optional<Fps> refreshRate = std::nullopt)
- EXCLUDES(mDisplayLock) {
+ DisplayModePtr modePtr = nullptr) EXCLUDES(mDisplayLock) {
std::scoped_lock lock(mDisplayLock);
ftl::FakeGuard guard(kMainThreadContext);
- resyncToHardwareVsyncLocked(id, allowToEnable, refreshRate);
+ resyncToHardwareVsyncLocked(id, allowToEnable, modePtr);
}
void forceNextResync() { mLastResyncTime = 0; }
@@ -354,7 +353,7 @@ private:
void onHardwareVsyncRequest(PhysicalDisplayId, bool enable);
void resyncToHardwareVsyncLocked(PhysicalDisplayId, bool allowToEnable,
- std::optional<Fps> refreshRate = std::nullopt)
+ DisplayModePtr modePtr = nullptr)
REQUIRES(kMainThreadContext, mDisplayLock);
void resyncAllToHardwareVsync(bool allowToEnable) EXCLUDES(mDisplayLock);
void setVsyncConfig(const VsyncConfig&, Period vsyncPeriod);
@@ -431,9 +430,6 @@ private:
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;
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index f5f93ce2f1..acb7265fc5 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -47,16 +47,16 @@ static auto constexpr kMaxPercent = 100u;
VSyncPredictor::~VSyncPredictor() = default;
-VSyncPredictor::VSyncPredictor(PhysicalDisplayId id, nsecs_t idealPeriod, size_t historySize,
+VSyncPredictor::VSyncPredictor(ftl::NonNull<DisplayModePtr> modePtr, size_t historySize,
size_t minimumSamplesForPrediction, uint32_t outlierTolerancePercent,
IVsyncTrackerCallback& callback)
- : mId(id),
+ : mId(modePtr->getPhysicalDisplayId()),
mTraceOn(property_get_bool("debug.sf.vsp_trace", false)),
kHistorySize(historySize),
kMinimumSamplesForPrediction(minimumSamplesForPrediction),
kOutlierTolerancePercent(std::min(outlierTolerancePercent, kMaxPercent)),
mVsyncTrackerCallback(callback),
- mIdealPeriod(idealPeriod) {
+ mDisplayModePtr(modePtr) {
resetModel();
}
@@ -74,13 +74,18 @@ inline size_t VSyncPredictor::next(size_t i) const {
return (i + 1) % mTimestamps.size();
}
+nsecs_t VSyncPredictor::idealPeriod() const {
+ return mDisplayModePtr->getVsyncRate().getPeriodNsecs();
+}
+
bool VSyncPredictor::validate(nsecs_t timestamp) const {
if (mLastTimestampIndex < 0 || mTimestamps.empty()) {
return true;
}
- auto const aValidTimestamp = mTimestamps[mLastTimestampIndex];
- auto const percent = (timestamp - aValidTimestamp) % mIdealPeriod * kMaxPercent / mIdealPeriod;
+ const auto aValidTimestamp = mTimestamps[mLastTimestampIndex];
+ const auto percent =
+ (timestamp - aValidTimestamp) % idealPeriod() * kMaxPercent / idealPeriod();
if (percent >= kOutlierTolerancePercent &&
percent <= (kMaxPercent - kOutlierTolerancePercent)) {
return false;
@@ -90,7 +95,7 @@ bool VSyncPredictor::validate(nsecs_t timestamp) const {
[timestamp](nsecs_t a, nsecs_t b) {
return std::abs(timestamp - a) < std::abs(timestamp - b);
});
- const auto distancePercent = std::abs(*iter - timestamp) * kMaxPercent / mIdealPeriod;
+ const auto distancePercent = std::abs(*iter - timestamp) * kMaxPercent / idealPeriod();
if (distancePercent < kOutlierTolerancePercent) {
// duplicate timestamp
return false;
@@ -100,7 +105,7 @@ bool VSyncPredictor::validate(nsecs_t timestamp) const {
nsecs_t VSyncPredictor::currentPeriod() const {
std::lock_guard lock(mMutex);
- return mRateMap.find(mIdealPeriod)->second.slope;
+ return mRateMap.find(idealPeriod())->second.slope;
}
bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
@@ -137,7 +142,7 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
const size_t numSamples = mTimestamps.size();
if (numSamples < kMinimumSamplesForPrediction) {
- mRateMap[mIdealPeriod] = {mIdealPeriod, 0};
+ mRateMap[idealPeriod()] = {idealPeriod(), 0};
return true;
}
@@ -161,7 +166,7 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
// Normalizing to the oldest timestamp cuts down on error in calculating the intercept.
const auto oldestTS = *std::min_element(mTimestamps.begin(), mTimestamps.end());
- auto it = mRateMap.find(mIdealPeriod);
+ auto it = mRateMap.find(idealPeriod());
auto const currentPeriod = it->second.slope;
// The mean of the ordinals must be precise for the intercept calculation, so scale them up for
@@ -199,7 +204,7 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
}
if (CC_UNLIKELY(bottom == 0)) {
- it->second = {mIdealPeriod, 0};
+ it->second = {idealPeriod(), 0};
clearTimestamps();
return false;
}
@@ -207,9 +212,9 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
nsecs_t const anticipatedPeriod = top * kScalingFactor / bottom;
nsecs_t const intercept = meanTS - (anticipatedPeriod * meanOrdinal / kScalingFactor);
- auto const percent = std::abs(anticipatedPeriod - mIdealPeriod) * kMaxPercent / mIdealPeriod;
+ auto const percent = std::abs(anticipatedPeriod - idealPeriod()) * kMaxPercent / idealPeriod();
if (percent >= kOutlierTolerancePercent) {
- it->second = {mIdealPeriod, 0};
+ it->second = {idealPeriod(), 0};
clearTimestamps();
return false;
}
@@ -241,8 +246,8 @@ nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFromLocked(nsecs_t timePoint) co
if (mTimestamps.empty()) {
traceInt64("VSP-mode", 1);
auto const knownTimestamp = mKnownTimestamp ? *mKnownTimestamp : timePoint;
- auto const numPeriodsOut = ((timePoint - knownTimestamp) / mIdealPeriod) + 1;
- return knownTimestamp + numPeriodsOut * mIdealPeriod;
+ auto const numPeriodsOut = ((timePoint - knownTimestamp) / idealPeriod()) + 1;
+ return knownTimestamp + numPeriodsOut * idealPeriod();
}
auto const oldest = *std::min_element(mTimestamps.begin(), mTimestamps.end());
@@ -278,11 +283,11 @@ nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const {
mLastVsyncSequence = getVsyncSequenceLocked(timePoint);
const auto renderRatePhase = [&]() REQUIRES(mMutex) -> int {
- if (!mDisplayModeDataOpt) return 0;
+ if (!mRenderRateOpt) return 0;
const auto divisor =
- RefreshRateSelector::getFrameRateDivisor(Fps::fromPeriodNsecs(mIdealPeriod),
- mDisplayModeDataOpt->renderRate);
+ RefreshRateSelector::getFrameRateDivisor(Fps::fromPeriodNsecs(idealPeriod()),
+ *mRenderRateOpt);
if (divisor <= 1) return 0;
const int mod = mLastVsyncSequence->seq % divisor;
@@ -293,12 +298,12 @@ nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const {
if (renderRatePhase == 0) {
const auto vsyncTime = mLastVsyncSequence->vsyncTime;
- if (FlagManager::getInstance().vrr_config() && mDisplayModeDataOpt) {
+ if (FlagManager::getInstance().vrr_config()) {
const auto vsyncTimePoint = TimePoint::fromNs(vsyncTime);
ATRACE_FORMAT("%s InPhase vsyncIn %.2fms", __func__,
ticks<std::milli, float>(vsyncTimePoint - TimePoint::now()));
- mVsyncTrackerCallback.onVsyncGenerated(mId, vsyncTimePoint, *mDisplayModeDataOpt,
- Period::fromNs(mIdealPeriod));
+ const Fps renderRate = mRenderRateOpt ? *mRenderRateOpt : mDisplayModePtr->getPeakFps();
+ mVsyncTrackerCallback.onVsyncGenerated(vsyncTimePoint, mDisplayModePtr, renderRate);
}
return vsyncTime;
}
@@ -307,12 +312,13 @@ nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const {
const auto approximateNextVsync = mLastVsyncSequence->vsyncTime + slope * renderRatePhase;
const auto nextAnticipatedVsyncTime =
nextAnticipatedVSyncTimeFromLocked(approximateNextVsync - slope / 2);
- if (FlagManager::getInstance().vrr_config() && mDisplayModeDataOpt) {
+ if (FlagManager::getInstance().vrr_config()) {
const auto nextAnticipatedVsyncTimePoint = TimePoint::fromNs(nextAnticipatedVsyncTime);
ATRACE_FORMAT("%s outOfPhase vsyncIn %.2fms", __func__,
ticks<std::milli, float>(nextAnticipatedVsyncTimePoint - TimePoint::now()));
- mVsyncTrackerCallback.onVsyncGenerated(mId, nextAnticipatedVsyncTimePoint,
- *mDisplayModeDataOpt, Period::fromNs(mIdealPeriod));
+ const Fps renderRate = mRenderRateOpt ? *mRenderRateOpt : mDisplayModePtr->getPeakFps();
+ mVsyncTrackerCallback.onVsyncGenerated(nextAnticipatedVsyncTimePoint, mDisplayModePtr,
+ renderRate);
}
return nextAnticipatedVsyncTime;
}
@@ -328,7 +334,8 @@ nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const {
bool VSyncPredictor::isVSyncInPhase(nsecs_t timePoint, Fps frameRate) const {
std::lock_guard lock(mMutex);
const auto divisor =
- RefreshRateSelector::getFrameRateDivisor(Fps::fromPeriodNsecs(mIdealPeriod), frameRate);
+ RefreshRateSelector::getFrameRateDivisor(Fps::fromPeriodNsecs(idealPeriod()),
+ frameRate);
return isVSyncInPhaseLocked(timePoint, static_cast<unsigned>(divisor));
}
@@ -344,7 +351,7 @@ bool VSyncPredictor::isVSyncInPhaseLocked(nsecs_t timePoint, unsigned divisor) c
return true;
}
- const nsecs_t period = mRateMap[mIdealPeriod].slope;
+ const nsecs_t period = mRateMap[idealPeriod()].slope;
const nsecs_t justBeforeTimePoint = timePoint - period / 2;
const auto vsyncSequence = getVsyncSequenceLocked(justBeforeTimePoint);
ATRACE_FORMAT_INSTANT("vsync in: %.2f sequence: %" PRId64,
@@ -352,45 +359,50 @@ bool VSyncPredictor::isVSyncInPhaseLocked(nsecs_t timePoint, unsigned divisor) c
return vsyncSequence.seq % divisor == 0;
}
-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");
+void VSyncPredictor::setRenderRate(Fps renderRate) {
+ ATRACE_FORMAT("%s %s", __func__, to_string(renderRate).c_str());
+ ALOGV("%s %s: RenderRate %s ", __func__, to_string(mId).c_str(), to_string(renderRate).c_str());
std::lock_guard lock(mMutex);
- mDisplayModeDataOpt = displayModeData;
+ mRenderRateOpt = renderRate;
}
-VSyncPredictor::Model VSyncPredictor::getVSyncPredictionModel() const {
+void VSyncPredictor::setDisplayModePtr(ftl::NonNull<DisplayModePtr> modePtr) {
+ LOG_ALWAYS_FATAL_IF(mId != modePtr->getPhysicalDisplayId(),
+ "mode does not belong to the display");
+ ATRACE_FORMAT("%s %s", __func__, to_string(*modePtr).c_str());
+ const auto timeout = modePtr->getVrrConfig()
+ ? modePtr->getVrrConfig()->notifyExpectedPresentConfig
+ : std::nullopt;
+ ALOGV("%s %s: DisplayMode %s notifyExpectedPresentTimeout %s", __func__, to_string(mId).c_str(),
+ to_string(*modePtr).c_str(),
+ timeout ? std::to_string(timeout->notifyExpectedPresentTimeoutNs).c_str() : "N/A");
std::lock_guard lock(mMutex);
- const auto model = VSyncPredictor::getVSyncPredictionModelLocked();
- return {model.slope, model.intercept};
-}
-VSyncPredictor::Model VSyncPredictor::getVSyncPredictionModelLocked() const {
- return mRateMap.find(mIdealPeriod)->second;
-}
+ mDisplayModePtr = modePtr;
+ traceInt64("VSP-setPeriod", modePtr->getVsyncRate().getPeriodNsecs());
-void VSyncPredictor::setPeriod(nsecs_t period) {
- ATRACE_FORMAT("%s %s", __func__, to_string(mId).c_str());
- traceInt64("VSP-setPeriod", period);
-
- std::lock_guard lock(mMutex);
static constexpr size_t kSizeLimit = 30;
if (CC_UNLIKELY(mRateMap.size() == kSizeLimit)) {
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};
+ if (mRateMap.find(idealPeriod()) == mRateMap.end()) {
+ mRateMap[idealPeriod()] = {idealPeriod(), 0};
}
clearTimestamps();
}
+VSyncPredictor::Model VSyncPredictor::getVSyncPredictionModel() const {
+ std::lock_guard lock(mMutex);
+ const auto model = VSyncPredictor::getVSyncPredictionModelLocked();
+ return {model.slope, model.intercept};
+}
+
+VSyncPredictor::Model VSyncPredictor::getVSyncPredictionModelLocked() const {
+ return mRateMap.find(idealPeriod())->second;
+}
+
void VSyncPredictor::clearTimestamps() {
if (!mTimestamps.empty()) {
auto const maxRb = *std::max_element(mTimestamps.begin(), mTimestamps.end());
@@ -412,18 +424,18 @@ bool VSyncPredictor::needsMoreSamples() const {
void VSyncPredictor::resetModel() {
std::lock_guard lock(mMutex);
- mRateMap[mIdealPeriod] = {mIdealPeriod, 0};
+ mRateMap[idealPeriod()] = {idealPeriod(), 0};
clearTimestamps();
}
void VSyncPredictor::dump(std::string& result) const {
std::lock_guard lock(mMutex);
- StringAppendF(&result, "\tmIdealPeriod=%.2f\n", mIdealPeriod / 1e6f);
+ StringAppendF(&result, "\tmDisplayModePtr=%s\n", to_string(*mDisplayModePtr).c_str());
StringAppendF(&result, "\tRefresh Rate Map:\n");
- for (const auto& [idealPeriod, periodInterceptTuple] : mRateMap) {
+ for (const auto& [period, periodInterceptTuple] : mRateMap) {
StringAppendF(&result,
"\t\tFor ideal period %.2fms: period = %.2fms, intercept = %" PRId64 "\n",
- idealPeriod / 1e6f, periodInterceptTuple.slope / 1e6f,
+ period / 1e6f, periodInterceptTuple.slope / 1e6f,
periodInterceptTuple.intercept);
}
}
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.h b/services/surfaceflinger/Scheduler/VSyncPredictor.h
index c271eb738e..fbc1e1665e 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.h
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.h
@@ -31,14 +31,14 @@ class VSyncPredictor : public VSyncTracker {
public:
/*
* \param [in] PhysicalDisplayid The display this corresponds to.
- * \param [in] idealPeriod The initial ideal period to use.
+ * \param [in] modePtr The initial display mode
* \param [in] historySize The internal amount of entries to store in the model.
* \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,
+ VSyncPredictor(ftl::NonNull<DisplayModePtr> modePtr, size_t historySize,
size_t minimumSamplesForPrediction, uint32_t outlierTolerancePercent,
IVsyncTrackerCallback&);
~VSyncPredictor();
@@ -48,15 +48,6 @@ public:
nsecs_t currentPeriod() const final EXCLUDES(mMutex);
void resetModel() final EXCLUDES(mMutex);
- /*
- * Inform the model that the period is anticipated to change to a new value.
- * model will use the period parameter to predict vsync events until enough
- * timestamps with the new period have been collected.
- *
- * \param [in] period The new period that should be used.
- */
- void setPeriod(nsecs_t period) final EXCLUDES(mMutex);
-
/* Query if the model is in need of more samples to make a prediction.
* \return True, if model would benefit from more samples, False if not.
*/
@@ -71,7 +62,9 @@ public:
bool isVSyncInPhase(nsecs_t timePoint, Fps frameRate) const final EXCLUDES(mMutex);
- void setDisplayModeData(const DisplayModeData&) final EXCLUDES(mMutex);
+ void setDisplayModePtr(ftl::NonNull<DisplayModePtr>) final EXCLUDES(mMutex);
+
+ void setRenderRate(Fps) final EXCLUDES(mMutex);
void dump(std::string& result) const final EXCLUDES(mMutex);
@@ -96,6 +89,7 @@ private:
int64_t seq;
};
VsyncSequence getVsyncSequenceLocked(nsecs_t timestamp) const REQUIRES(mMutex);
+ nsecs_t idealPeriod() const REQUIRES(mMutex);
bool const mTraceOn;
size_t const kHistorySize;
@@ -104,7 +98,6 @@ private:
IVsyncTrackerCallback& mVsyncTrackerCallback;
std::mutex mutable mMutex;
- nsecs_t mIdealPeriod GUARDED_BY(mMutex);
std::optional<nsecs_t> mKnownTimestamp GUARDED_BY(mMutex);
// Map between ideal vsync period and the calculated model
@@ -113,7 +106,8 @@ private:
size_t mLastTimestampIndex GUARDED_BY(mMutex) = 0;
std::vector<nsecs_t> mTimestamps GUARDED_BY(mMutex);
- std::optional<DisplayModeData> mDisplayModeDataOpt GUARDED_BY(mMutex);
+ ftl::NonNull<DisplayModePtr> mDisplayModePtr GUARDED_BY(mMutex);
+ std::optional<Fps> mRenderRateOpt GUARDED_BY(mMutex);
mutable std::optional<VsyncSequence> mLastVsyncSequence GUARDED_BY(mMutex);
};
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index 2938aa3fb3..24737e4fb2 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -116,32 +116,34 @@ void VSyncReactor::updateIgnorePresentFencesInternal() {
}
}
-void VSyncReactor::startPeriodTransitionInternal(nsecs_t newPeriod) {
+void VSyncReactor::startPeriodTransitionInternal(ftl::NonNull<DisplayModePtr> modePtr) {
ATRACE_FORMAT("%s %" PRIu64, __func__, mId.value);
mPeriodConfirmationInProgress = true;
- mPeriodTransitioningTo = newPeriod;
+ mModePtrTransitioningTo = modePtr.get();
mMoreSamplesNeeded = true;
setIgnorePresentFencesInternal(true);
}
void VSyncReactor::endPeriodTransition() {
ATRACE_FORMAT("%s %" PRIu64, __func__, mId.value);
- mPeriodTransitioningTo.reset();
+ mModePtrTransitioningTo.reset();
mPeriodConfirmationInProgress = false;
mLastHwVsync.reset();
}
-void VSyncReactor::startPeriodTransition(nsecs_t period, bool force) {
- ATRACE_INT64(ftl::Concat("VSR-", __func__, " ", mId.value).c_str(), period);
+void VSyncReactor::onDisplayModeChanged(ftl::NonNull<DisplayModePtr> modePtr, bool force) {
+ ATRACE_INT64(ftl::Concat("VSR-", __func__, " ", mId.value).c_str(),
+ modePtr->getVsyncRate().getPeriodNsecs());
std::lock_guard lock(mMutex);
mLastHwVsync.reset();
- if (!mSupportKernelIdleTimer && period == mTracker.currentPeriod() && !force) {
+ if (!mSupportKernelIdleTimer &&
+ modePtr->getVsyncRate().getPeriodNsecs() == mTracker.currentPeriod() && !force) {
endPeriodTransition();
setIgnorePresentFencesInternal(false);
mMoreSamplesNeeded = false;
} else {
- startPeriodTransitionInternal(period);
+ startPeriodTransitionInternal(modePtr);
}
}
@@ -159,14 +161,16 @@ bool VSyncReactor::periodConfirmed(nsecs_t vsync_timestamp, std::optional<nsecs_
return false;
}
- const bool periodIsChanging =
- mPeriodTransitioningTo && (*mPeriodTransitioningTo != mTracker.currentPeriod());
+ const std::optional<Period> newPeriod = mModePtrTransitioningTo
+ ? mModePtrTransitioningTo->getVsyncRate().getPeriod()
+ : std::optional<Period>{};
+ const bool periodIsChanging = newPeriod && (newPeriod->ns() != mTracker.currentPeriod());
if (mSupportKernelIdleTimer && !periodIsChanging) {
// Clear out the Composer-provided period and use the allowance logic below
HwcVsyncPeriod = {};
}
- auto const period = mPeriodTransitioningTo ? *mPeriodTransitioningTo : mTracker.currentPeriod();
+ auto const period = newPeriod ? newPeriod->ns() : mTracker.currentPeriod();
static constexpr int allowancePercent = 10;
static constexpr std::ratio<allowancePercent, 100> allowancePercentRatio;
auto const allowance = period * allowancePercentRatio.num / allowancePercentRatio.den;
@@ -185,8 +189,8 @@ bool VSyncReactor::addHwVsyncTimestamp(nsecs_t timestamp, std::optional<nsecs_t>
std::lock_guard lock(mMutex);
if (periodConfirmed(timestamp, hwcVsyncPeriod)) {
ATRACE_FORMAT("VSR %" PRIu64 ": period confirmed", mId.value);
- if (mPeriodTransitioningTo) {
- mTracker.setPeriod(*mPeriodTransitioningTo);
+ if (mModePtrTransitioningTo) {
+ mTracker.setDisplayModePtr(ftl::as_non_null(mModePtrTransitioningTo));
*periodFlushed = true;
}
@@ -228,10 +232,11 @@ void VSyncReactor::dump(std::string& result) const {
mInternalIgnoreFences, mExternalIgnoreFences);
StringAppendF(&result, "mMoreSamplesNeeded=%d mPeriodConfirmationInProgress=%d\n",
mMoreSamplesNeeded, mPeriodConfirmationInProgress);
- if (mPeriodTransitioningTo) {
- StringAppendF(&result, "mPeriodTransitioningTo=%" PRId64 "\n", *mPeriodTransitioningTo);
+ if (mModePtrTransitioningTo) {
+ StringAppendF(&result, "mModePtrTransitioningTo=%s\n",
+ to_string(*mModePtrTransitioningTo).c_str());
} else {
- StringAppendF(&result, "mPeriodTransitioningTo=nullptr\n");
+ StringAppendF(&result, "mModePtrTransitioningTo=nullptr\n");
}
if (mLastHwVsync) {
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.h b/services/surfaceflinger/Scheduler/VSyncReactor.h
index f2302422ad..2415a66a64 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.h
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.h
@@ -27,6 +27,7 @@
#include <scheduler/TimeKeeper.h>
+#include "VSyncTracker.h"
#include "VsyncController.h"
namespace android::scheduler {
@@ -45,7 +46,7 @@ public:
bool addPresentFence(std::shared_ptr<FenceTime>) final;
void setIgnorePresentFences(bool ignore) final;
- void startPeriodTransition(nsecs_t period, bool force) final;
+ void onDisplayModeChanged(ftl::NonNull<DisplayModePtr>, bool force) final;
bool addHwVsyncTimestamp(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
bool* periodFlushed) final;
@@ -57,7 +58,7 @@ public:
private:
void setIgnorePresentFencesInternal(bool ignore) REQUIRES(mMutex);
void updateIgnorePresentFencesInternal() REQUIRES(mMutex);
- void startPeriodTransitionInternal(nsecs_t newPeriod) REQUIRES(mMutex);
+ void startPeriodTransitionInternal(ftl::NonNull<DisplayModePtr>) REQUIRES(mMutex);
void endPeriodTransition() REQUIRES(mMutex);
bool periodConfirmed(nsecs_t vsync_timestamp, std::optional<nsecs_t> hwcVsyncPeriod)
REQUIRES(mMutex);
@@ -74,7 +75,7 @@ private:
bool mMoreSamplesNeeded GUARDED_BY(mMutex) = false;
bool mPeriodConfirmationInProgress GUARDED_BY(mMutex) = false;
- std::optional<nsecs_t> mPeriodTransitioningTo GUARDED_BY(mMutex);
+ DisplayModePtr mModePtrTransitioningTo GUARDED_BY(mMutex);
std::optional<nsecs_t> mLastHwVsync GUARDED_BY(mMutex);
hal::PowerMode mDisplayPowerMode GUARDED_BY(mMutex) = hal::PowerMode::ON;
diff --git a/services/surfaceflinger/Scheduler/VSyncTracker.h b/services/surfaceflinger/Scheduler/VSyncTracker.h
index 7eedc312e2..2ae5c0b5ce 100644
--- a/services/surfaceflinger/Scheduler/VSyncTracker.h
+++ b/services/surfaceflinger/Scheduler/VSyncTracker.h
@@ -20,25 +20,16 @@
#include <utils/Timers.h>
#include <scheduler/Fps.h>
+#include <scheduler/FrameRateMode.h>
#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;
+ virtual void onVsyncGenerated(TimePoint expectedPresentTime, ftl::NonNull<DisplayModePtr>,
+ Fps renderRate) = 0;
};
/*
@@ -77,13 +68,6 @@ public:
*/
virtual nsecs_t currentPeriod() const = 0;
- /*
- * Inform the tracker that the period is changing and the tracker needs to recalibrate itself.
- *
- * \param [in] period The period that the system is changing into.
- */
- virtual void setPeriod(nsecs_t period) = 0;
-
/* Inform the tracker that the samples it has are not accurate for prediction. */
virtual void resetModel() = 0;
@@ -98,20 +82,25 @@ public:
virtual bool isVSyncInPhase(nsecs_t timePoint, Fps frameRate) const = 0;
/*
- * 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.
+ * Sets the active mode of the display which includes the vsync period and other VRR attributes.
+ * This will inform the tracker that the period is changing and the tracker needs to recalibrate
+ * itself.
+ *
+ * \param [in] DisplayModePtr The display mode the tracker will use.
+ */
+ virtual void setDisplayModePtr(ftl::NonNull<DisplayModePtr>) = 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.
* 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] DisplayModeData The DisplayModeData the tracker will use.
+ * \param [in] Fps The render rate the tracker should operate at.
*/
- virtual void setDisplayModeData(const DisplayModeData&) = 0;
+ virtual void setRenderRate(Fps) = 0;
virtual void dump(std::string& result) const = 0;
diff --git a/services/surfaceflinger/Scheduler/VsyncController.h b/services/surfaceflinger/Scheduler/VsyncController.h
index 917789934a..807a7fba53 100644
--- a/services/surfaceflinger/Scheduler/VsyncController.h
+++ b/services/surfaceflinger/Scheduler/VsyncController.h
@@ -22,6 +22,7 @@
#include <DisplayHardware/HWComposer.h>
#include <DisplayHardware/Hal.h>
+#include <scheduler/FrameRateMode.h>
#include <ui/FenceTime.h>
#include <utils/Mutex.h>
#include <utils/RefBase.h>
@@ -59,13 +60,14 @@ public:
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.
+ * Inform the controller that the display mode is changing and the controller needs to
+ * recalibrate itself to the new vsync period. The controller will end the period transition
+ * internally.
*
- * \param [in] period The period that the system is changing into.
+ * \param [in] DisplayModePtr The new mode the display is changing to.
* \param [in] force True to recalibrate even if period matches the existing period.
*/
- virtual void startPeriodTransition(nsecs_t period, bool force) = 0;
+ virtual void onDisplayModeChanged(ftl::NonNull<DisplayModePtr>, bool force) = 0;
/*
* Tells the tracker to stop using present fences to get a vsync signal.
diff --git a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
index 5fb53f9e20..4a8aac606b 100644
--- a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
+++ b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
@@ -16,6 +16,8 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <common/FlagManager.h>
+
#include <ftl/fake_guard.h>
#include <scheduler/Fps.h>
#include <scheduler/Timer.h>
@@ -53,14 +55,14 @@ private:
VSyncCallbackRegistration mRegistration;
};
-VsyncSchedule::VsyncSchedule(PhysicalDisplayId id, FeatureFlags features,
+VsyncSchedule::VsyncSchedule(ftl::NonNull<DisplayModePtr> modePtr, FeatureFlags features,
RequestHardwareVsync requestHardwareVsync,
IVsyncTrackerCallback& callback)
- : mId(id),
+ : mId(modePtr->getPhysicalDisplayId()),
mRequestHardwareVsync(std::move(requestHardwareVsync)),
- mTracker(createTracker(id, callback)),
+ mTracker(createTracker(modePtr, callback)),
mDispatch(createDispatch(mTracker)),
- mController(createController(id, *mTracker, features)),
+ mController(createController(modePtr->getPhysicalDisplayId(), *mTracker, features)),
mTracer(features.test(Feature::kTracePredictedVsync)
? std::make_unique<PredictedVsyncTracer>(mDispatch)
: nullptr) {}
@@ -101,17 +103,15 @@ void VsyncSchedule::dump(std::string& out) const {
mDispatch->dump(out);
}
-VsyncSchedule::TrackerPtr VsyncSchedule::createTracker(PhysicalDisplayId id,
+VsyncSchedule::TrackerPtr VsyncSchedule::createTracker(ftl::NonNull<DisplayModePtr> modePtr,
IVsyncTrackerCallback& callback) {
// TODO(b/144707443): Tune constants.
- constexpr nsecs_t kInitialPeriod = (60_Hz).getPeriodNsecs();
constexpr size_t kHistorySize = 20;
constexpr size_t kMinSamplesForPrediction = 6;
constexpr uint32_t kDiscardOutlierPercent = 20;
- return std::make_unique<VSyncPredictor>(id, kInitialPeriod, kHistorySize,
- kMinSamplesForPrediction, kDiscardOutlierPercent,
- callback);
+ return std::make_unique<VSyncPredictor>(modePtr, kHistorySize, kMinSamplesForPrediction,
+ kDiscardOutlierPercent, callback);
}
VsyncSchedule::DispatchPtr VsyncSchedule::createDispatch(TrackerPtr tracker) {
@@ -140,9 +140,9 @@ VsyncSchedule::ControllerPtr VsyncSchedule::createController(PhysicalDisplayId i
return reactor;
}
-void VsyncSchedule::startPeriodTransition(Period period, bool force) {
+void VsyncSchedule::onDisplayModeChanged(ftl::NonNull<DisplayModePtr> modePtr, bool force) {
std::lock_guard<std::mutex> lock(mHwVsyncLock);
- mController->startPeriodTransition(period.ns(), force);
+ mController->onDisplayModeChanged(modePtr, force);
enableHardwareVsyncLocked();
}
diff --git a/services/surfaceflinger/Scheduler/VsyncSchedule.h b/services/surfaceflinger/Scheduler/VsyncSchedule.h
index ca61f875c3..60c4105f51 100644
--- a/services/surfaceflinger/Scheduler/VsyncSchedule.h
+++ b/services/surfaceflinger/Scheduler/VsyncSchedule.h
@@ -57,21 +57,22 @@ class VsyncSchedule final : public IVsyncSource {
public:
using RequestHardwareVsync = std::function<void(PhysicalDisplayId, bool enabled)>;
- VsyncSchedule(PhysicalDisplayId, FeatureFlags, RequestHardwareVsync, IVsyncTrackerCallback&);
+ VsyncSchedule(ftl::NonNull<DisplayModePtr> modePtr, FeatureFlags, RequestHardwareVsync,
+ IVsyncTrackerCallback&);
~VsyncSchedule();
// IVsyncSource overrides:
Period period() const override;
TimePoint vsyncDeadlineAfter(TimePoint) const override;
- // Inform the schedule that the period is changing and the schedule needs to recalibrate
- // itself. The schedule will end the period transition internally. This will
- // enable hardware VSYNCs in order to calibrate.
+ // Inform the schedule that the display mode changed the schedule needs to recalibrate
+ // itself to the new vsync period. The schedule will end the period transition internally.
+ // This will enable hardware VSYNCs in order to calibrate.
//
- // \param [in] period The period that the system is changing into.
+ // \param [in] DisplayModePtr The mode that the display is changing to.
// \param [in] force True to force a transition even if it is not a
// change.
- void startPeriodTransition(Period period, bool force);
+ void onDisplayModeChanged(ftl::NonNull<DisplayModePtr>, bool force);
// Pass a VSYNC sample to VsyncController. Return true if
// VsyncController detected that the VSYNC period changed. Enable or disable
@@ -125,7 +126,7 @@ private:
friend class android::VsyncScheduleTest;
friend class android::fuzz::SchedulerFuzzer;
- static TrackerPtr createTracker(PhysicalDisplayId, IVsyncTrackerCallback&);
+ static TrackerPtr createTracker(ftl::NonNull<DisplayModePtr> modePtr, IVsyncTrackerCallback&);
static DispatchPtr createDispatch(TrackerPtr);
static ControllerPtr createController(PhysicalDisplayId, VsyncTracker&, FeatureFlags);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c15e74f107..2e70b22ee1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1202,7 +1202,7 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& request, bool
// Start receiving vsync samples now, so that we can detect a period
// switch.
mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */,
- mode.modePtr->getVsyncRate());
+ mode.modePtr.get());
// As we called to set period, we will call to onRefreshRateChangeCompleted once
// VsyncController model is locked.
@@ -1332,10 +1332,9 @@ void SurfaceFlinger::applyActiveMode(const sp<DisplayDevice>& display) {
const auto desiredModeOpt = display->getDesiredMode();
const auto& modeOpt = desiredModeOpt->modeOpt;
const auto displayId = modeOpt->modePtr->getPhysicalDisplayId();
- const auto vsyncRate = modeOpt->modePtr->getVsyncRate();
const auto renderFps = modeOpt->fps;
dropModeRequest(display);
- mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */, vsyncRate);
+ mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */, modeOpt->modePtr.get());
mScheduler->setRenderRate(displayId, renderFps);
if (displayId == mActiveDisplayId) {
@@ -4035,15 +4034,23 @@ void SurfaceFlinger::onChoreographerAttached() {
}
}
-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);
+void SurfaceFlinger::onVsyncGenerated(TimePoint expectedPresentTime,
+ ftl::NonNull<DisplayModePtr> modePtr, Fps renderRate) {
+ const auto vsyncPeriod = modePtr->getVsyncRate().getPeriod();
+ const auto timeout = [&]() -> std::optional<Period> {
+ const auto vrrConfig = modePtr->getVrrConfig();
+ if (!vrrConfig) return std::nullopt;
+
+ const auto notifyExpectedPresentConfig =
+ modePtr->getVrrConfig()->notifyExpectedPresentConfig;
+ if (!notifyExpectedPresentConfig) return std::nullopt;
+ return Period::fromNs(notifyExpectedPresentConfig->notifyExpectedPresentTimeoutNs);
+ }();
+
+ const auto displayId = modePtr->getPhysicalDisplayId();
+ const auto status = getHwComposer().notifyExpectedPresentIfRequired(displayId, vsyncPeriod,
+ expectedPresentTime,
+ renderRate, timeout);
if (status != NO_ERROR) {
ALOGE("%s failed to notifyExpectedPresentHint for display %" PRId64, __func__,
displayId.value);
@@ -5765,7 +5772,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
display->setPowerMode(mode);
- const auto refreshRate = display->refreshRateSelector().getActiveMode().modePtr->getVsyncRate();
+ const auto activeMode = display->refreshRateSelector().getActiveMode().modePtr;
if (!currentModeOpt || *currentModeOpt == hal::PowerMode::OFF) {
// Turn on the display
@@ -5802,7 +5809,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
mScheduler->enableSyntheticVsync(false);
constexpr bool kAllowToEnable = true;
- mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, refreshRate);
+ mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, activeMode.get());
}
mVisibleRegionsDirty = true;
@@ -5844,7 +5851,8 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
mVisibleRegionsDirty = true;
scheduleRepaint();
mScheduler->enableSyntheticVsync(false);
- mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */, refreshRate);
+ mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */,
+ activeMode.get());
}
} else if (mode == hal::PowerMode::DOZE_SUSPEND) {
// Leave display going to doze
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 75fd25a200..e90f8feb6e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -658,8 +658,8 @@ private:
void notifyCpuLoadUp() override;
// IVsyncTrackerCallback overrides
- void onVsyncGenerated(PhysicalDisplayId, TimePoint expectedPresentTime,
- const scheduler::DisplayModeData&, Period vsyncPeriod) override;
+ void onVsyncGenerated(TimePoint expectedPresentTime, ftl::NonNull<DisplayModePtr>,
+ Fps renderRate) 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 9b2d4536cd..4fc39cc912 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
@@ -806,8 +806,7 @@ private:
void onChoreographerAttached() override {}
// IVsyncTrackerCallback overrides
- void onVsyncGenerated(PhysicalDisplayId, TimePoint, const scheduler::DisplayModeData&,
- Period) override {}
+ void onVsyncGenerated(TimePoint, ftl::NonNull<DisplayModePtr>, Fps) override {}
surfaceflinger::test::Factory mFactory;
sp<SurfaceFlinger> mFlinger =
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
index 8fcfd8131a..101f04fa73 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
@@ -28,6 +28,7 @@
#include "Scheduler/VSyncPredictor.h"
#include "Scheduler/VSyncReactor.h"
+#include "mock/DisplayHardware/MockDisplayMode.h"
#include "mock/MockVSyncDispatch.h"
#include "mock/MockVSyncTracker.h"
@@ -179,8 +180,7 @@ void SchedulerFuzzer::fuzzVSyncDispatchTimerQueue() {
}
struct VsyncTrackerCallback : public scheduler::IVsyncTrackerCallback {
- void onVsyncGenerated(PhysicalDisplayId, TimePoint, const scheduler::DisplayModeData&,
- Period) override {}
+ void onVsyncGenerated(TimePoint, ftl::NonNull<DisplayModePtr>, Fps) override {}
};
void SchedulerFuzzer::fuzzVSyncPredictor() {
@@ -189,14 +189,14 @@ void SchedulerFuzzer::fuzzVSyncPredictor() {
uint16_t minimumSamplesForPrediction = mFdp.ConsumeIntegralInRange<uint16_t>(1, UINT16_MAX);
nsecs_t idealPeriod = mFdp.ConsumeIntegralInRange<nsecs_t>(1, UINT32_MAX);
VsyncTrackerCallback callback;
- scheduler::VSyncPredictor tracker{kDisplayId,
- idealPeriod,
- historySize,
- minimumSamplesForPrediction,
+ const auto mode = ftl::as_non_null(
+ mock::createDisplayMode(DisplayModeId(0), Fps::fromPeriodNsecs(idealPeriod)));
+ scheduler::VSyncPredictor tracker{mode, historySize, minimumSamplesForPrediction,
mFdp.ConsumeIntegral<uint32_t>() /*outlierTolerancePercent*/,
callback};
uint16_t period = mFdp.ConsumeIntegral<uint16_t>();
- tracker.setPeriod(period);
+ tracker.setDisplayModePtr(ftl::as_non_null(
+ mock::createDisplayMode(DisplayModeId(0), Fps::fromPeriodNsecs(period))));
for (uint16_t i = 0; i < minimumSamplesForPrediction; ++i) {
if (!tracker.needsMoreSamples()) {
break;
@@ -271,7 +271,10 @@ void SchedulerFuzzer::fuzzVSyncReactor() {
*vSyncTracker, mFdp.ConsumeIntegral<uint8_t>() /*pendingLimit*/,
false);
- reactor.startPeriodTransition(mFdp.ConsumeIntegral<nsecs_t>(), mFdp.ConsumeBool());
+ const auto mode = ftl::as_non_null(
+ mock::createDisplayMode(DisplayModeId(0),
+ Fps::fromPeriodNsecs(mFdp.ConsumeIntegral<nsecs_t>())));
+ reactor.onDisplayModeChanged(mode, mFdp.ConsumeBool());
bool periodFlushed = false; // Value does not matter, since this is an out
// param from addHwVsyncTimestamp.
reactor.addHwVsyncTimestamp(0, std::nullopt, &periodFlushed);
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
index 728708f05c..165de1d7fa 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
@@ -90,8 +90,6 @@ public:
nsecs_t currentPeriod() const override { return 1; }
- void setPeriod(nsecs_t /* period */) override {}
-
void resetModel() override {}
bool needsMoreSamples() const override { return true; }
@@ -100,7 +98,7 @@ public:
return true;
}
- void setDisplayModeData(const scheduler::DisplayModeData&) override {}
+ void setDisplayModePtr(ftl::NonNull<DisplayModePtr>) override {}
nsecs_t nextVSyncTime(nsecs_t timePoint) const {
if (timePoint % mPeriod == 0) {
@@ -109,6 +107,8 @@ public:
return (timePoint - (timePoint % mPeriod) + mPeriod);
}
+ void setRenderRate(Fps) override {}
+
void dump(std::string& /* result */) const override {}
protected:
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
index cf3fab3aa3..31e13305a4 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
@@ -25,6 +25,11 @@
namespace android {
namespace {
+MATCHER_P(DisplayModeFps, value, "equals") {
+ using fps_approx_ops::operator==;
+ return arg->getVsyncRate() == value;
+}
+
// Used when we simulate a display that supports doze.
template <typename Display>
struct DozeIsSupportedVariant {
@@ -94,7 +99,8 @@ struct DispSyncIsSupportedVariant {
static void setupResetModelCallExpectations(DisplayTransactionTest* test) {
auto vsyncSchedule = test->mFlinger.scheduler()->getVsyncSchedule();
EXPECT_CALL(static_cast<mock::VsyncController&>(vsyncSchedule->getController()),
- startPeriodTransition(DEFAULT_VSYNC_PERIOD, false))
+ onDisplayModeChanged(DisplayModeFps(Fps::fromPeriodNsecs(DEFAULT_VSYNC_PERIOD)),
+ false))
.Times(1);
EXPECT_CALL(static_cast<mock::VSyncTracker&>(vsyncSchedule->getTracker()), resetModel())
.Times(1);
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
index 4be07a1ddb..21888318df 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
@@ -50,11 +50,11 @@ public:
nsecs_t currentPeriod() const final { return mPeriod; }
- void setPeriod(nsecs_t) final {}
void resetModel() final {}
bool needsMoreSamples() const final { return false; }
bool isVSyncInPhase(nsecs_t, Fps) const final { return false; }
- void setDisplayModeData(const DisplayModeData&) final {}
+ void setDisplayModePtr(ftl::NonNull<DisplayModePtr>) final {}
+ void setRenderRate(Fps) final {}
void dump(std::string&) const final {}
private:
@@ -88,11 +88,11 @@ public:
return mPeriod;
}
- void setPeriod(nsecs_t) final {}
void resetModel() final {}
bool needsMoreSamples() const final { return false; }
bool isVSyncInPhase(nsecs_t, Fps) const final { return false; }
- void setDisplayModeData(const DisplayModeData&) final {}
+ void setDisplayModePtr(ftl::NonNull<DisplayModePtr>) final {}
+ void setRenderRate(Fps) 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 83108662b9..b97ebba48e 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
@@ -33,6 +33,7 @@
#include "FlagUtils.h"
#include "Scheduler/VSyncDispatchTimerQueue.h"
#include "Scheduler/VSyncTracker.h"
+#include "mock/MockVSyncTracker.h"
#include <com_android_graphics_surfaceflinger_flags.h>
@@ -42,7 +43,7 @@ using namespace std::literals;
namespace android::scheduler {
using namespace com::android::graphics::surfaceflinger;
-class MockVSyncTracker : public VSyncTracker {
+class MockVSyncTracker : public mock::VSyncTracker {
public:
MockVSyncTracker(nsecs_t period) : mPeriod{period} {
ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_))
@@ -52,16 +53,6 @@ public:
.WillByDefault(Invoke(this, &MockVSyncTracker::getCurrentPeriod));
}
- MOCK_METHOD1(addVsyncTimestamp, bool(nsecs_t));
- MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
- MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
- MOCK_METHOD1(setPeriod, void(nsecs_t));
- MOCK_METHOD0(resetModel, void());
- MOCK_CONST_METHOD0(needsMoreSamples, bool());
- MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
- MOCK_METHOD(void, setDisplayModeData, (const DisplayModeData&), (override));
- MOCK_CONST_METHOD1(dump, void(std::string&));
-
nsecs_t nextVSyncTime(nsecs_t timePoint) const {
if (timePoint % mPeriod == 0) {
return timePoint;
diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
index 30a2855955..01f5af4fd1 100644
--- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
@@ -25,6 +25,7 @@
#include "FlagUtils.h"
#include "Scheduler/VSyncPredictor.h"
+#include "mock/DisplayHardware/MockDisplayMode.h"
#include "mock/MockVsyncTrackerCallback.h"
#include <gmock/gmock.h>
@@ -39,12 +40,24 @@ using namespace testing;
using namespace std::literals;
using namespace com::android::graphics::surfaceflinger;
+using NotifyExpectedPresentConfig =
+ ::aidl::android::hardware::graphics::composer3::VrrConfig::NotifyExpectedPresentConfig;
+
+using android::mock::createDisplayMode;
+using android::mock::createVrrDisplayMode;
+
namespace android::scheduler {
+namespace {
MATCHER_P2(IsCloseTo, value, tolerance, "is within tolerance") {
return arg <= value + tolerance && arg >= value - tolerance;
}
+MATCHER_P(FpsMatcher, value, "equals") {
+ using fps_approx_ops::operator==;
+ return arg == value;
+}
+
std::vector<nsecs_t> generateVsyncTimestamps(size_t count, nsecs_t period, nsecs_t bias) {
std::vector<nsecs_t> vsyncs(count);
std::generate(vsyncs.begin(), vsyncs.end(),
@@ -54,21 +67,27 @@ std::vector<nsecs_t> generateVsyncTimestamps(size_t count, nsecs_t period, nsecs
constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(42u);
+ftl::NonNull<DisplayModePtr> displayMode(nsecs_t period) {
+ const int32_t kGroup = 0;
+ const auto kResolution = ui::Size(1920, 1080);
+ const auto refreshRate = Fps::fromPeriodNsecs(period);
+ return ftl::as_non_null(createDisplayMode(DisplayModeId(0), refreshRate, kGroup, kResolution,
+ DEFAULT_DISPLAY_ID));
+}
+} // namespace
+
struct VSyncPredictorTest : testing::Test {
nsecs_t mNow = 0;
nsecs_t mPeriod = 1000;
+ ftl::NonNull<DisplayModePtr> mMode = displayMode(mPeriod);
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,
- mVsyncTrackerCallback};
+ VSyncPredictor tracker{mMode, kHistorySize, kMinimumSamplesForPrediction,
+ kOutlierTolerancePercent, mVsyncTrackerCallback};
};
TEST_F(VSyncPredictorTest, reportsAnticipatedPeriod) {
@@ -78,7 +97,7 @@ TEST_F(VSyncPredictorTest, reportsAnticipatedPeriod) {
EXPECT_THAT(model.intercept, Eq(0));
auto const changedPeriod = 2000;
- tracker.setPeriod(changedPeriod);
+ tracker.setDisplayModePtr(displayMode(changedPeriod));
model = tracker.getVSyncPredictionModel();
EXPECT_THAT(model.slope, Eq(changedPeriod));
EXPECT_THAT(model.intercept, Eq(0));
@@ -99,7 +118,7 @@ TEST_F(VSyncPredictorTest, reportsSamplesNeededAfterExplicitRateChange) {
EXPECT_FALSE(tracker.needsMoreSamples());
auto const changedPeriod = mPeriod * 2;
- tracker.setPeriod(changedPeriod);
+ tracker.setDisplayModePtr(displayMode(changedPeriod));
EXPECT_TRUE(tracker.needsMoreSamples());
for (auto i = 0u; i < kMinimumSamplesForPrediction; i++) {
@@ -133,7 +152,7 @@ TEST_F(VSyncPredictorTest, uponNotifiedOfInaccuracyUsesSynthetic) {
}
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + slightlyLessPeriod));
- tracker.setPeriod(changedPeriod);
+ tracker.setDisplayModePtr(displayMode(changedPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + changedPeriod));
}
@@ -179,7 +198,7 @@ TEST_F(VSyncPredictorTest, adaptsToFenceTimelines_60hzHighVariance) {
auto constexpr expectedPeriod = 16639242;
auto constexpr expectedIntercept = 1049341;
- tracker.setPeriod(idealPeriod);
+ tracker.setDisplayModePtr(displayMode(idealPeriod));
for (auto const& timestamp : simulatedVsyncs) {
tracker.addVsyncTimestamp(timestamp);
}
@@ -198,7 +217,7 @@ TEST_F(VSyncPredictorTest, adaptsToFenceTimelines_90hzLowVariance) {
auto expectedPeriod = 11089413;
auto expectedIntercept = 94421;
- tracker.setPeriod(idealPeriod);
+ tracker.setDisplayModePtr(displayMode(idealPeriod));
for (auto const& timestamp : simulatedVsyncs) {
tracker.addVsyncTimestamp(timestamp);
}
@@ -225,7 +244,7 @@ TEST_F(VSyncPredictorTest, adaptsToFenceTimelinesDiscontinuous_22hzLowVariance)
auto expectedPeriod = 45450152;
auto expectedIntercept = 469647;
- tracker.setPeriod(idealPeriod);
+ tracker.setDisplayModePtr(displayMode(idealPeriod));
for (auto const& timestamp : simulatedVsyncs) {
tracker.addVsyncTimestamp(timestamp);
}
@@ -251,7 +270,7 @@ TEST_F(VSyncPredictorTest, againstOutliersDiscontinuous_500hzLowVariance) {
auto expectedPeriod = 1999892;
auto expectedIntercept = 86342;
- tracker.setPeriod(idealPeriod);
+ tracker.setDisplayModePtr(displayMode(idealPeriod));
for (auto const& timestamp : simulatedVsyncs) {
tracker.addVsyncTimestamp(timestamp);
}
@@ -271,7 +290,7 @@ TEST_F(VSyncPredictorTest, handlesVsyncChange) {
auto const simulatedVsyncsSlow =
generateVsyncTimestamps(kMinimumSamplesForPrediction, slowPeriod, slowTimeBase);
- tracker.setPeriod(fastPeriod);
+ tracker.setDisplayModePtr(displayMode(fastPeriod));
for (auto const& timestamp : simulatedVsyncsFast) {
tracker.addVsyncTimestamp(timestamp);
}
@@ -281,7 +300,7 @@ TEST_F(VSyncPredictorTest, handlesVsyncChange) {
EXPECT_THAT(model.slope, IsCloseTo(fastPeriod, mMaxRoundingError));
EXPECT_THAT(model.intercept, IsCloseTo(0, mMaxRoundingError));
- tracker.setPeriod(slowPeriod);
+ tracker.setDisplayModePtr(displayMode(slowPeriod));
for (auto const& timestamp : simulatedVsyncsSlow) {
tracker.addVsyncTimestamp(timestamp);
}
@@ -305,7 +324,7 @@ TEST_F(VSyncPredictorTest, willBeAccurateUsingPriorResultsForRate) {
generateVsyncTimestamps(kMinimumSamplesForPrediction, fastPeriod2, fastTimeBase);
auto idealPeriod = 100000;
- tracker.setPeriod(idealPeriod);
+ tracker.setDisplayModePtr(displayMode(idealPeriod));
for (auto const& timestamp : simulatedVsyncsFast) {
tracker.addVsyncTimestamp(timestamp);
}
@@ -313,14 +332,14 @@ TEST_F(VSyncPredictorTest, willBeAccurateUsingPriorResultsForRate) {
EXPECT_THAT(model.slope, Eq(fastPeriod));
EXPECT_THAT(model.intercept, Eq(0));
- tracker.setPeriod(slowPeriod);
+ tracker.setDisplayModePtr(displayMode(slowPeriod));
for (auto const& timestamp : simulatedVsyncsSlow) {
tracker.addVsyncTimestamp(timestamp);
}
// we had a model for 100ns mPeriod before, use that until the new samples are
// sufficiently built up
- tracker.setPeriod(idealPeriod);
+ tracker.setDisplayModePtr(displayMode(idealPeriod));
model = tracker.getVSyncPredictionModel();
EXPECT_THAT(model.slope, Eq(fastPeriod));
EXPECT_THAT(model.intercept, Eq(0));
@@ -369,7 +388,7 @@ TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) {
auto const expectedPeriod = 11113919;
auto const expectedIntercept = -1195945;
- tracker.setPeriod(idealPeriod);
+ tracker.setDisplayModePtr(displayMode(idealPeriod));
for (auto const& timestamp : simulatedVsyncs) {
tracker.addVsyncTimestamp(timestamp);
}
@@ -388,11 +407,8 @@ TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) {
// See b/151146131
TEST_F(VSyncPredictorTest, hasEnoughPrecision) {
- VSyncPredictor tracker{DEFAULT_DISPLAY_ID,
- mPeriod,
- 20,
- kMinimumSamplesForPrediction,
- kOutlierTolerancePercent,
+ const auto mode = displayMode(mPeriod);
+ VSyncPredictor tracker{mode, 20, kMinimumSamplesForPrediction, kOutlierTolerancePercent,
mVsyncTrackerCallback};
std::vector<nsecs_t> const simulatedVsyncs{840873348817, 840890049444, 840906762675,
840923581635, 840940161584, 840956868096,
@@ -407,7 +423,7 @@ TEST_F(VSyncPredictorTest, hasEnoughPrecision) {
auto const expectedPeriod = 16698426;
auto const expectedIntercept = 58055;
- tracker.setPeriod(idealPeriod);
+ tracker.setDisplayModePtr(displayMode(idealPeriod));
for (auto const& timestamp : simulatedVsyncs) {
tracker.addVsyncTimestamp(timestamp);
}
@@ -420,7 +436,7 @@ TEST_F(VSyncPredictorTest, hasEnoughPrecision) {
TEST_F(VSyncPredictorTest, resetsWhenInstructed) {
auto const idealPeriod = 10000;
auto const realPeriod = 10500;
- tracker.setPeriod(idealPeriod);
+ tracker.setDisplayModePtr(displayMode(idealPeriod));
for (auto i = 0; i < kMinimumSamplesForPrediction; i++) {
tracker.addVsyncTimestamp(i * realPeriod);
}
@@ -562,7 +578,7 @@ TEST_F(VSyncPredictorTest, robustToDuplicateTimestamps_60hzRealTraceData) {
auto constexpr expectedPeriod = 16'644'742;
auto constexpr expectedIntercept = 125'626;
- tracker.setPeriod(idealPeriod);
+ tracker.setDisplayModePtr(displayMode(idealPeriod));
for (auto const& timestamp : simulatedVsyncs) {
tracker.addVsyncTimestamp(timestamp);
}
@@ -580,7 +596,7 @@ TEST_F(VSyncPredictorTest, setRenderRateIsRespected) {
tracker.addVsyncTimestamp(mNow);
}
- tracker.setDisplayModeData({.renderRate = Fps::fromPeriodNsecs(3 * mPeriod)});
+ tracker.setRenderRate(Fps::fromPeriodNsecs(3 * mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 100), Eq(mNow + mPeriod));
@@ -602,12 +618,12 @@ TEST_F(VSyncPredictorTest, setRenderRateOfDivisorIsInPhase) {
const auto refreshRate = Fps::fromPeriodNsecs(mPeriod);
- tracker.setDisplayModeData({.renderRate = refreshRate / 4});
+ tracker.setRenderRate(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.setDisplayModeData({.renderRate = refreshRate / 2});
+ tracker.setRenderRate(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));
@@ -615,7 +631,7 @@ TEST_F(VSyncPredictorTest, setRenderRateOfDivisorIsInPhase) {
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 7 * mPeriod), Eq(mNow + 9 * mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 9 * mPeriod), Eq(mNow + 11 * mPeriod));
- tracker.setDisplayModeData({.renderRate = refreshRate / 6});
+ tracker.setRenderRate(refreshRate / 6);
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + 1 * mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 1 * mPeriod), Eq(mNow + 7 * mPeriod));
}
@@ -629,7 +645,7 @@ TEST_F(VSyncPredictorTest, setRenderRateIsIgnoredIfNotDivisor) {
tracker.addVsyncTimestamp(mNow);
}
- tracker.setDisplayModeData({.renderRate = Fps::fromPeriodNsecs(3.5f * mPeriod)});
+ tracker.setRenderRate(Fps::fromPeriodNsecs(3.5f * mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + mPeriod));
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 100), Eq(mNow + mPeriod));
@@ -642,16 +658,27 @@ TEST_F(VSyncPredictorTest, setRenderRateIsIgnoredIfNotDivisor) {
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);
+ NotifyExpectedPresentConfig notifyExpectedPresentConfig;
+ notifyExpectedPresentConfig.notifyExpectedPresentTimeoutNs = Period::fromNs(30).ns();
+
+ hal::VrrConfig vrrConfig;
+ vrrConfig.notifyExpectedPresentConfig = notifyExpectedPresentConfig;
+ vrrConfig.minFrameIntervalNs = refreshRate.getPeriodNsecs();
+
+ const int32_t kGroup = 0;
+ const auto kResolution = ui::Size(1920, 1080);
+ const auto mode =
+ ftl::as_non_null(createVrrDisplayMode(DisplayModeId(0), refreshRate, vrrConfig, kGroup,
+ kResolution, DEFAULT_DISPLAY_ID));
+
+ tracker.setDisplayModePtr(mode);
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)))
+ onVsyncGenerated(TimePoint::fromNs(last + mPeriod), mode,
+ FpsMatcher(refreshRate)))
.Times(1);
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(last + mPeriod));
mNow += mPeriod;
@@ -659,14 +686,12 @@ TEST_F(VSyncPredictorTest, vsyncTrackerCallback) {
tracker.addVsyncTimestamp(mNow);
}
- displayModeData = DisplayModeData{.renderRate = refreshRate / 2,
- .notifyExpectedPresentTimeoutOpt = Period::fromNs(30)};
- tracker.setDisplayModeData(displayModeData);
+ tracker.setRenderRate(refreshRate / 2);
{
// out of render rate phase
EXPECT_CALL(mVsyncTrackerCallback,
- onVsyncGenerated(DEFAULT_DISPLAY_ID, TimePoint::fromNs(mNow + 3 * mPeriod),
- displayModeData, Period::fromNs(mPeriod)))
+ onVsyncGenerated(TimePoint::fromNs(mNow + 3 * mPeriod), mode,
+ FpsMatcher(refreshRate / 2)))
.Times(1);
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 1 * mPeriod),
Eq(mNow + 3 * mPeriod));
diff --git a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
index aca3ccca6d..8d9623de1c 100644
--- a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
@@ -31,6 +31,9 @@
#include <scheduler/TimeKeeper.h>
+#include "mock/DisplayHardware/MockDisplayMode.h"
+#include "mock/MockVSyncTracker.h"
+
#include "Scheduler/VSyncDispatch.h"
#include "Scheduler/VSyncReactor.h"
#include "Scheduler/VSyncTracker.h"
@@ -40,20 +43,7 @@ using namespace std::literals;
namespace android::scheduler {
-class MockVSyncTracker : public VSyncTracker {
-public:
- MockVSyncTracker() { ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true)); }
- MOCK_METHOD1(addVsyncTimestamp, bool(nsecs_t));
- MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
- MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
- MOCK_METHOD1(setPeriod, void(nsecs_t));
- MOCK_METHOD0(resetModel, void());
- MOCK_CONST_METHOD0(needsMoreSamples, bool());
- MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
- MOCK_METHOD(void, setDisplayModeData, (const DisplayModeData&), (override));
- MOCK_CONST_METHOD1(dump, void(std::string&));
-};
-
+namespace {
class MockClock : public Clock {
public:
MOCK_CONST_METHOD0(now, nsecs_t());
@@ -93,18 +83,33 @@ std::shared_ptr<android::FenceTime> generateSignalledFenceWithTime(nsecs_t time)
constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(42u);
+ftl::NonNull<DisplayModePtr> displayMode(nsecs_t vsyncPeriod) {
+ const int32_t kGroup = 0;
+ const auto kResolution = ui::Size(1920, 1080);
+ const auto refreshRate = Fps::fromPeriodNsecs(vsyncPeriod);
+ return ftl::as_non_null(mock::createDisplayMode(DisplayModeId(0), refreshRate, kGroup,
+ kResolution, DEFAULT_DISPLAY_ID));
+}
+
+MATCHER_P(DisplayModeMatcher, value, "display mode equals") {
+ return arg->getId() == value->getId() && equalsExceptDisplayModeId(*arg, *value);
+}
+
+} // namespace
+
class VSyncReactorTest : public testing::Test {
protected:
VSyncReactorTest()
- : mMockTracker(std::make_shared<NiceMock<MockVSyncTracker>>()),
+ : mMockTracker(std::make_shared<NiceMock<mock::VSyncTracker>>()),
mMockClock(std::make_shared<NiceMock<MockClock>>()),
mReactor(DEFAULT_DISPLAY_ID, std::make_unique<ClockWrapper>(mMockClock), *mMockTracker,
kPendingLimit, false /* supportKernelIdleTimer */) {
ON_CALL(*mMockClock, now()).WillByDefault(Return(mFakeNow));
ON_CALL(*mMockTracker, currentPeriod()).WillByDefault(Return(period));
+ ON_CALL(*mMockTracker, addVsyncTimestamp(_)).WillByDefault(Return(true));
}
- std::shared_ptr<MockVSyncTracker> mMockTracker;
+ std::shared_ptr<mock::VSyncTracker> mMockTracker;
std::shared_ptr<MockClock> mMockClock;
static constexpr size_t kPendingLimit = 3;
static constexpr nsecs_t mDummyTime = 47;
@@ -194,7 +199,8 @@ TEST_F(VSyncReactorTest, ignoresProperlyAfterAPeriodConfirmation) {
mReactor.setIgnorePresentFences(true);
nsecs_t const newPeriod = 5000;
- mReactor.startPeriodTransition(newPeriod, false);
+
+ mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(0, std::nullopt, &periodFlushed));
EXPECT_FALSE(periodFlushed);
@@ -206,8 +212,8 @@ TEST_F(VSyncReactorTest, ignoresProperlyAfterAPeriodConfirmation) {
TEST_F(VSyncReactorTest, setPeriodCalledOnceConfirmedChange) {
nsecs_t const newPeriod = 5000;
- EXPECT_CALL(*mMockTracker, setPeriod(_)).Times(0);
- mReactor.startPeriodTransition(newPeriod, false);
+ EXPECT_CALL(*mMockTracker, setDisplayModePtr(_)).Times(0);
+ mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
bool periodFlushed = true;
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(10000, std::nullopt, &periodFlushed));
@@ -217,7 +223,7 @@ TEST_F(VSyncReactorTest, setPeriodCalledOnceConfirmedChange) {
EXPECT_FALSE(periodFlushed);
Mock::VerifyAndClearExpectations(mMockTracker.get());
- EXPECT_CALL(*mMockTracker, setPeriod(newPeriod)).Times(1);
+ EXPECT_CALL(*mMockTracker, setDisplayModePtr(/*displayMode(newPeriod)*/ _)).Times(1);
EXPECT_FALSE(mReactor.addHwVsyncTimestamp(25000, std::nullopt, &periodFlushed));
EXPECT_TRUE(periodFlushed);
@@ -226,7 +232,7 @@ TEST_F(VSyncReactorTest, setPeriodCalledOnceConfirmedChange) {
TEST_F(VSyncReactorTest, changingPeriodBackAbortsConfirmationProcess) {
nsecs_t sampleTime = 0;
nsecs_t const newPeriod = 5000;
- mReactor.startPeriodTransition(newPeriod, false);
+ mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
bool periodFlushed = true;
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
EXPECT_FALSE(periodFlushed);
@@ -234,7 +240,7 @@ TEST_F(VSyncReactorTest, changingPeriodBackAbortsConfirmationProcess) {
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
EXPECT_FALSE(periodFlushed);
- mReactor.startPeriodTransition(period, false);
+ mReactor.onDisplayModeChanged(displayMode(period), false);
EXPECT_FALSE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
EXPECT_FALSE(periodFlushed);
}
@@ -244,13 +250,13 @@ TEST_F(VSyncReactorTest, changingToAThirdPeriodWillWaitForLastPeriod) {
nsecs_t const secondPeriod = 5000;
nsecs_t const thirdPeriod = 2000;
- mReactor.startPeriodTransition(secondPeriod, false);
+ mReactor.onDisplayModeChanged(displayMode(secondPeriod), false);
bool periodFlushed = true;
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
EXPECT_FALSE(periodFlushed);
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
EXPECT_FALSE(periodFlushed);
- mReactor.startPeriodTransition(thirdPeriod, false);
+ mReactor.onDisplayModeChanged(displayMode(thirdPeriod), false);
EXPECT_TRUE(
mReactor.addHwVsyncTimestamp(sampleTime += secondPeriod, std::nullopt, &periodFlushed));
EXPECT_FALSE(periodFlushed);
@@ -291,21 +297,22 @@ TEST_F(VSyncReactorTest, reportedBadTimestampFromPredictorWillReactivateHwVSyncP
TEST_F(VSyncReactorTest, presentFenceAdditionDoesNotInterruptConfirmationProcess) {
nsecs_t const newPeriod = 5000;
- mReactor.startPeriodTransition(newPeriod, false);
+ mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
}
TEST_F(VSyncReactorTest, setPeriodCalledFirstTwoEventsNewPeriod) {
nsecs_t const newPeriod = 5000;
- EXPECT_CALL(*mMockTracker, setPeriod(_)).Times(0);
- mReactor.startPeriodTransition(newPeriod, false);
+ EXPECT_CALL(*mMockTracker, setDisplayModePtr(_)).Times(0);
+ mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
bool periodFlushed = true;
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(5000, std::nullopt, &periodFlushed));
EXPECT_FALSE(periodFlushed);
Mock::VerifyAndClearExpectations(mMockTracker.get());
- EXPECT_CALL(*mMockTracker, setPeriod(newPeriod)).Times(1);
+ EXPECT_CALL(*mMockTracker, setDisplayModePtr(DisplayModeMatcher(displayMode(newPeriod))))
+ .Times(1);
EXPECT_FALSE(mReactor.addHwVsyncTimestamp(10000, std::nullopt, &periodFlushed));
EXPECT_TRUE(periodFlushed);
}
@@ -323,7 +330,7 @@ TEST_F(VSyncReactorTest, addResyncSamplePeriodChanges) {
bool periodFlushed = false;
nsecs_t const newPeriod = 4000;
- mReactor.startPeriodTransition(newPeriod, false);
+ mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
auto time = 0;
auto constexpr numTimestampSubmissions = 10;
@@ -348,7 +355,7 @@ TEST_F(VSyncReactorTest, addHwVsyncTimestampDozePreempt) {
bool periodFlushed = false;
nsecs_t const newPeriod = 4000;
- mReactor.startPeriodTransition(newPeriod, false);
+ mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
auto time = 0;
// If the power mode is not DOZE or DOZE_SUSPEND, it is still collecting timestamps.
@@ -365,7 +372,7 @@ TEST_F(VSyncReactorTest, addPresentFenceWhileAwaitingPeriodConfirmationRequestsH
auto time = 0;
bool periodFlushed = false;
nsecs_t const newPeriod = 4000;
- mReactor.startPeriodTransition(newPeriod, false);
+ mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
time += period;
mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed);
@@ -381,7 +388,7 @@ TEST_F(VSyncReactorTest, hwVsyncIsRequestedForTracker) {
auto time = 0;
bool periodFlushed = false;
nsecs_t const newPeriod = 4000;
- mReactor.startPeriodTransition(newPeriod, false);
+ mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
static auto constexpr numSamplesWithNewPeriod = 4;
Sequence seq;
@@ -408,7 +415,7 @@ TEST_F(VSyncReactorTest, hwVsyncturnsOffOnConfirmationWhenTrackerDoesntRequest)
auto time = 0;
bool periodFlushed = false;
nsecs_t const newPeriod = 4000;
- mReactor.startPeriodTransition(newPeriod, false);
+ mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
Sequence seq;
EXPECT_CALL(*mMockTracker, needsMoreSamples())
@@ -428,7 +435,7 @@ TEST_F(VSyncReactorTest, hwVsyncIsRequestedForTrackerMultiplePeriodChanges) {
nsecs_t const newPeriod1 = 4000;
nsecs_t const newPeriod2 = 7000;
- mReactor.startPeriodTransition(newPeriod1, false);
+ mReactor.onDisplayModeChanged(displayMode(newPeriod1), false);
Sequence seq;
EXPECT_CALL(*mMockTracker, needsMoreSamples())
@@ -447,7 +454,7 @@ TEST_F(VSyncReactorTest, hwVsyncIsRequestedForTrackerMultiplePeriodChanges) {
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod1, std::nullopt, &periodFlushed));
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod1, std::nullopt, &periodFlushed));
- mReactor.startPeriodTransition(newPeriod2, false);
+ mReactor.onDisplayModeChanged(displayMode(newPeriod2), false);
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod1, std::nullopt, &periodFlushed));
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod2, std::nullopt, &periodFlushed));
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod2, std::nullopt, &periodFlushed));
@@ -460,7 +467,7 @@ TEST_F(VSyncReactorTest, periodChangeWithGivenVsyncPeriod) {
mReactor.setIgnorePresentFences(true);
nsecs_t const newPeriod = 5000;
- mReactor.startPeriodTransition(newPeriod, false);
+ mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
EXPECT_TRUE(mReactor.addHwVsyncTimestamp(0, 0, &periodFlushed));
EXPECT_FALSE(periodFlushed);
@@ -484,7 +491,7 @@ TEST_F(VSyncReactorTest, periodIsMeasuredIfIgnoringComposer) {
// First, set the same period, which should only be confirmed when we receive two
// matching callbacks
- idleReactor.startPeriodTransition(10000, false);
+ idleReactor.onDisplayModeChanged(displayMode(10000), false);
EXPECT_TRUE(idleReactor.addHwVsyncTimestamp(0, 0, &periodFlushed));
EXPECT_FALSE(periodFlushed);
// Correct period but incorrect timestamp delta
@@ -497,7 +504,7 @@ TEST_F(VSyncReactorTest, periodIsMeasuredIfIgnoringComposer) {
// Then, set a new period, which should be confirmed as soon as we receive a callback
// reporting the new period
nsecs_t const newPeriod = 5000;
- idleReactor.startPeriodTransition(newPeriod, false);
+ idleReactor.onDisplayModeChanged(displayMode(newPeriod), false);
// Incorrect timestamp delta and period
EXPECT_TRUE(idleReactor.addHwVsyncTimestamp(20000, 10000, &periodFlushed));
EXPECT_FALSE(periodFlushed);
diff --git a/services/surfaceflinger/tests/unittests/VsyncScheduleTest.cpp b/services/surfaceflinger/tests/unittests/VsyncScheduleTest.cpp
index a8a3cd0293..bfdd5963f3 100644
--- a/services/surfaceflinger/tests/unittests/VsyncScheduleTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VsyncScheduleTest.cpp
@@ -25,10 +25,12 @@
#include <scheduler/Fps.h>
#include "Scheduler/VsyncSchedule.h"
#include "ThreadContext.h"
+#include "mock/DisplayHardware/MockDisplayMode.h"
#include "mock/MockVSyncDispatch.h"
#include "mock/MockVSyncTracker.h"
#include "mock/MockVsyncController.h"
+using android::mock::createDisplayMode;
using testing::_;
namespace android {
@@ -157,35 +159,35 @@ TEST_F(VsyncScheduleTest, StartPeriodTransition) {
// allowed.
ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
- const Period period = (60_Hz).getPeriod();
+ const auto mode = ftl::as_non_null(createDisplayMode(DisplayModeId(0), 60_Hz));
EXPECT_CALL(mRequestHardwareVsync, Call(kDisplayId, true));
- EXPECT_CALL(getController(), startPeriodTransition(period.ns(), false));
+ EXPECT_CALL(getController(), onDisplayModeChanged(mode, false));
- mVsyncSchedule->startPeriodTransition(period, false);
+ mVsyncSchedule->onDisplayModeChanged(mode, false);
}
TEST_F(VsyncScheduleTest, StartPeriodTransitionAlreadyEnabled) {
ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
mVsyncSchedule->enableHardwareVsync();
- const Period period = (60_Hz).getPeriod();
+ const auto mode = ftl::as_non_null(createDisplayMode(DisplayModeId(0), 60_Hz));
EXPECT_CALL(mRequestHardwareVsync, Call(_, _)).Times(0);
- EXPECT_CALL(getController(), startPeriodTransition(period.ns(), false));
+ EXPECT_CALL(getController(), onDisplayModeChanged(mode, false));
- mVsyncSchedule->startPeriodTransition(period, false);
+ mVsyncSchedule->onDisplayModeChanged(mode, false);
}
TEST_F(VsyncScheduleTest, StartPeriodTransitionForce) {
ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
- const Period period = (60_Hz).getPeriod();
+ const auto mode = ftl::as_non_null(createDisplayMode(DisplayModeId(0), 60_Hz));
EXPECT_CALL(mRequestHardwareVsync, Call(kDisplayId, true));
- EXPECT_CALL(getController(), startPeriodTransition(period.ns(), true));
+ EXPECT_CALL(getController(), onDisplayModeChanged(mode, true));
- mVsyncSchedule->startPeriodTransition(period, true);
+ mVsyncSchedule->onDisplayModeChanged(mode, true);
}
TEST_F(VsyncScheduleTest, AddResyncSampleDisallowed) {
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplayMode.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplayMode.h
index cb05c00699..5bcce501e6 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplayMode.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplayMode.h
@@ -52,6 +52,7 @@ inline DisplayModePtr createVrrDisplayMode(
.setVrrConfig(std::move(vrrConfig))
.build();
}
+
inline DisplayModePtr cloneForDisplay(PhysicalDisplayId displayId, const DisplayModePtr& modePtr) {
return DisplayMode::Builder(modePtr->getHwcId())
.setId(modePtr->getId())
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
index 31eb86e4c5..ec22b70296 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
@@ -27,15 +27,15 @@ public:
VSyncTracker();
~VSyncTracker() override;
- MOCK_METHOD1(addVsyncTimestamp, bool(nsecs_t));
- MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
- MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
- MOCK_METHOD1(setPeriod, void(nsecs_t));
- MOCK_METHOD0(resetModel, void());
- MOCK_CONST_METHOD0(needsMoreSamples, bool());
- MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
- MOCK_METHOD(void, setDisplayModeData, (const scheduler::DisplayModeData&), (override));
- MOCK_CONST_METHOD1(dump, void(std::string&));
+ MOCK_METHOD(bool, addVsyncTimestamp, (nsecs_t), (override));
+ MOCK_METHOD(nsecs_t, nextAnticipatedVSyncTimeFrom, (nsecs_t), (const, override));
+ MOCK_METHOD(nsecs_t, currentPeriod, (), (const, override));
+ MOCK_METHOD(void, resetModel, (), (override));
+ MOCK_METHOD(bool, needsMoreSamples, (), (const, override));
+ MOCK_METHOD(bool, isVSyncInPhase, (nsecs_t, Fps), (const, override));
+ MOCK_METHOD(void, setDisplayModePtr, (ftl::NonNull<DisplayModePtr>), (override));
+ MOCK_METHOD(void, setRenderRate, (Fps), (override));
+ MOCK_METHOD(void, dump, (std::string&), (const, override));
};
} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h b/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h
index 69ec60acd4..f7433908b0 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h
@@ -29,7 +29,7 @@ public:
MOCK_METHOD(bool, addPresentFence, (std::shared_ptr<FenceTime>), (override));
MOCK_METHOD(bool, addHwVsyncTimestamp, (nsecs_t, std::optional<nsecs_t>, bool*), (override));
- MOCK_METHOD(void, startPeriodTransition, (nsecs_t, bool), (override));
+ MOCK_METHOD(void, onDisplayModeChanged, (ftl::NonNull<DisplayModePtr>, bool), (override));
MOCK_METHOD(void, setIgnorePresentFences, (bool), (override));
MOCK_METHOD(void, setDisplayPowerMode, (hal::PowerMode), (override));
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVsyncTrackerCallback.h b/services/surfaceflinger/tests/unittests/mock/MockVsyncTrackerCallback.h
index b8e24e0593..b48529f4ac 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVsyncTrackerCallback.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockVsyncTrackerCallback.h
@@ -23,13 +23,10 @@
namespace android::scheduler::mock {
struct VsyncTrackerCallback final : IVsyncTrackerCallback {
- MOCK_METHOD(void, onVsyncGenerated,
- (PhysicalDisplayId, TimePoint, const scheduler::DisplayModeData&, Period),
- (override));
+ MOCK_METHOD(void, onVsyncGenerated, (TimePoint, ftl::NonNull<DisplayModePtr>, Fps), (override));
};
struct NoOpVsyncTrackerCallback final : IVsyncTrackerCallback {
- void onVsyncGenerated(PhysicalDisplayId, TimePoint, const scheduler::DisplayModeData&,
- Period) override{};
+ void onVsyncGenerated(TimePoint, ftl::NonNull<DisplayModePtr>, Fps) override{};
};
} // namespace android::scheduler::mock