[SF] Send NotifyExpectedPresentHint at the transaction time
BUG: 314199179
BUG: 315989692
BUG: 284845445
Test: atest NotifyExpectedPresentTest
Change-Id: Ief7fff69e8b92f0affd228b2bdcdc5009806f905
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index d5ec654..3eabe1f 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -117,14 +117,16 @@
mThread->onVsync(expectedPresentationTime, timestamp, deadlineTimestamp);
}
+ static constexpr scheduler::ScheduleResult kScheduleResult{TimePoint::fromNs(0),
+ TimePoint::fromNs(0)};
AsyncCallRecorderWithCannedReturn<
scheduler::ScheduleResult (*)(scheduler::VSyncDispatch::CallbackToken,
scheduler::VSyncDispatch::ScheduleTiming)>
- mVSyncCallbackScheduleRecorder{0};
+ mVSyncCallbackScheduleRecorder{kScheduleResult};
AsyncCallRecorderWithCannedReturn<
scheduler::ScheduleResult (*)(scheduler::VSyncDispatch::CallbackToken,
scheduler::VSyncDispatch::ScheduleTiming)>
- mVSyncCallbackUpdateRecorder{0};
+ mVSyncCallbackUpdateRecorder{kScheduleResult};
AsyncCallRecorderWithCannedReturn<
scheduler::VSyncDispatch::CallbackToken (*)(scheduler::VSyncDispatch::Callback,
std::string)>
diff --git a/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp b/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp
index f5661fc..71f9f88 100644
--- a/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp
@@ -25,6 +25,7 @@
#include "FrameTimeline.h"
#include "Scheduler/MessageQueue.h"
#include "mock/MockVSyncDispatch.h"
+#include "utils/Timers.h"
namespace android {
@@ -49,6 +50,8 @@
using MessageQueue::Handler::Handler;
MOCK_METHOD(void, dispatchFrame, (VsyncId, TimePoint), (override));
+ MOCK_METHOD(bool, isFramePending, (), (const, override));
+ MOCK_METHOD(TimePoint, getExpectedVsyncTime, (), (const override));
};
explicit TestableMessageQueue(sp<MockHandler> handler)
@@ -94,13 +97,17 @@
const auto timing = scheduler::VSyncDispatch::ScheduleTiming{.workDuration = kDuration.ns(),
.readyDuration = 0,
.lastVsync = 0};
- EXPECT_FALSE(mEventQueue.getScheduledFrameTime());
+ EXPECT_FALSE(mEventQueue.getScheduledFrameResult());
- EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(1234));
+ const auto timePoint = TimePoint::fromNs(1234);
+ const auto scheduleResult = scheduler::ScheduleResult{timePoint, timePoint};
+ EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(scheduleResult));
EXPECT_NO_FATAL_FAILURE(mEventQueue.scheduleFrame());
- ASSERT_TRUE(mEventQueue.getScheduledFrameTime());
- EXPECT_EQ(1234, mEventQueue.getScheduledFrameTime()->time_since_epoch().count());
+ const auto scheduledFrameResult = mEventQueue.getScheduledFrameResult();
+ ASSERT_TRUE(scheduledFrameResult);
+ EXPECT_EQ(1234, scheduledFrameResult->callbackTime.ns());
+ EXPECT_EQ(1234, scheduledFrameResult->vsyncTime.ns());
}
TEST_F(MessageQueueTest, commitTwice) {
@@ -109,17 +116,25 @@
.readyDuration = 0,
.lastVsync = 0};
- EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(1234));
+ auto timePoint = TimePoint::fromNs(1234);
+ auto scheduleResult = scheduler::ScheduleResult{timePoint, timePoint};
+ EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(scheduleResult));
EXPECT_NO_FATAL_FAILURE(mEventQueue.scheduleFrame());
- ASSERT_TRUE(mEventQueue.getScheduledFrameTime());
- EXPECT_EQ(1234, mEventQueue.getScheduledFrameTime()->time_since_epoch().count());
+ auto scheduledFrameResult = mEventQueue.getScheduledFrameResult();
+ ASSERT_TRUE(scheduledFrameResult);
+ EXPECT_EQ(1234, scheduledFrameResult->callbackTime.ns());
+ EXPECT_EQ(1234, scheduledFrameResult->vsyncTime.ns());
- EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(4567));
+ timePoint = TimePoint::fromNs(4567);
+ scheduleResult = scheduler::ScheduleResult{timePoint, timePoint};
+ EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(scheduleResult));
EXPECT_NO_FATAL_FAILURE(mEventQueue.scheduleFrame());
- ASSERT_TRUE(mEventQueue.getScheduledFrameTime());
- EXPECT_EQ(4567, mEventQueue.getScheduledFrameTime()->time_since_epoch().count());
+ scheduledFrameResult = mEventQueue.getScheduledFrameResult();
+ ASSERT_TRUE(scheduledFrameResult);
+ EXPECT_EQ(4567, scheduledFrameResult->callbackTime.ns());
+ EXPECT_EQ(4567, scheduledFrameResult->vsyncTime.ns());
}
TEST_F(MessageQueueTest, commitTwiceWithCallback) {
@@ -128,11 +143,15 @@
.readyDuration = 0,
.lastVsync = 0};
- EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(1234));
+ const auto timePoint = TimePoint::fromNs(1234);
+ auto scheduleResult = scheduler::ScheduleResult{timePoint, timePoint};
+ EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(scheduleResult));
EXPECT_NO_FATAL_FAILURE(mEventQueue.scheduleFrame());
- ASSERT_TRUE(mEventQueue.getScheduledFrameTime());
- EXPECT_EQ(1234, mEventQueue.getScheduledFrameTime()->time_since_epoch().count());
+ auto scheduledFrameResult = mEventQueue.getScheduledFrameResult();
+ ASSERT_TRUE(scheduledFrameResult);
+ EXPECT_EQ(1234, scheduledFrameResult->callbackTime.ns());
+ EXPECT_EQ(1234, scheduledFrameResult->vsyncTime.ns());
constexpr TimePoint kStartTime = TimePoint::fromNs(100);
constexpr TimePoint kEndTime = kStartTime + kDuration;
@@ -148,14 +167,15 @@
EXPECT_NO_FATAL_FAILURE(
mEventQueue.vsyncCallback(kPresentTime.ns(), kStartTime.ns(), kEndTime.ns()));
- EXPECT_FALSE(mEventQueue.getScheduledFrameTime());
+ EXPECT_FALSE(mEventQueue.getScheduledFrameResult());
const auto timingAfterCallback =
scheduler::VSyncDispatch::ScheduleTiming{.workDuration = kDuration.ns(),
.readyDuration = 0,
.lastVsync = kPresentTime.ns()};
-
- EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timingAfterCallback)).WillOnce(Return(0));
+ scheduleResult = scheduler::ScheduleResult{TimePoint::fromNs(0), TimePoint::fromNs(0)};
+ EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timingAfterCallback))
+ .WillOnce(Return(scheduleResult));
EXPECT_NO_FATAL_FAILURE(mEventQueue.scheduleFrame());
}
@@ -167,9 +187,24 @@
.readyDuration = 0,
.lastVsync = 0};
- EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(0));
+ const auto scheduleResult =
+ scheduler::ScheduleResult{TimePoint::fromNs(0), TimePoint::fromNs(0)};
+ EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(scheduleResult));
EXPECT_NO_FATAL_FAILURE(mEventQueue.scheduleFrame());
}
+TEST_F(MessageQueueTest, scheduleResultWhenFrameIsPending) {
+ const auto timePoint = TimePoint::now();
+ EXPECT_CALL(*mEventQueue.mHandler, isFramePending()).WillOnce(Return(true));
+ EXPECT_CALL(*mEventQueue.mHandler, getExpectedVsyncTime()).WillRepeatedly(Return(timePoint));
+
+ const auto scheduledFrameResult = mEventQueue.getScheduledFrameResult();
+
+ ASSERT_TRUE(scheduledFrameResult);
+ EXPECT_NEAR(static_cast<double>(TimePoint::now().ns()),
+ static_cast<double>(scheduledFrameResult->callbackTime.ns()), ms2ns(1));
+ EXPECT_EQ(timePoint, scheduledFrameResult->vsyncTime);
+}
+
} // namespace
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp
index 91b9018..20a3315 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp
@@ -41,6 +41,33 @@
}
protected:
+ void setTransactionState() {
+ ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
+ TransactionInfo transaction;
+ mFlinger.setTransactionState(FrameTimelineInfo{}, transaction.states, transaction.displays,
+ transaction.flags, transaction.applyToken,
+ transaction.inputWindowCommands,
+ TimePoint::now().ns() + s2ns(1), transaction.isAutoTimestamp,
+ transaction.unCachedBuffers,
+ /*HasListenerCallbacks=*/false, transaction.callbacks,
+ transaction.id, transaction.mergedTransactionIds);
+ }
+
+ struct TransactionInfo {
+ Vector<ComposerState> states;
+ Vector<DisplayState> displays;
+ uint32_t flags = 0;
+ sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
+ InputWindowCommands inputWindowCommands;
+ int64_t desiredPresentTime = 0;
+ bool isAutoTimestamp = false;
+ FrameTimelineInfo frameTimelineInfo{};
+ std::vector<client_cache_t> unCachedBuffers;
+ uint64_t id = static_cast<uint64_t>(-1);
+ std::vector<uint64_t> mergedTransactionIds;
+ std::vector<ListenerCallbacks> callbacks;
+ };
+
struct Compositor final : ICompositor {
explicit Compositor(PhysicalDisplayId displayId, TestableSurfaceFlinger& surfaceFlinger)
: displayId(displayId), surfaceFlinger(surfaceFlinger) {}
@@ -102,7 +129,7 @@
};
TEST_F(NotifyExpectedPresentTest, noNotifyExpectedPresentHintCall_absentTimeout) {
- auto expectedPresentTime = systemTime() + ms2ns(10);
+ auto expectedPresentTime = TimePoint::now().ns() + ms2ns(10);
ASSERT_NO_FATAL_FAILURE(
mFlinger.setNotifyExpectedPresentData(mPhysicalDisplayId,
TimePoint::fromNs(expectedPresentTime),
@@ -120,7 +147,7 @@
}
TEST_F(NotifyExpectedPresentTest, notifyExpectedPresentHint_zeroTimeout) {
- auto expectedPresentTime = systemTime() + ms2ns(10);
+ auto expectedPresentTime = TimePoint::now().ns() + ms2ns(10);
{
// Very first ExpectedPresent after idle, no previous timestamp.
EXPECT_CALL(*mComposer,
@@ -139,6 +166,10 @@
{
mCompositor->committed = false;
expectedPresentTime += kFrameInterval60HzNs;
+ EXPECT_CALL(static_cast<mock::VSyncTracker&>(
+ mFlinger.scheduler()->getVsyncSchedule()->getTracker()),
+ nextAnticipatedVSyncTimeFrom(_, _))
+ .WillRepeatedly(Return(expectedPresentTime));
EXPECT_CALL(*mComposer,
notifyExpectedPresent(kHwcDisplayId, expectedPresentTime, kFrameInterval60HzNs))
.WillOnce(Return(Error::NONE));
@@ -154,6 +185,10 @@
}
{
expectedPresentTime += kFrameInterval60HzNs;
+ EXPECT_CALL(static_cast<mock::VSyncTracker&>(
+ mFlinger.scheduler()->getVsyncSchedule()->getTracker()),
+ nextAnticipatedVSyncTimeFrom(_, _))
+ .WillRepeatedly(Return(expectedPresentTime));
EXPECT_CALL(*mComposer,
notifyExpectedPresent(kHwcDisplayId, expectedPresentTime, kFrameInterval60HzNs))
.WillOnce(Return(Error::NONE));
@@ -168,9 +203,8 @@
ASSERT_TRUE(mFlinger.verifyHintIsSent(mPhysicalDisplayId));
}
}
-
TEST_F(NotifyExpectedPresentTest, notifyExpectedPresentTimeout) {
- auto expectedPresentTime = systemTime() + ms2ns(10);
+ auto expectedPresentTime = TimePoint::now().ns() + ms2ns(10);
{
// Very first ExpectedPresent after idle, no previous timestamp
mCompositor->committed = false;
@@ -185,6 +219,27 @@
ASSERT_TRUE(mFlinger.verifyHintIsSent(mPhysicalDisplayId));
}
{
+ EXPECT_CALL(*mComposer, notifyExpectedPresent(kHwcDisplayId, _, _)).Times(0);
+ expectedPresentTime += 2 * kFrameInterval5HzNs;
+ mFlinger.notifyExpectedPresentIfRequired(mPhysicalDisplayId, kVsyncPeriod,
+ TimePoint::fromNs(expectedPresentTime), kFps60Hz,
+ kTimeoutNs);
+ EXPECT_TRUE(
+ mFlinger.verifyLastExpectedPresentTime(mPhysicalDisplayId, expectedPresentTime));
+ ASSERT_TRUE(mFlinger.verifyHintStatusIsScheduledOnTx(mPhysicalDisplayId));
+ mFlinger.scheduler()->doFrameSignal(*mCompositor, VsyncId{42});
+ ASSERT_TRUE(mFlinger.verifyHintStatusIsScheduledOnTx(mPhysicalDisplayId));
+ {
+ EXPECT_CALL(*mComposer,
+ notifyExpectedPresent(kHwcDisplayId, expectedPresentTime,
+ kFrameInterval60HzNs))
+ .WillOnce(Return(Error::NONE));
+ // Hint sent with the setTransactionState
+ setTransactionState();
+ ASSERT_TRUE(mFlinger.verifyHintIsSent(mPhysicalDisplayId));
+ }
+ }
+ {
// ExpectedPresentTime is after the timeoutNs
mCompositor->committed = true;
expectedPresentTime += 2 * kFrameInterval5HzNs;
@@ -194,7 +249,7 @@
kTimeoutNs);
EXPECT_TRUE(
mFlinger.verifyLastExpectedPresentTime(mPhysicalDisplayId, expectedPresentTime));
- ASSERT_TRUE(mFlinger.verifyHintIsSent(mPhysicalDisplayId));
+ ASSERT_TRUE(mFlinger.verifyHintStatusIsScheduledOnTx(mPhysicalDisplayId));
mFlinger.scheduler()->doFrameSignal(*mCompositor, VsyncId{42});
// Present happens notifyExpectedPresentHintStatus is Start
ASSERT_TRUE(mFlinger.verifyHintStatusIsStart(mPhysicalDisplayId));
@@ -259,7 +314,7 @@
}
TEST_F(NotifyExpectedPresentTest, notifyExpectedPresentRenderRateChanged) {
- const auto now = systemTime();
+ const auto now = TimePoint::now().ns();
auto expectedPresentTime = now;
static constexpr Period kTimeoutNs = Period::fromNs(static_cast<Fps>(1_Hz).getPeriodNsecs());
@@ -298,6 +353,10 @@
TimePoint::fromNs(expectedPresentTime),
Fps::fromPeriodNsecs(frameIntervalNs), kTimeoutNs);
+ EXPECT_CALL(static_cast<mock::VSyncTracker&>(
+ mFlinger.scheduler()->getVsyncSchedule()->getTracker()),
+ nextAnticipatedVSyncTimeFrom(_, _))
+ .WillRepeatedly(Return(expectedPresentTime));
if (callNotifyExpectedPresentHint) {
mCompositor->committed = false;
ASSERT_TRUE(mFlinger.verifyHintIsScheduledOnPresent(mPhysicalDisplayId))
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
index eb4e84e..951faf6 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
@@ -247,7 +247,8 @@
mDispatch->schedule(cb,
{.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(900, *result);
+ EXPECT_EQ(900, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
}
}
@@ -260,7 +261,8 @@
mDispatch->schedule(cb,
{.workDuration = 100, .readyDuration = 0, .lastVsync = intended});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(900, *result);
+ EXPECT_EQ(900, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
advanceToNextCallback();
@@ -279,12 +281,14 @@
mDispatch->schedule(cb,
{.workDuration = 100, .readyDuration = 0, .lastVsync = intended});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(900, *result);
+ EXPECT_EQ(900, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
result =
mDispatch->update(cb, {.workDuration = 300, .readyDuration = 0, .lastVsync = intended});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(700, *result);
+ EXPECT_EQ(700, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
advanceToNextCallback();
@@ -332,7 +336,8 @@
.readyDuration = 0,
.lastVsync = mPeriod});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(mPeriod, *result);
+ EXPECT_EQ(mPeriod, result->callbackTime.ns());
+ EXPECT_EQ(workDuration + mPeriod, result->vsyncTime.ns());
}
TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
@@ -344,7 +349,8 @@
mDispatch->schedule(cb,
{.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(mPeriod - 100, *result);
+ EXPECT_EQ(mPeriod - 100, result->callbackTime.ns());
+ EXPECT_EQ(mPeriod, result->vsyncTime.ns());
EXPECT_EQ(mDispatch->cancel(cb), CancelResult::Cancelled);
}
@@ -357,7 +363,8 @@
mDispatch->schedule(cb,
{.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(mPeriod - 100, *result);
+ EXPECT_EQ(mPeriod - 100, result->callbackTime.ns());
+ EXPECT_EQ(mPeriod, result->vsyncTime.ns());
mMockClock.advanceBy(950);
EXPECT_EQ(mDispatch->cancel(cb), CancelResult::TooLate);
}
@@ -371,7 +378,8 @@
mDispatch->schedule(cb,
{.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(mPeriod - 100, *result);
+ EXPECT_EQ(mPeriod - 100, result->callbackTime.ns());
+ EXPECT_EQ(mPeriod, result->vsyncTime.ns());
std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
EXPECT_TRUE(cb.waitForPause());
@@ -392,7 +400,8 @@
mDispatch->schedule(cb,
{.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(mPeriod - 100, *result);
+ EXPECT_EQ(mPeriod - 100, result->callbackTime.ns());
+ EXPECT_EQ(mPeriod, result->vsyncTime.ns());
std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
EXPECT_TRUE(cb.waitForPause());
@@ -625,19 +634,22 @@
.readyDuration = 0,
.lastVsync = timestamp - mVsyncMoveThreshold});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(mPeriod + timestamp - 400, *result);
+ EXPECT_EQ(mPeriod + timestamp - 400, result->callbackTime.ns());
+ EXPECT_EQ(mPeriod + timestamp, result->vsyncTime.ns());
result = mDispatch->schedule(tmp,
{.workDuration = 400,
.readyDuration = 0,
.lastVsync = timestamp});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(mPeriod + timestamp - 400, *result);
+ EXPECT_EQ(mPeriod + timestamp - 400, result->callbackTime.ns());
+ EXPECT_EQ(mPeriod + timestamp, result->vsyncTime.ns());
result = mDispatch->schedule(tmp,
{.workDuration = 400,
.readyDuration = 0,
.lastVsync = timestamp + mVsyncMoveThreshold});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(mPeriod + timestamp - 400, *result);
+ EXPECT_EQ(mPeriod + timestamp - 400, result->callbackTime.ns());
+ EXPECT_EQ(mPeriod + timestamp, result->vsyncTime.ns());
lastTarget = timestamp;
},
"oo");
@@ -726,10 +738,12 @@
auto result =
mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(500, *result);
+ EXPECT_EQ(500, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
result = mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(900, *result);
+ EXPECT_EQ(900, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
}
// b/1450138150
@@ -741,12 +755,14 @@
auto result =
mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(500, *result);
+ EXPECT_EQ(500, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
mMockClock.advanceBy(400);
result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(1200, *result);
+ EXPECT_EQ(1200, result->callbackTime.ns());
+ EXPECT_EQ(2000, result->vsyncTime.ns());
advanceToNextCallback();
ASSERT_THAT(cb.mCalls.size(), Eq(1));
@@ -763,12 +779,14 @@
auto result =
mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(500, *result);
+ EXPECT_EQ(500, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
mMockClock.advanceBy(400);
result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(400, *result);
+ EXPECT_EQ(400, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
advanceToNextCallback();
ASSERT_THAT(cb.mCalls.size(), Eq(1));
@@ -784,11 +802,13 @@
auto result =
mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(500, *result);
+ EXPECT_EQ(500, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
mMockClock.advanceBy(400);
result = mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(602, *result);
+ EXPECT_EQ(602, result->callbackTime.ns());
+ EXPECT_EQ(1002, result->vsyncTime.ns());
}
TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
@@ -796,12 +816,14 @@
auto result =
mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(500, *result);
+ EXPECT_EQ(500, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
advanceToNextCallback();
result =
mDispatch->schedule(cb0, {.workDuration = 1100, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(900, *result);
+ EXPECT_EQ(900, result->callbackTime.ns());
+ EXPECT_EQ(2000, result->vsyncTime.ns());
}
TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
@@ -812,12 +834,14 @@
auto result =
mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(500, *result);
+ EXPECT_EQ(500, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
advanceToNextCallback();
result =
mDispatch->schedule(cb0, {.workDuration = 1900, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(1100, *result);
+ EXPECT_EQ(1100, result->callbackTime.ns());
+ EXPECT_EQ(3000, result->vsyncTime.ns());
}
TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
@@ -829,11 +853,13 @@
auto result =
mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(600, *result);
+ EXPECT_EQ(600, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
result = mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(600, *result);
+ EXPECT_EQ(600, result->callbackTime.ns());
+ EXPECT_EQ(2000, result->vsyncTime.ns());
advanceToNextCallback();
}
@@ -849,11 +875,13 @@
auto result =
mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(600, *result);
+ EXPECT_EQ(600, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
result = mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(0, *result);
+ EXPECT_EQ(0, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
advanceToNextCallback();
}
@@ -899,14 +927,16 @@
auto result =
mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(600, *result);
+ EXPECT_EQ(600, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
mMockClock.setLag(100);
mMockClock.advanceBy(620);
result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(1900, *result);
+ EXPECT_EQ(1900, result->callbackTime.ns());
+ EXPECT_EQ(2000, result->vsyncTime.ns());
mMockClock.advanceBy(80);
EXPECT_THAT(cb1.mCalls.size(), Eq(1));
@@ -927,14 +957,16 @@
auto result =
mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(600, *result);
+ EXPECT_EQ(600, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
mMockClock.setLag(100);
mMockClock.advanceBy(620);
result = mDispatch->schedule(cb, {.workDuration = 370, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(1630, *result);
+ EXPECT_EQ(1630, result->callbackTime.ns());
+ EXPECT_EQ(2000, result->vsyncTime.ns());
mMockClock.advanceBy(80);
EXPECT_THAT(cb.mCalls.size(), Eq(1));
@@ -954,14 +986,16 @@
auto result =
mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(600, *result);
+ EXPECT_EQ(600, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
mMockClock.setLag(100);
mMockClock.advanceBy(620);
result = mDispatch->schedule(cb, {.workDuration = 370, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(600, *result);
+ EXPECT_EQ(600, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
mMockClock.advanceBy(80);
ASSERT_EQ(1, cb.mCalls.size());
@@ -982,10 +1016,12 @@
auto result =
mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(600, *result);
+ EXPECT_EQ(600, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(1900, *result);
+ EXPECT_EQ(1900, result->callbackTime.ns());
+ EXPECT_EQ(2000, result->vsyncTime.ns());
mMockClock.setLag(100);
mMockClock.advanceBy(620);
@@ -1009,10 +1045,12 @@
auto result =
mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(600, *result);
+ EXPECT_EQ(600, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(1900, *result);
+ EXPECT_EQ(1900, result->callbackTime.ns());
+ EXPECT_EQ(2000, result->vsyncTime.ns());
mMockClock.setLag(100);
mMockClock.advanceBy(620);
@@ -1045,10 +1083,12 @@
auto result =
mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(600, *result);
+ EXPECT_EQ(600, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
result = mDispatch->schedule(cb2, {.workDuration = 390, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(610, *result);
+ EXPECT_EQ(610, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
mMockClock.setLag(100);
mMockClock.advanceBy(700);
@@ -1072,7 +1112,8 @@
mDispatch->schedule(cb,
{.workDuration = 70, .readyDuration = 30, .lastVsync = intended});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(900, *result);
+ EXPECT_EQ(900, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
advanceToNextCallback();
ASSERT_THAT(cb.mCalls.size(), Eq(1));
@@ -1138,12 +1179,14 @@
auto result =
mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(500, *result);
+ EXPECT_EQ(500, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
mMockClock.advanceBy(300);
result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(1200, *result);
+ EXPECT_EQ(1200, result->callbackTime.ns());
+ EXPECT_EQ(2000, result->vsyncTime.ns());
advanceToNextCallback();
ASSERT_THAT(cb.mCalls.size(), Eq(1));
@@ -1159,12 +1202,14 @@
auto result =
mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(500, *result);
+ EXPECT_EQ(500, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
mMockClock.advanceBy(300);
result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
- EXPECT_EQ(300, *result);
+ EXPECT_EQ(300, result->callbackTime.ns());
+ EXPECT_EQ(1000, result->vsyncTime.ns());
advanceToNextCallback();
ASSERT_THAT(cb.mCalls.size(), Eq(1));
@@ -1197,9 +1242,12 @@
"test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
EXPECT_FALSE(entry.wakeupTime());
- EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
- *mStubTracker.get(), 0)
- .has_value());
+ const auto scheduleResultOpt =
+ entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
+ *mStubTracker, 0);
+ ASSERT_TRUE(scheduleResultOpt);
+ EXPECT_EQ(900, scheduleResultOpt->callbackTime.ns());
+ EXPECT_EQ(1000, scheduleResultOpt->vsyncTime.ns());
auto const wakeup = entry.wakeupTime();
ASSERT_TRUE(wakeup);
EXPECT_THAT(*wakeup, Eq(900));
@@ -1220,9 +1268,12 @@
"test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
EXPECT_FALSE(entry.wakeupTime());
- EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 994},
- *mStubTracker.get(), now)
- .has_value());
+ const auto scheduleResultOpt =
+ entry.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 994},
+ *mStubTracker, now);
+ ASSERT_TRUE(scheduleResultOpt);
+ EXPECT_EQ(9500, scheduleResultOpt->callbackTime.ns());
+ EXPECT_EQ(10000, scheduleResultOpt->vsyncTime.ns());
auto const wakeup = entry.wakeupTime();
ASSERT_TRUE(wakeup);
EXPECT_THAT(*wakeup, Eq(9500));
@@ -1243,9 +1294,12 @@
},
mVsyncMoveThreshold);
- EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
- *mStubTracker.get(), 0)
- .has_value());
+ const auto scheduleResultOpt =
+ entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
+ *mStubTracker, 0);
+ ASSERT_TRUE(scheduleResultOpt);
+ EXPECT_EQ(900, scheduleResultOpt->callbackTime.ns());
+ EXPECT_EQ(1000, scheduleResultOpt->vsyncTime.ns());
auto const wakeup = entry.wakeupTime();
ASSERT_TRUE(wakeup);
EXPECT_THAT(*wakeup, Eq(900));
@@ -1275,17 +1329,20 @@
"test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
EXPECT_FALSE(entry.wakeupTime());
- entry.update(*mStubTracker.get(), 0);
+ entry.update(*mStubTracker, 0);
EXPECT_FALSE(entry.wakeupTime());
- EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
- *mStubTracker.get(), 0)
- .has_value());
+ const auto scheduleResultOpt =
+ entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
+ *mStubTracker, 0);
+ ASSERT_TRUE(scheduleResultOpt);
+ EXPECT_EQ(900, scheduleResultOpt->callbackTime.ns());
+ EXPECT_EQ(1000, scheduleResultOpt->vsyncTime.ns());
auto wakeup = entry.wakeupTime();
ASSERT_TRUE(wakeup);
EXPECT_THAT(wakeup, Eq(900));
- entry.update(*mStubTracker.get(), 0);
+ entry.update(*mStubTracker, 0);
wakeup = entry.wakeupTime();
ASSERT_TRUE(wakeup);
EXPECT_THAT(*wakeup, Eq(920));
@@ -1307,26 +1364,35 @@
TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
VSyncDispatchTimerQueueEntry entry(
"test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
- EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
- *mStubTracker.get(), 0)
- .has_value());
+ auto scheduleResultOpt =
+ entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
+ *mStubTracker, 0);
+ ASSERT_TRUE(scheduleResultOpt);
+ EXPECT_EQ(900, scheduleResultOpt->callbackTime.ns());
+ EXPECT_EQ(1000, scheduleResultOpt->vsyncTime.ns());
entry.executing(); // 1000 is executing
// had 1000 not been executing, this could have been scheduled for time 800.
- EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
- *mStubTracker.get(), 0)
- .has_value());
+ scheduleResultOpt = entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
+ *mStubTracker, 0);
+ ASSERT_TRUE(scheduleResultOpt);
+ EXPECT_EQ(1800, scheduleResultOpt->callbackTime.ns());
+ EXPECT_EQ(2000, scheduleResultOpt->vsyncTime.ns());
EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
EXPECT_THAT(*entry.readyTime(), Eq(2000));
- EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 500},
- *mStubTracker.get(), 0)
- .has_value());
+ scheduleResultOpt = entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 500},
+ *mStubTracker, 0);
+ ASSERT_TRUE(scheduleResultOpt);
+ EXPECT_EQ(1950, scheduleResultOpt->callbackTime.ns());
+ EXPECT_EQ(2000, scheduleResultOpt->vsyncTime.ns());
EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
EXPECT_THAT(*entry.readyTime(), Eq(2000));
- EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 1001},
- *mStubTracker.get(), 0)
- .has_value());
+ scheduleResultOpt = entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 1001},
+ *mStubTracker, 0);
+ ASSERT_TRUE(scheduleResultOpt);
+ EXPECT_EQ(1800, scheduleResultOpt->callbackTime.ns());
+ EXPECT_EQ(2000, scheduleResultOpt->vsyncTime.ns());
EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
EXPECT_THAT(*entry.readyTime(), Eq(2000));
}
@@ -1349,31 +1415,36 @@
.InSequence(seq)
.WillOnce(Return(2000));
- EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
- *mStubTracker.get(), 0)
- .has_value());
+ auto scheduleResultOpt =
+ entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
+ *mStubTracker, 0);
+ ASSERT_TRUE(scheduleResultOpt);
+ EXPECT_EQ(900, scheduleResultOpt->callbackTime.ns());
+ EXPECT_EQ(1000, scheduleResultOpt->vsyncTime.ns());
entry.executing(); // 1000 is executing
- EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
- *mStubTracker.get(), 0)
- .has_value());
+ scheduleResultOpt = entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
+ *mStubTracker, 0);
+ ASSERT_TRUE(scheduleResultOpt);
+ EXPECT_EQ(1800, scheduleResultOpt->callbackTime.ns());
+ EXPECT_EQ(2000, scheduleResultOpt->vsyncTime.ns());
}
TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
VSyncDispatchTimerQueueEntry entry(
"test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
- *mStubTracker.get(), 0)
+ *mStubTracker, 0)
.has_value());
EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
- *mStubTracker.get(), 0)
+ *mStubTracker, 0)
.has_value());
EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 500},
- *mStubTracker.get(), 0)
+ *mStubTracker, 0)
.has_value());
EXPECT_TRUE(entry.schedule({.workDuration = 1200, .readyDuration = 0, .lastVsync = 500},
- *mStubTracker.get(), 0)
+ *mStubTracker, 0)
.has_value());
}
@@ -1389,7 +1460,7 @@
.readyDuration = 0,
.lastVsync = 400});
EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
- entry.update(*mStubTracker.get(), 0);
+ entry.update(*mStubTracker, 0);
EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
}
@@ -1409,9 +1480,12 @@
},
mVsyncMoveThreshold);
- EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .lastVsync = 500},
- *mStubTracker.get(), 0)
- .has_value());
+ const auto scheduleResultOpt =
+ entry.schedule({.workDuration = 70, .readyDuration = 30, .lastVsync = 500},
+ *mStubTracker, 0);
+ ASSERT_TRUE(scheduleResultOpt);
+ EXPECT_EQ(900, scheduleResultOpt->callbackTime.ns());
+ EXPECT_EQ(mPeriod, scheduleResultOpt->vsyncTime.ns());
auto const wakeup = entry.wakeupTime();
ASSERT_TRUE(wakeup);
EXPECT_THAT(*wakeup, Eq(900));
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVSyncDispatch.h b/services/surfaceflinger/tests/unittests/mock/MockVSyncDispatch.h
index dc32ff9..1dc2ef4 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVSyncDispatch.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockVSyncDispatch.h
@@ -29,8 +29,10 @@
MOCK_METHOD(CallbackToken, registerCallback, (Callback, std::string), (override));
MOCK_METHOD(void, unregisterCallback, (CallbackToken), (override));
- MOCK_METHOD(scheduler::ScheduleResult, schedule, (CallbackToken, ScheduleTiming), (override));
- MOCK_METHOD(scheduler::ScheduleResult, update, (CallbackToken, ScheduleTiming), (override));
+ MOCK_METHOD(std::optional<scheduler::ScheduleResult>, schedule, (CallbackToken, ScheduleTiming),
+ (override));
+ MOCK_METHOD(std::optional<scheduler::ScheduleResult>, update, (CallbackToken, ScheduleTiming),
+ (override));
MOCK_METHOD(scheduler::CancelResult, cancel, (CallbackToken token), (override));
MOCK_METHOD(void, dump, (std::string&), (const, override));
};