SurfaceFlinger: use vsyncPeriod from HWC
Composer 2.4 onVsync callback provides a vsyncPeriod. Use that period
in VsyncReactor to know when a vsync transition is done.
Test: adb shell /data/nativetest64/libsurfaceflinger_unittest/libsurfaceflinger_unittest
Bug: 140201379
Change-Id: Ia255e3b1d722fd1a3e571ec2aeceb1e8569d44d4
diff --git a/services/surfaceflinger/Scheduler/DispSync.cpp b/services/surfaceflinger/Scheduler/DispSync.cpp
index ca41608..809a0e5 100644
--- a/services/surfaceflinger/Scheduler/DispSync.cpp
+++ b/services/surfaceflinger/Scheduler/DispSync.cpp
@@ -542,7 +542,8 @@
resetLocked();
}
-bool DispSync::addResyncSample(nsecs_t timestamp, bool* periodFlushed) {
+bool DispSync::addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> /*hwcVsyncPeriod*/,
+ bool* periodFlushed) {
Mutex::Autolock lock(mMutex);
ALOGV("[%s] addResyncSample(%" PRId64 ")", mName, ns2us(timestamp));
diff --git a/services/surfaceflinger/Scheduler/DispSync.h b/services/surfaceflinger/Scheduler/DispSync.h
index c6aadbb..2d9afc9 100644
--- a/services/surfaceflinger/Scheduler/DispSync.h
+++ b/services/surfaceflinger/Scheduler/DispSync.h
@@ -49,7 +49,8 @@
virtual void reset() = 0;
virtual bool addPresentFence(const std::shared_ptr<FenceTime>&) = 0;
virtual void beginResync() = 0;
- virtual bool addResyncSample(nsecs_t timestamp, bool* periodFlushed) = 0;
+ virtual bool addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
+ bool* periodFlushed) = 0;
virtual void endResync() = 0;
virtual void setPeriod(nsecs_t period) = 0;
virtual nsecs_t getPeriod() = 0;
@@ -125,7 +126,8 @@
// down the DispSync model, and false otherwise.
// periodFlushed will be set to true if mPendingPeriod is flushed to
// mIntendedPeriod, and false otherwise.
- bool addResyncSample(nsecs_t timestamp, bool* periodFlushed) override;
+ bool addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
+ bool* periodFlushed) override;
void endResync() override;
// The setPeriod method sets the vsync event model's period to a specific
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index bc4f805..614b74e 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -340,13 +340,15 @@
}
}
-void Scheduler::addResyncSample(nsecs_t timestamp, bool* periodFlushed) {
+void Scheduler::addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
+ bool* periodFlushed) {
bool needsHwVsync = false;
*periodFlushed = false;
{ // Scope for the lock
std::lock_guard<std::mutex> lock(mHWVsyncLock);
if (mPrimaryHWVsyncEnabled) {
- needsHwVsync = mPrimaryDispSync->addResyncSample(timestamp, periodFlushed);
+ needsHwVsync =
+ mPrimaryDispSync->addResyncSample(timestamp, hwcVsyncPeriod, periodFlushed);
}
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 01062f8..0208ba2 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -109,7 +109,8 @@
// Passes a vsync sample to DispSync. periodFlushed will be true if
// DispSync detected that the vsync period changed, and false otherwise.
- void addResyncSample(nsecs_t timestamp, bool* periodFlushed);
+ void addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
+ bool* periodFlushed);
void addPresentFence(const std::shared_ptr<FenceTime>&);
void setIgnorePresentFences(bool ignore);
nsecs_t getDispSyncExpectedPresentTime();
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index 70e4760..da73e4e 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -229,24 +229,33 @@
void VSyncReactor::endResync() {}
-bool VSyncReactor::periodConfirmed(nsecs_t vsync_timestamp) {
- if (!mLastHwVsync || !mPeriodConfirmationInProgress) {
+bool VSyncReactor::periodConfirmed(nsecs_t vsync_timestamp, std::optional<nsecs_t> HwcVsyncPeriod) {
+ if (!mPeriodConfirmationInProgress) {
return false;
}
- auto const period = mPeriodTransitioningTo ? *mPeriodTransitioningTo : getPeriod();
+ if (!mLastHwVsync && !HwcVsyncPeriod) {
+ return false;
+ }
+
+ auto const period = mPeriodTransitioningTo ? *mPeriodTransitioningTo : getPeriod();
static constexpr int allowancePercent = 10;
static constexpr std::ratio<allowancePercent, 100> allowancePercentRatio;
auto const allowance = period * allowancePercentRatio.num / allowancePercentRatio.den;
+ if (HwcVsyncPeriod) {
+ return std::abs(*HwcVsyncPeriod - period) < allowance;
+ }
+
auto const distance = vsync_timestamp - *mLastHwVsync;
return std::abs(distance - period) < allowance;
}
-bool VSyncReactor::addResyncSample(nsecs_t timestamp, bool* periodFlushed) {
+bool VSyncReactor::addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
+ bool* periodFlushed) {
assert(periodFlushed);
std::lock_guard<std::mutex> lk(mMutex);
- if (periodConfirmed(timestamp)) {
+ if (periodConfirmed(timestamp, hwcVsyncPeriod)) {
if (mPeriodTransitioningTo) {
mTracker->setPeriod(*mPeriodTransitioningTo);
for (auto& entry : mCallbacks) {
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.h b/services/surfaceflinger/Scheduler/VSyncReactor.h
index 5b79f35..aa8a38d 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.h
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.h
@@ -49,7 +49,8 @@
// TODO: (b/145626181) remove begin,endResync functions from DispSync i/f when possible.
void beginResync() final;
- bool addResyncSample(nsecs_t timestamp, bool* periodFlushed) final;
+ bool addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
+ bool* periodFlushed) final;
void endResync() final;
status_t addEventListener(const char* name, nsecs_t phase, DispSync::Callback* callback,
@@ -65,7 +66,8 @@
void updateIgnorePresentFencesInternal() REQUIRES(mMutex);
void startPeriodTransition(nsecs_t newPeriod) REQUIRES(mMutex);
void endPeriodTransition() REQUIRES(mMutex);
- bool periodConfirmed(nsecs_t vsync_timestamp) REQUIRES(mMutex);
+ bool periodConfirmed(nsecs_t vsync_timestamp, std::optional<nsecs_t> hwcVsyncPeriod)
+ REQUIRES(mMutex);
std::unique_ptr<Clock> const mClock;
std::unique_ptr<VSyncTracker> const mTracker;