summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Kevin DuBois <kevindubois@google.com> 2019-11-14 08:52:45 -0800
committer Kevin DuBois <kevindubois@google.com> 2019-11-26 11:10:28 -0800
commit2fd3ceaf9834d1a0056ff59c454c643f7ab14f75 (patch)
tree102379b55c35b9b7e9ba01a756197f13c4aeb126
parentb2501bad7ccb2000237ccb2b08ca04f7ca6c5ec1 (diff)
SF: VSyncReactor add timestamp querying functions
Adds 2 more functions from the DispSync interface to VSyncReactor, computeNextRefresh, and expectedPresentTime Bug: 140303479 Test: 3 new units Change-Id: I75ea79ed749f05daf3337ddc8ca145e2ecceabcd
-rw-r--r--services/surfaceflinger/Scheduler/TimeKeeper.h21
-rw-r--r--services/surfaceflinger/Scheduler/VSyncPredictor.cpp5
-rw-r--r--services/surfaceflinger/Scheduler/VSyncPredictor.h1
-rw-r--r--services/surfaceflinger/Scheduler/VSyncReactor.cpp18
-rw-r--r--services/surfaceflinger/Scheduler/VSyncReactor.h9
-rw-r--r--services/surfaceflinger/Scheduler/VSyncTracker.h7
-rw-r--r--services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp7
-rw-r--r--services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp1
-rw-r--r--services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp55
9 files changed, 113 insertions, 11 deletions
diff --git a/services/surfaceflinger/Scheduler/TimeKeeper.h b/services/surfaceflinger/Scheduler/TimeKeeper.h
index 699cd504fa..38f07081bb 100644
--- a/services/surfaceflinger/Scheduler/TimeKeeper.h
+++ b/services/surfaceflinger/Scheduler/TimeKeeper.h
@@ -21,10 +21,24 @@
namespace android::scheduler {
+class Clock {
+public:
+ virtual ~Clock();
+ /*
+ * Returns the SYSTEM_TIME_MONOTONIC, used by testing infra to stub time.
+ */
+ virtual nsecs_t now() const = 0;
+
+protected:
+ Clock() = default;
+ Clock(Clock const&) = delete;
+ Clock& operator=(Clock const&) = delete;
+};
+
/*
* TimeKeeper is the interface for a single-shot timer primitive.
*/
-class TimeKeeper {
+class TimeKeeper : public Clock {
public:
virtual ~TimeKeeper();
@@ -39,11 +53,6 @@ public:
*/
virtual void alarmCancel() = 0;
- /*
- * Returns the SYSTEM_TIME_MONOTONIC, used by testing infra to stub time.
- */
- virtual nsecs_t now() const = 0;
-
protected:
TimeKeeper(TimeKeeper const&) = delete;
TimeKeeper& operator=(TimeKeeper const&) = delete;
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index 643c5d2a5a..3894992ad1 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -54,6 +54,11 @@ bool VSyncPredictor::validate(nsecs_t timestamp) const {
return percent < kOutlierTolerancePercent || percent > (kMaxPercent - kOutlierTolerancePercent);
}
+nsecs_t VSyncPredictor::currentPeriod() const {
+ std::lock_guard<std::mutex> lk(mMutex);
+ return std::get<0>(mRateMap.find(mIdealPeriod)->second);
+}
+
void VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
std::lock_guard<std::mutex> lk(mMutex);
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.h b/services/surfaceflinger/Scheduler/VSyncPredictor.h
index 1590f490aa..4210b3cf46 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.h
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.h
@@ -39,6 +39,7 @@ public:
void addVsyncTimestamp(nsecs_t timestamp) final;
nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const final;
+ nsecs_t currentPeriod() const final;
/*
* Inform the model that the period is anticipated to change to a new value.
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index 1398362b00..9ce440c084 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -15,14 +15,18 @@
*/
#include "VSyncReactor.h"
+#include "TimeKeeper.h"
#include "VSyncDispatch.h"
#include "VSyncTracker.h"
namespace android::scheduler {
-VSyncReactor::VSyncReactor(std::unique_ptr<VSyncDispatch> dispatch,
+Clock::~Clock() = default;
+
+VSyncReactor::VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch,
std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit)
- : mDispatch(std::move(dispatch)),
+ : mClock(std::move(clock)),
+ mDispatch(std::move(dispatch)),
mTracker(std::move(tracker)),
mPendingLimit(pendingFenceLimit) {}
@@ -73,4 +77,14 @@ void VSyncReactor::setIgnorePresentFences(bool ignoration) {
}
}
+nsecs_t VSyncReactor::computeNextRefresh(int periodOffset) const {
+ auto const now = mClock->now();
+ auto const currentPeriod = periodOffset ? mTracker->currentPeriod() : 0;
+ return mTracker->nextAnticipatedVSyncTimeFrom(now + periodOffset * currentPeriod);
+}
+
+nsecs_t VSyncReactor::expectedPresentTime() {
+ return mTracker->nextAnticipatedVSyncTimeFrom(mClock->now());
+}
+
} // namespace android::scheduler
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.h b/services/surfaceflinger/Scheduler/VSyncReactor.h
index 05fd0fdec3..8436e8a8ce 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.h
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.h
@@ -24,19 +24,24 @@
namespace android::scheduler {
+class Clock;
class VSyncDispatch;
class VSyncTracker;
// TODO (b/145217110): consider renaming.
class VSyncReactor /* TODO (b/140201379): : public android::DispSync */ {
public:
- VSyncReactor(std::unique_ptr<VSyncDispatch> dispatch, std::unique_ptr<VSyncTracker> tracker,
- size_t pendingFenceLimit);
+ VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch,
+ std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit);
bool addPresentFence(const std::shared_ptr<FenceTime>& fence);
void setIgnorePresentFences(bool ignoration);
+ nsecs_t computeNextRefresh(int periodOffset) const;
+ nsecs_t expectedPresentTime();
+
private:
+ std::unique_ptr<Clock> const mClock;
std::unique_ptr<VSyncDispatch> const mDispatch;
std::unique_ptr<VSyncTracker> const mTracker;
size_t const mPendingLimit;
diff --git a/services/surfaceflinger/Scheduler/VSyncTracker.h b/services/surfaceflinger/Scheduler/VSyncTracker.h
index 97b9620cd6..335042d430 100644
--- a/services/surfaceflinger/Scheduler/VSyncTracker.h
+++ b/services/surfaceflinger/Scheduler/VSyncTracker.h
@@ -47,6 +47,13 @@ public:
*/
virtual nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const = 0;
+ /*
+ * The current period of the vsync signal.
+ *
+ * \return The current period of the vsync signal
+ */
+ virtual nsecs_t currentPeriod() const = 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 c01261619e..448954fbf4 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
@@ -47,6 +47,8 @@ public:
return timePoint - floor + mPeriod;
}
+ nsecs_t currentPeriod() const final { return mPeriod; }
+
private:
nsecs_t const mPeriod;
};
@@ -73,6 +75,11 @@ public:
mBase = last_known;
}
+ nsecs_t currentPeriod() const final {
+ std::lock_guard<decltype(mMutex)> lk(mMutex);
+ return mPeriod;
+ }
+
private:
std::mutex mutable mMutex;
nsecs_t mPeriod;
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
index 82950b5792..82b1051a6d 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
@@ -39,6 +39,7 @@ public:
MOCK_METHOD1(addVsyncTimestamp, void(nsecs_t));
MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
+ MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
nsecs_t nextVSyncTime(nsecs_t timePoint) const {
if (timePoint % mPeriod == 0) {
diff --git a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
index b4aebf0f19..c8784c686b 100644
--- a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "LibSurfaceFlingerUnittests"
#define LOG_NDEBUG 0
+#include "Scheduler/TimeKeeper.h"
#include "Scheduler/VSyncDispatch.h"
#include "Scheduler/VSyncReactor.h"
#include "Scheduler/VSyncTracker.h"
@@ -36,6 +37,7 @@ class MockVSyncTracker : public VSyncTracker {
public:
MOCK_METHOD1(addVsyncTimestamp, void(nsecs_t));
MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
+ MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
};
class VSyncTrackerWrapper : public VSyncTracker {
@@ -46,11 +48,27 @@ public:
nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const final {
return mTracker->nextAnticipatedVSyncTimeFrom(timePoint);
}
+ nsecs_t currentPeriod() const final { return mTracker->currentPeriod(); }
private:
std::shared_ptr<VSyncTracker> const mTracker;
};
+class MockClock : public Clock {
+public:
+ MOCK_CONST_METHOD0(now, nsecs_t());
+};
+
+class ClockWrapper : public Clock {
+public:
+ ClockWrapper(std::shared_ptr<Clock> const& clock) : mClock(clock) {}
+
+ nsecs_t now() const { return mClock->now(); }
+
+private:
+ std::shared_ptr<Clock> const mClock;
+};
+
class MockVSyncDispatch : public VSyncDispatch {
public:
MOCK_METHOD2(registerCallback, CallbackToken(std::function<void(nsecs_t)> const&, std::string));
@@ -107,11 +125,14 @@ protected:
VSyncReactorTest()
: mMockDispatch(std::make_shared<MockVSyncDispatch>()),
mMockTracker(std::make_shared<MockVSyncTracker>()),
- mReactor(std::make_unique<VSyncDispatchWrapper>(mMockDispatch),
+ mMockClock(std::make_shared<NiceMock<MockClock>>()),
+ mReactor(std::make_unique<ClockWrapper>(mMockClock),
+ std::make_unique<VSyncDispatchWrapper>(mMockDispatch),
std::make_unique<VSyncTrackerWrapper>(mMockTracker), kPendingLimit) {}
std::shared_ptr<MockVSyncDispatch> mMockDispatch;
std::shared_ptr<MockVSyncTracker> mMockTracker;
+ std::shared_ptr<MockClock> mMockClock;
static constexpr size_t kPendingLimit = 3;
static constexpr nsecs_t dummyTime = 47;
VSyncReactor mReactor;
@@ -181,4 +202,36 @@ TEST_F(VSyncReactorTest, ignoresPresentFencesWhenToldTo) {
EXPECT_FALSE(mReactor.addPresentFence(generateSignalledFenceWithTime(dummyTime)));
}
+TEST_F(VSyncReactorTest, queriesTrackerForNextRefreshNow) {
+ nsecs_t const fakeTimestamp = 4839;
+ EXPECT_CALL(*mMockTracker, currentPeriod()).Times(0);
+ EXPECT_CALL(*mMockTracker, nextAnticipatedVSyncTimeFrom(_))
+ .Times(1)
+ .WillOnce(Return(fakeTimestamp));
+
+ EXPECT_THAT(mReactor.computeNextRefresh(0), Eq(fakeTimestamp));
+}
+
+TEST_F(VSyncReactorTest, queriesTrackerForExpectedPresentTime) {
+ nsecs_t const fakeTimestamp = 4839;
+ EXPECT_CALL(*mMockTracker, currentPeriod()).Times(0);
+ EXPECT_CALL(*mMockTracker, nextAnticipatedVSyncTimeFrom(_))
+ .Times(1)
+ .WillOnce(Return(fakeTimestamp));
+
+ EXPECT_THAT(mReactor.expectedPresentTime(), Eq(fakeTimestamp));
+}
+
+TEST_F(VSyncReactorTest, queriesTrackerForNextRefreshFuture) {
+ nsecs_t const fakeTimestamp = 4839;
+ nsecs_t const fakePeriod = 1010;
+ nsecs_t const fakeNow = 2214;
+ int const numPeriodsOut = 3;
+ EXPECT_CALL(*mMockClock, now()).WillOnce(Return(fakeNow));
+ EXPECT_CALL(*mMockTracker, currentPeriod()).WillOnce(Return(fakePeriod));
+ EXPECT_CALL(*mMockTracker, nextAnticipatedVSyncTimeFrom(fakeNow + numPeriodsOut * fakePeriod))
+ .WillOnce(Return(fakeTimestamp));
+ EXPECT_THAT(mReactor.computeNextRefresh(numPeriodsOut), Eq(fakeTimestamp));
+}
+
} // namespace android::scheduler