diff options
| -rw-r--r-- | services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp | 6 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp | 31 |
2 files changed, 34 insertions, 3 deletions
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp index a596bce002..2a6fd0521f 100644 --- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp +++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp @@ -243,7 +243,8 @@ void VSyncDispatchTimerQueue::timerCallback() { std::vector<Invocation> invocations; { std::lock_guard<decltype(mMutex)> lk(mMutex); - mLastTimerCallback = mTimeKeeper->now(); + auto const now = mTimeKeeper->now(); + mLastTimerCallback = now; for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) { auto& callback = it->second; auto const wakeupTime = callback->wakeupTime(); @@ -251,7 +252,8 @@ void VSyncDispatchTimerQueue::timerCallback() { continue; } - if (*wakeupTime < mIntendedWakeupTime + mTimerSlack) { + auto const lagAllowance = std::max(now - mIntendedWakeupTime, static_cast<nsecs_t>(0)); + if (*wakeupTime < mIntendedWakeupTime + mTimerSlack + lagAllowance) { callback->executing(); invocations.emplace_back( Invocation{callback, *callback->lastExecutedVsyncTarget(), *wakeupTime}); diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp index d940dc5870..db5d6af611 100644 --- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp @@ -115,11 +115,15 @@ public: operator VSyncDispatch::CallbackToken() const { return mToken; } - void counter(nsecs_t time, nsecs_t) { mCalls.push_back(time); } + void counter(nsecs_t time, nsecs_t wakeup_time) { + mCalls.push_back(time); + mWakeupTime.push_back(wakeup_time); + } VSyncDispatch& mDispatch; VSyncDispatch::CallbackToken mToken; std::vector<nsecs_t> mCalls; + std::vector<nsecs_t> mWakeupTime; }; class PausingCallback { @@ -747,6 +751,31 @@ TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) { EXPECT_THAT(cb2.mCalls.size(), Eq(1)); } +TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) { + CountingCallback cb1(mDispatch); + CountingCallback cb2(mDispatch); + + Sequence seq; + EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)) + .InSequence(seq) + .WillOnce(Return(1000)); + EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq); + EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)) + .InSequence(seq) + .WillOnce(Return(1000)); + + EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled); + EXPECT_EQ(mDispatch.schedule(cb2, 390, 1000), ScheduleResult::Scheduled); + + mMockClock.setLag(100); + mMockClock.advanceBy(700); + + ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1)); + EXPECT_THAT(cb1.mWakeupTime[0], Eq(600)); + ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1)); + EXPECT_THAT(cb2.mWakeupTime[0], Eq(610)); +} + class VSyncDispatchTimerQueueEntryTest : public testing::Test { protected: nsecs_t const mPeriod = 1000; |