diff options
author | Ady Abraham <adyabr@google.com> | 2021-07-19 12:24:31 -0700 |
---|---|---|
committer | Ady Abraham <adyabr@google.com> | 2021-07-19 16:28:52 -0700 |
commit | 69b9e62fd59d084e6b50a9afd6e8074a8c59594c (patch) | |
tree | 81fdd7fbdf22f9f8defd78dab147601eff68b40f | |
parent | 6a409e17600f320134dea722247c15770030d7b2 (diff) | |
download | native-69b9e62fd59d084e6b50a9afd6e8074a8c59594c.tar.gz |
SF: fix expected vsync time when changing work duration
When changing the work duration for a scheduled callback, we should
apply it on the next frame only if we would skip a callback call.
This change fixes the condition where we apply a different work
duration that doesn't change the wake up time but rather changes
the expected vsync time.
Test: TouchLatency bouncy ball + expand notification shade
Bug: 191969790
Change-Id: I067693fe361200a6f899bd81b74d8a1a155a452d
-rw-r--r-- | services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp | 7 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp | 21 |
2 files changed, 26 insertions, 2 deletions
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp index 28be962f2c..b805bf68e4 100644 --- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp +++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp @@ -84,10 +84,13 @@ ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTim VSyncTracker& tracker, nsecs_t now) { auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom( std::max(timing.earliestVsync, now + timing.workDuration + timing.readyDuration)); + auto nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration; bool const wouldSkipAVsyncTarget = mArmedInfo && (nextVsyncTime > (mArmedInfo->mActualVsyncTime + mMinVsyncDistance)); - if (wouldSkipAVsyncTarget) { + bool const wouldSkipAWakeup = + mArmedInfo && ((nextWakeupTime > (mArmedInfo->mActualWakeupTime + mMinVsyncDistance))); + if (wouldSkipAVsyncTarget && wouldSkipAWakeup) { return getExpectedCallbackTime(nextVsyncTime, timing); } @@ -97,9 +100,9 @@ ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTim if (alreadyDispatchedForVsync) { nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + mMinVsyncDistance); + nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration; } - auto const nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration; auto const nextReadyTime = nextVsyncTime - timing.readyDuration; mScheduleTiming = timing; mArmedInfo = {nextWakeupTime, nextVsyncTime, nextReadyTime}; diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp index d59d64bc02..ddc02bfbe6 100644 --- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp @@ -942,6 +942,27 @@ TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) { EXPECT_THAT(cb.mReadyTime[0], 970); } +TEST_F(VSyncDispatchTimerQueueTest, updatesVsyncTimeForCloseWakeupTime) { + Sequence seq; + EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq); + + CountingCallback cb(mDispatch); + + mDispatch.schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}); + mDispatch.schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000}); + + advanceToNextCallback(); + + advanceToNextCallback(); + + ASSERT_THAT(cb.mCalls.size(), Eq(1)); + EXPECT_THAT(cb.mCalls[0], Eq(2000)); + ASSERT_THAT(cb.mWakeupTime.size(), Eq(1)); + EXPECT_THAT(cb.mWakeupTime[0], Eq(600)); + ASSERT_THAT(cb.mReadyTime.size(), Eq(1)); + EXPECT_THAT(cb.mReadyTime[0], Eq(2000)); +} + class VSyncDispatchTimerQueueEntryTest : public testing::Test { protected: nsecs_t const mPeriod = 1000; |