diff options
| author | 2020-10-16 23:48:02 +0000 | |
|---|---|---|
| committer | 2020-10-16 23:48:02 +0000 | |
| commit | a4d3a69c574a853e467eb03c87bc6d34f952017e (patch) | |
| tree | ee52b64d0ccedd2092dc0acab9856d8463312da1 | |
| parent | 3f21eafad7c078ffca17c901c1528820501b3f78 (diff) | |
| parent | 5ff4bb8fe1780d8132ec967938ad5e5bdff1a2ac (diff) | |
Merge changes I3d727530,Ia17bc5a0
* changes:
SurfaceFlinger: use TFD_TIMER_ABSTIME for VSP timer
VSR: dispatch cbs skipped due to timer lag.
7 files changed, 151 insertions, 73 deletions
diff --git a/services/surfaceflinger/Scheduler/TimeKeeper.h b/services/surfaceflinger/Scheduler/TimeKeeper.h index da2195c253..40dd8410a3 100644 --- a/services/surfaceflinger/Scheduler/TimeKeeper.h +++ b/services/surfaceflinger/Scheduler/TimeKeeper.h @@ -43,10 +43,10 @@ public: virtual ~TimeKeeper(); /* - * Arms callback to fired in time nanoseconds. + * Arms callback to fired when time is current based on CLOCK_MONOTONIC * There is only one timer, and subsequent calls will reset the callback function and the time. */ - virtual void alarmIn(std::function<void()> const& callback, nsecs_t time) = 0; + virtual void alarmAt(std::function<void()> const& callback, nsecs_t time) = 0; /* * Cancels an existing pending callback diff --git a/services/surfaceflinger/Scheduler/Timer.cpp b/services/surfaceflinger/Scheduler/Timer.cpp index 7c5058e431..59c336ab10 100644 --- a/services/surfaceflinger/Scheduler/Timer.cpp +++ b/services/surfaceflinger/Scheduler/Timer.cpp @@ -88,7 +88,7 @@ nsecs_t Timer::now() const { return systemTime(SYSTEM_TIME_MONOTONIC); } -void Timer::alarmIn(std::function<void()> const& cb, nsecs_t fireIn) { +void Timer::alarmAt(std::function<void()> const& cb, nsecs_t time) { std::lock_guard<decltype(mMutex)> lk(mMutex); using namespace std::literals; static constexpr int ns_per_s = @@ -99,11 +99,11 @@ void Timer::alarmIn(std::function<void()> const& cb, nsecs_t fireIn) { struct itimerspec old_timer; struct itimerspec new_timer { .it_interval = {.tv_sec = 0, .tv_nsec = 0}, - .it_value = {.tv_sec = static_cast<long>(fireIn / ns_per_s), - .tv_nsec = static_cast<long>(fireIn % ns_per_s)}, + .it_value = {.tv_sec = static_cast<long>(time / ns_per_s), + .tv_nsec = static_cast<long>(time % ns_per_s)}, }; - if (timerfd_settime(mTimerFd, 0, &new_timer, &old_timer)) { + if (timerfd_settime(mTimerFd, TFD_TIMER_ABSTIME, &new_timer, &old_timer)) { ALOGW("Failed to set timerfd %s (%i)", strerror(errno), errno); } } diff --git a/services/surfaceflinger/Scheduler/Timer.h b/services/surfaceflinger/Scheduler/Timer.h index a8e2d5a53d..69ce079437 100644 --- a/services/surfaceflinger/Scheduler/Timer.h +++ b/services/surfaceflinger/Scheduler/Timer.h @@ -30,9 +30,9 @@ public: ~Timer(); nsecs_t now() const final; - // NB: alarmIn and alarmCancel are threadsafe; with the last-returning function being effectual + // NB: alarmAt and alarmCancel are threadsafe; with the last-returning function being effectual // Most users will want to serialize thes calls so as to be aware of the timer state. - void alarmIn(std::function<void()> const& cb, nsecs_t fireIn) final; + void alarmAt(std::function<void()> const& cb, nsecs_t time) final; void alarmCancel() final; void dump(std::string& result) const final; diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp index a596bce002..ef9268015c 100644 --- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp +++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp @@ -180,10 +180,10 @@ void VSyncDispatchTimerQueue::cancelTimer() { mTimeKeeper->alarmCancel(); } -void VSyncDispatchTimerQueue::setTimer(nsecs_t targetTime, nsecs_t now) { +void VSyncDispatchTimerQueue::setTimer(nsecs_t targetTime, nsecs_t /*now*/) { mIntendedWakeupTime = targetTime; - mTimeKeeper->alarmIn(std::bind(&VSyncDispatchTimerQueue::timerCallback, this), - targetTime - now); + mTimeKeeper->alarmAt(std::bind(&VSyncDispatchTimerQueue::timerCallback, this), + mIntendedWakeupTime); mLastTimerSchedule = mTimeKeeper->now(); } @@ -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/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp index 3c4a791a5e..1bbc3f8b41 100644 --- a/services/surfaceflinger/tests/unittests/Android.bp +++ b/services/surfaceflinger/tests/unittests/Android.bp @@ -58,6 +58,7 @@ cc_test { "RegionSamplingTest.cpp", "TimeStatsTest.cpp", "FrameTracerTest.cpp", + "TimerTest.cpp", "TransactionApplicationTest.cpp", "StrongTypingTest.cpp", "VSyncDispatchTimerQueueTest.cpp", diff --git a/services/surfaceflinger/tests/unittests/TimerTest.cpp b/services/surfaceflinger/tests/unittests/TimerTest.cpp new file mode 100644 index 0000000000..cda6bbfe81 --- /dev/null +++ b/services/surfaceflinger/tests/unittests/TimerTest.cpp @@ -0,0 +1,45 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AsyncCallRecorder.h" +#include "Scheduler/TimeKeeper.h" +#include "Scheduler/Timer.h" + +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +using namespace testing; +using namespace std::literals; + +namespace android::scheduler { + +struct TimerTest : testing::Test { + static constexpr int mIterations = 20; + + AsyncCallRecorder<void (*)()> mCallbackRecorder; + Timer mTimer; + + void timerCallback() { mCallbackRecorder.recordCall(); } +}; + +TEST_F(TimerTest, callsCallbackIfScheduledInPast) { + for (int i = 0; i < mIterations; i++) { + mTimer.alarmAt(std::bind(&TimerTest::timerCallback, this), systemTime() - 10'000'00); + EXPECT_TRUE(mCallbackRecorder.waitForCall().has_value()); + EXPECT_FALSE(mCallbackRecorder.waitForUnexpectedCall().has_value()); + } +} +} // namespace android::scheduler diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp index d940dc5870..fa5cc32d29 100644 --- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp @@ -63,19 +63,19 @@ protected: class ControllableClock : public TimeKeeper { public: ControllableClock() { - ON_CALL(*this, alarmIn(_, _)) - .WillByDefault(Invoke(this, &ControllableClock::alarmInDefaultBehavior)); + ON_CALL(*this, alarmAt(_, _)) + .WillByDefault(Invoke(this, &ControllableClock::alarmAtDefaultBehavior)); ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime)); } MOCK_CONST_METHOD0(now, nsecs_t()); - MOCK_METHOD2(alarmIn, void(std::function<void()> const&, nsecs_t time)); + MOCK_METHOD2(alarmAt, void(std::function<void()> const&, nsecs_t time)); MOCK_METHOD0(alarmCancel, void()); MOCK_CONST_METHOD1(dump, void(std::string&)); - void alarmInDefaultBehavior(std::function<void()> const& callback, nsecs_t time) { + void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) { mCallback = callback; - mNextCallbackTime = time + mCurrentTime; + mNextCallbackTime = time; } nsecs_t fakeTime() const { return mCurrentTime; } @@ -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 { @@ -187,8 +191,8 @@ protected: class TimeKeeperWrapper : public TimeKeeper { public: TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {} - void alarmIn(std::function<void()> const& callback, nsecs_t time) final { - mControllableClock.alarmIn(callback, time); + void alarmAt(std::function<void()> const& callback, nsecs_t time) final { + mControllableClock.alarmAt(callback, time); } void alarmCancel() final { mControllableClock.alarmCancel(); } nsecs_t now() const final { return mControllableClock.now(); } @@ -217,7 +221,7 @@ protected: }; TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) { - EXPECT_CALL(mMockClock, alarmIn(_, 900)); + EXPECT_CALL(mMockClock, alarmAt(_, 900)); EXPECT_CALL(mMockClock, alarmCancel()); { VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold, @@ -229,7 +233,7 @@ TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) { TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) { auto intended = mPeriod - 230; - EXPECT_CALL(mMockClock, alarmIn(_, 900)); + EXPECT_CALL(mMockClock, alarmAt(_, 900)); CountingCallback cb(mDispatch); EXPECT_EQ(mDispatch.schedule(cb, 100, intended), ScheduleResult::Scheduled); @@ -241,7 +245,7 @@ TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) { TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) { EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150)); - EXPECT_CALL(mMockClock, alarmIn(_, 1050)); + EXPECT_CALL(mMockClock, alarmAt(_, 1050)); CountingCallback cb(mDispatch); mDispatch.schedule(cb, 100, mPeriod); @@ -257,14 +261,14 @@ TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) { auto const workDuration = 10 * mPeriod; EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + workDuration)) .WillOnce(Return(mPeriod * 11)); - EXPECT_CALL(mMockClock, alarmIn(_, mPeriod - now)); + EXPECT_CALL(mMockClock, alarmAt(_, mPeriod)); CountingCallback cb(mDispatch); EXPECT_EQ(mDispatch.schedule(cb, workDuration, mPeriod), ScheduleResult::Scheduled); } TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) { - EXPECT_CALL(mMockClock, alarmIn(_, 900)); + EXPECT_CALL(mMockClock, alarmAt(_, 900)); EXPECT_CALL(mMockClock, alarmCancel()); CountingCallback cb(mDispatch); @@ -273,7 +277,7 @@ TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) { } TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) { - EXPECT_CALL(mMockClock, alarmIn(_, 900)); + EXPECT_CALL(mMockClock, alarmAt(_, 900)); EXPECT_CALL(mMockClock, alarmCancel()); CountingCallback cb(mDispatch); @@ -283,7 +287,7 @@ TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) { } TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) { - EXPECT_CALL(mMockClock, alarmIn(_, 900)); + EXPECT_CALL(mMockClock, alarmAt(_, 900)); EXPECT_CALL(mMockClock, alarmCancel()); PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s)); @@ -297,7 +301,7 @@ TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) { } TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) { - EXPECT_CALL(mMockClock, alarmIn(_, 900)); + EXPECT_CALL(mMockClock, alarmAt(_, 900)); EXPECT_CALL(mMockClock, alarmCancel()); auto resource = std::make_shared<int>(110); @@ -327,9 +331,9 @@ TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) { .WillOnce(Return(1075)); Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 955)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 813)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 162)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq); CountingCallback cb0(mDispatch); CountingCallback cb1(mDispatch); @@ -355,9 +359,9 @@ TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) { .WillOnce(Return(10000)); Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 9900)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 750)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 9900)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq); CountingCallback cb0(mDispatch); CountingCallback cb1(mDispatch); @@ -369,8 +373,8 @@ TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) { TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 100)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq); CountingCallback cb0(mDispatch); CountingCallback cb1(mDispatch); @@ -383,9 +387,9 @@ TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) { TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 100)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq); CountingCallback cb0(mDispatch); CountingCallback cb1(mDispatch); @@ -398,10 +402,10 @@ TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) { TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 990)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 10)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq); auto offset = 400; auto closeOffset = offset + mDispatchGroupThreshold - 1; @@ -432,9 +436,10 @@ TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) { } TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) { - EXPECT_CALL(mMockClock, alarmIn(_, 900)); - EXPECT_CALL(mMockClock, alarmIn(_, 800)); - EXPECT_CALL(mMockClock, alarmIn(_, 100)); + Sequence seq; + EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq); EXPECT_CALL(mMockClock, alarmCancel()); CountingCallback cb0(mDispatch); @@ -472,8 +477,8 @@ TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 900)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq); VSyncDispatch::CallbackToken tmp; tmp = mDispatch.registerCallback([&](auto, auto) { mDispatch.schedule(tmp, 100, 2000); }, @@ -507,10 +512,10 @@ TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) { TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 200)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 150)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq); CountingCallback cb(mDispatch); mDispatch.schedule(cb, 0, 1000); @@ -527,10 +532,10 @@ TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) { TEST_F(VSyncDispatchTimerQueueTest, lateModifications) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 400)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 350)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 950)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq); CountingCallback cb0(mDispatch); CountingCallback cb1(mDispatch); @@ -548,7 +553,7 @@ TEST_F(VSyncDispatchTimerQueueTest, lateModifications) { TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq); CountingCallback cb0(mDispatch); CountingCallback cb1(mDispatch); @@ -558,9 +563,9 @@ TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) { TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq); EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 900)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq); CountingCallback cb0(mDispatch); mDispatch.schedule(cb0, 500, 1000); @@ -582,7 +587,7 @@ TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) { // b/1450138150 TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) { - EXPECT_CALL(mMockClock, alarmIn(_, 500)); + EXPECT_CALL(mMockClock, alarmAt(_, 500)); CountingCallback cb(mDispatch); EXPECT_EQ(mDispatch.schedule(cb, 500, 1000), ScheduleResult::Scheduled); mMockClock.advanceBy(400); @@ -612,8 +617,8 @@ TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPer TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq); CountingCallback cb0(mDispatch); EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled); advanceToNextCallback(); @@ -621,7 +626,7 @@ TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) { } TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) { - EXPECT_CALL(mMockClock, alarmIn(_, 600)); + EXPECT_CALL(mMockClock, alarmAt(_, 600)); CountingCallback cb(mDispatch); EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled); @@ -632,7 +637,7 @@ TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) } TEST_F(VSyncDispatchTimerQueueTest, helperMove) { - EXPECT_CALL(mMockClock, alarmIn(_, 500)).Times(1); + EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1); EXPECT_CALL(mMockClock, alarmCancel()).Times(1); VSyncCallbackRegistration cb( @@ -646,7 +651,7 @@ TEST_F(VSyncDispatchTimerQueueTest, helperMove) { } TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) { - EXPECT_CALL(mMockClock, alarmIn(_, 500)).Times(1); + EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1); EXPECT_CALL(mMockClock, alarmCancel()).Times(1); VSyncCallbackRegistration cb( @@ -664,8 +669,8 @@ TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) { // b/154303580 TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 1200)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq); CountingCallback cb1(mDispatch); CountingCallback cb2(mDispatch); @@ -686,8 +691,8 @@ TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent // update later, as opposed to blocking the calling thread. TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 930)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq); CountingCallback cb(mDispatch); EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled); @@ -704,7 +709,7 @@ TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent // b/154303580. TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq); EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq); CountingCallback cb1(mDispatch); CountingCallback cb2(mDispatch); @@ -725,8 +730,8 @@ TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) { TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) { Sequence seq; - EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq); - EXPECT_CALL(mMockClock, alarmIn(_, 1280)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq); + EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq); EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq); CountingCallback cb1(mDispatch); CountingCallback cb2(mDispatch); @@ -747,6 +752,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, alarmAt(_, 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; |