diff options
| author | 2020-01-21 20:53:35 +0000 | |
|---|---|---|
| committer | 2020-01-21 20:53:35 +0000 | |
| commit | ca479e9c86aee6b6e4ef50ffdc3abe29eec0fae5 (patch) | |
| tree | 8c4ea5439c8af279960c0b7f492fb07e758bb666 | |
| parent | 6d8a276c39310bf61dfd581d1c6596b5c8207ef0 (diff) | |
| parent | c3e9e8eaf55b6c5078b6c0b547284a863cf9cbd9 (diff) | |
Merge "SF: VSyncTracker, clear timestamps on beginResync"
8 files changed, 46 insertions, 4 deletions
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp index 915419154f..e8c47a570e 100644 --- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp +++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp @@ -42,7 +42,7 @@ VSyncPredictor::VSyncPredictor(nsecs_t idealPeriod, size_t historySize, kMinimumSamplesForPrediction(minimumSamplesForPrediction), kOutlierTolerancePercent(std::min(outlierTolerancePercent, kMaxPercent)), mIdealPeriod(idealPeriod) { - mRateMap[mIdealPeriod] = {idealPeriod, 0}; + resetModel(); } inline size_t VSyncPredictor::next(int i) const { @@ -203,6 +203,10 @@ void VSyncPredictor::setPeriod(nsecs_t period) { mRateMap[mIdealPeriod] = {period, 0}; } + clearTimestamps(); +} + +void VSyncPredictor::clearTimestamps() { if (!timestamps.empty()) { mKnownTimestamp = *std::max_element(timestamps.begin(), timestamps.end()); timestamps.clear(); @@ -227,6 +231,12 @@ bool VSyncPredictor::needsMoreSamples(nsecs_t now) const { return needsMoreSamples; } +void VSyncPredictor::resetModel() { + std::lock_guard<std::mutex> lk(mMutex); + mRateMap[mIdealPeriod] = {mIdealPeriod, 0}; + clearTimestamps(); +} + } // namespace android::scheduler // TODO(b/129481165): remove the #pragma below and fix conversion issues diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.h b/services/surfaceflinger/Scheduler/VSyncPredictor.h index 4210b3cf46..41e5469c20 100644 --- a/services/surfaceflinger/Scheduler/VSyncPredictor.h +++ b/services/surfaceflinger/Scheduler/VSyncPredictor.h @@ -40,6 +40,7 @@ public: void addVsyncTimestamp(nsecs_t timestamp) final; nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const final; nsecs_t currentPeriod() const final; + void resetModel() final; /* * Inform the model that the period is anticipated to change to a new value. @@ -48,7 +49,7 @@ public: * * \param [in] period The new period that should be used. */ - void setPeriod(nsecs_t period); + void setPeriod(nsecs_t period) final; /* Query if the model is in need of more samples to make a prediction at timePoint. * \param [in] timePoint The timePoint to inquire of. @@ -61,6 +62,7 @@ public: private: VSyncPredictor(VSyncPredictor const&) = delete; VSyncPredictor& operator=(VSyncPredictor const&) = delete; + void clearTimestamps() REQUIRES(mMutex); size_t const kHistorySize; size_t const kMinimumSamplesForPrediction; diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp index 20b6238c92..98cec7187a 100644 --- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp +++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp @@ -199,7 +199,9 @@ nsecs_t VSyncReactor::getPeriod() { return mTracker->currentPeriod(); } -void VSyncReactor::beginResync() {} +void VSyncReactor::beginResync() { + mTracker->resetModel(); +} void VSyncReactor::endResync() {} diff --git a/services/surfaceflinger/Scheduler/VSyncTracker.h b/services/surfaceflinger/Scheduler/VSyncTracker.h index 6be63fe9d2..2b278848b3 100644 --- a/services/surfaceflinger/Scheduler/VSyncTracker.h +++ b/services/surfaceflinger/Scheduler/VSyncTracker.h @@ -61,6 +61,9 @@ public: */ virtual void setPeriod(nsecs_t period) = 0; + /* Inform the tracker that the samples it has are not accurate for prediction. */ + virtual void resetModel() = 0; + protected: VSyncTracker(VSyncTracker const&) = delete; VSyncTracker& operator=(VSyncTracker const&) = delete; diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp index b51a025e30..acf852daa1 100644 --- a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp @@ -50,6 +50,7 @@ public: nsecs_t currentPeriod() const final { return mPeriod; } void setPeriod(nsecs_t) final {} + void resetModel() final {} private: nsecs_t const mPeriod; @@ -83,6 +84,7 @@ public: } void setPeriod(nsecs_t) final {} + void resetModel() final {} private: std::mutex mutable mMutex; diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp index f5649ee2db..70c92254b2 100644 --- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp @@ -45,6 +45,7 @@ public: MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t)); MOCK_CONST_METHOD0(currentPeriod, nsecs_t()); MOCK_METHOD1(setPeriod, void(nsecs_t)); + MOCK_METHOD0(resetModel, void()); nsecs_t nextVSyncTime(nsecs_t timePoint) const { if (timePoint % mPeriod == 0) { diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp index 00d3cc6e0b..6ec3844f25 100644 --- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp @@ -355,6 +355,21 @@ TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) { EXPECT_THAT(prediction, Ge(timePoint)); } +TEST_F(VSyncPredictorTest, resetsWhenInstructed) { + auto const idealPeriod = 10000; + auto const realPeriod = 10500; + tracker.setPeriod(idealPeriod); + for (auto i = 0; i < kMinimumSamplesForPrediction; i++) { + tracker.addVsyncTimestamp(i * realPeriod); + } + + EXPECT_THAT(std::get<0>(tracker.getVSyncPredictionModel()), + IsCloseTo(realPeriod, mMaxRoundingError)); + tracker.resetModel(); + EXPECT_THAT(std::get<0>(tracker.getVSyncPredictionModel()), + IsCloseTo(idealPeriod, mMaxRoundingError)); +} + } // namespace android::scheduler // TODO(b/129481165): remove the #pragma below and fix conversion issues diff --git a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp index 188adea8ad..ce1fafedc9 100644 --- a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp @@ -39,6 +39,7 @@ public: MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t)); MOCK_CONST_METHOD0(currentPeriod, nsecs_t()); MOCK_METHOD1(setPeriod, void(nsecs_t)); + MOCK_METHOD0(resetModel, void()); }; class VSyncTrackerWrapper : public VSyncTracker { @@ -50,7 +51,8 @@ public: return mTracker->nextAnticipatedVSyncTimeFrom(timePoint); } nsecs_t currentPeriod() const final { return mTracker->currentPeriod(); } - void setPeriod(nsecs_t period) { mTracker->setPeriod(period); } + void setPeriod(nsecs_t period) final { mTracker->setPeriod(period); } + void resetModel() final { mTracker->resetModel(); } private: std::shared_ptr<VSyncTracker> const mTracker; @@ -559,6 +561,11 @@ TEST_F(VSyncReactorTest, negativeOffsetsApplied) { mReactor.addEventListener(mName, negativePhase, &outerCb, lastCallbackTime); } +TEST_F(VSyncReactorTest, beginResyncResetsModel) { + EXPECT_CALL(*mMockTracker, resetModel()); + mReactor.beginResync(); +} + using VSyncReactorDeathTest = VSyncReactorTest; TEST_F(VSyncReactorDeathTest, invalidRemoval) { mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); |