Don't clear timestamps when enabling HW vsync.
It should clear after the first HW Vsync timestamp comes in,
and when VSyncReactor period confirmed. Therefore, a prediction
when HW vsync is enabled but not yet confirmed is consistent with a
prediction when coming out of idle.
Bug: 272802278
Test: Flash, perfetto trace
Test: atest libsurfaceflinger_unittest
Change-Id: I619162d5583f33087de04c0e3b073a589ec4c2f7
diff --git a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
index ff3f29d..5691792 100644
--- a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
+++ b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
@@ -17,6 +17,7 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include <ftl/fake_guard.h>
+#include <gui/TraceUtils.h>
#include <scheduler/Fps.h>
#include <scheduler/Timer.h>
@@ -144,6 +145,14 @@
}
bool VsyncSchedule::addResyncSample(TimePoint timestamp, ftl::Optional<Period> hwcVsyncPeriod) {
+ ATRACE_CALL();
+
+ if (mClearTimestampsOnNextSample) {
+ ATRACE_FORMAT("clearing sample after HW vsync enabled", __func__);
+ getTracker().resetModel();
+ mClearTimestampsOnNextSample = false;
+ }
+
bool needsHwVsync = false;
bool periodFlushed = false;
{
@@ -170,7 +179,7 @@
void VsyncSchedule::enableHardwareVsyncLocked() {
if (mHwVsyncState == HwVsyncState::Disabled) {
- getTracker().resetModel();
+ mClearTimestampsOnNextSample = true;
mRequestHardwareVsync(mId, true);
mHwVsyncState = HwVsyncState::Enabled;
}
diff --git a/services/surfaceflinger/Scheduler/VsyncSchedule.h b/services/surfaceflinger/Scheduler/VsyncSchedule.h
index 5eca29a..556ef80 100644
--- a/services/surfaceflinger/Scheduler/VsyncSchedule.h
+++ b/services/surfaceflinger/Scheduler/VsyncSchedule.h
@@ -146,6 +146,11 @@
// device is off.
HwVsyncState mPendingHwVsyncState GUARDED_BY(kMainThreadContext) = HwVsyncState::Disabled;
+ // Whether to reset the timestamps stored in the vsync model on the next hw vsync sample. This
+ // is to avoid clearing the model when hw vsync is enabled, in order to be consistent with the
+ // stale timestamps. Instead, clear the model on the first hw vsync callback.
+ bool mClearTimestampsOnNextSample = false;
+
class PredictedVsyncTracer;
using TracerPtr = std::unique_ptr<PredictedVsyncTracer>;
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
index cf3fab3..4780e49 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
@@ -91,18 +91,16 @@
};
struct DispSyncIsSupportedVariant {
- static void setupResetModelCallExpectations(DisplayTransactionTest* test) {
+ static void setupStartPeriodTransitionCallExpectations(DisplayTransactionTest* test) {
auto vsyncSchedule = test->mFlinger.scheduler()->getVsyncSchedule();
EXPECT_CALL(static_cast<mock::VsyncController&>(vsyncSchedule->getController()),
startPeriodTransition(DEFAULT_VSYNC_PERIOD, false))
.Times(1);
- EXPECT_CALL(static_cast<mock::VSyncTracker&>(vsyncSchedule->getTracker()), resetModel())
- .Times(1);
}
};
struct DispSyncNotSupportedVariant {
- static void setupResetModelCallExpectations(DisplayTransactionTest* /* test */) {}
+ static void setupStartPeriodTransitionCallExpectations(DisplayTransactionTest* /* test */) {}
};
// --------------------------------------------------------------------
@@ -125,7 +123,7 @@
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
Case::EventThread::setupEnableVsyncCallExpectations(test);
- Case::DispSync::setupResetModelCallExpectations(test);
+ Case::DispSync::setupStartPeriodTransitionCallExpectations(test);
Case::setupRepaintEverythingCallExpectations(test);
}
@@ -186,7 +184,7 @@
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupEnableVsyncCallExpectations(test);
- Case::DispSync::setupResetModelCallExpectations(test);
+ Case::DispSync::setupStartPeriodTransitionCallExpectations(test);
Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
}
};
@@ -204,7 +202,7 @@
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupEnableVsyncCallExpectations(test);
- Case::DispSync::setupResetModelCallExpectations(test);
+ Case::DispSync::setupStartPeriodTransitionCallExpectations(test);
Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
}
};