diff options
11 files changed, 124 insertions, 45 deletions
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp index 16799bd32d..e79eac037c 100644 --- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp +++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp @@ -486,13 +486,13 @@ Duration VSyncPredictor::ensureMinFrameDurationIsKept(TimePoint expectedPresentT return 0ns; } -void VSyncPredictor::onFrameBegin(TimePoint expectedPresentTime, - TimePoint lastConfirmedPresentTime) { +void VSyncPredictor::onFrameBegin(TimePoint expectedPresentTime, FrameTime lastSignaledFrameTime) { SFTRACE_NAME("VSyncPredictor::onFrameBegin"); std::lock_guard lock(mMutex); if (!mDisplayModePtr->getVrrConfig()) return; + const auto [lastConfirmedPresentTime, lastConfirmedExpectedPresentTime] = lastSignaledFrameTime; if (CC_UNLIKELY(mTraceOn)) { SFTRACE_FORMAT_INSTANT("vsync is %.2f past last signaled fence", static_cast<float>(expectedPresentTime.ns() - @@ -518,6 +518,11 @@ void VSyncPredictor::onFrameBegin(TimePoint expectedPresentTime, } } + if (lastConfirmedExpectedPresentTime.ns() - lastConfirmedPresentTime.ns() > threshold) { + SFTRACE_FORMAT_INSTANT("lastFramePresentedEarly"); + return; + } + const auto phase = ensureMinFrameDurationIsKept(expectedPresentTime, lastConfirmedPresentTime); if (phase > 0ns) { mMissedVsync = {expectedPresentTime, minFramePeriodLocked()}; diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.h b/services/surfaceflinger/Scheduler/VSyncPredictor.h index 66a7d71435..db5f455966 100644 --- a/services/surfaceflinger/Scheduler/VSyncPredictor.h +++ b/services/surfaceflinger/Scheduler/VSyncPredictor.h @@ -22,6 +22,7 @@ #include <vector> #include <android-base/thread_annotations.h> +#include <scheduler/FrameTime.h> #include <scheduler/TimeKeeper.h> #include <ui/DisplayId.h> @@ -77,7 +78,7 @@ public: void setRenderRate(Fps, bool applyImmediately) final EXCLUDES(mMutex); - void onFrameBegin(TimePoint expectedPresentTime, TimePoint lastConfirmedPresentTime) final + void onFrameBegin(TimePoint expectedPresentTime, FrameTime lastSignaledFrameTime) final EXCLUDES(mMutex); void onFrameMissed(TimePoint expectedPresentTime) final EXCLUDES(mMutex); diff --git a/services/surfaceflinger/Scheduler/VSyncTracker.h b/services/surfaceflinger/Scheduler/VSyncTracker.h index 134d28e1e5..3376fadad0 100644 --- a/services/surfaceflinger/Scheduler/VSyncTracker.h +++ b/services/surfaceflinger/Scheduler/VSyncTracker.h @@ -21,6 +21,7 @@ #include <scheduler/Fps.h> #include <scheduler/FrameRateMode.h> +#include <scheduler/FrameTime.h> #include "VSyncDispatch.h" @@ -112,8 +113,7 @@ public: */ virtual void setRenderRate(Fps, bool applyImmediately) = 0; - virtual void onFrameBegin(TimePoint expectedPresentTime, - TimePoint lastConfirmedPresentTime) = 0; + virtual void onFrameBegin(TimePoint expectedPresentTime, FrameTime lastSignaledFrameTime) = 0; virtual void onFrameMissed(TimePoint expectedPresentTime) = 0; diff --git a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h index d37d2dc51b..38cb446a81 100644 --- a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h +++ b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h @@ -26,6 +26,7 @@ #include <ui/FenceTime.h> #include <scheduler/Features.h> +#include <scheduler/FrameTime.h> #include <scheduler/Time.h> #include <scheduler/VsyncId.h> #include <scheduler/interface/CompositeResult.h> @@ -57,13 +58,6 @@ public: // The time of the VSYNC that preceded this frame. See `presentFenceForPastVsync` for details. TimePoint pastVsyncTime(Period minFramePeriod) const; - // The present fence for the frame that had targeted the most recent VSYNC before this frame. - // If the target VSYNC for any given frame is more than `vsyncPeriod` in the future, then the - // VSYNC of at least one previous frame has not yet passed. In other words, this is NOT the - // `presentFenceForPreviousFrame` if running N VSYNCs ahead, but the one that should have been - // signaled by now (unless that frame missed). - FenceTimePtr presentFenceForPastVsync(Period minFramePeriod) const; - // Equivalent to `presentFenceForPastVsync` unless running N VSYNCs ahead. const FenceTimePtr& presentFenceForPreviousFrame() const { return mPresentFences.front().fenceTime; @@ -72,7 +66,7 @@ public: bool isFramePending() const { return mFramePending; } bool didMissFrame() const { return mFrameMissed; } bool didMissHwcFrame() const { return mHwcFrameMissed && !mGpuFrameMissed; } - TimePoint lastSignaledFrameTime() const { return mLastSignaledFrameTime; }; + FrameTime lastSignaledFrameTime() const { return mLastSignaledFrameTime; } protected: explicit FrameTarget(const std::string& displayLabel); @@ -106,10 +100,17 @@ protected: FenceTimePtr fenceTime = FenceTime::NO_FENCE; TimePoint expectedPresentTime = TimePoint(); }; + + // The present fence for the frame that had targeted the most recent VSYNC before this frame. + // If the target VSYNC for any given frame is more than `vsyncPeriod` in the future, then the + // VSYNC of at least one previous frame has not yet passed. In other words, this is NOT the + // `presentFenceForPreviousFrame` if running N VSYNCs ahead, but the one that should have been + // signaled by now (unless that frame missed). + FenceWithFenceTime presentFenceForPastVsync(Period minFramePeriod) const; std::array<FenceWithFenceTime, 2> mPresentFences; utils::RingBuffer<FenceWithFenceTime, 5> mFenceWithFenceTimes; - TimePoint mLastSignaledFrameTime; + FrameTime mLastSignaledFrameTime; private: friend class FrameTargeterTestBase; @@ -120,16 +121,17 @@ private: return expectedFrameDuration() > (N - 1) * minFramePeriod; } - const FenceTimePtr pastVsyncTimePtr() const { - auto pastFenceTimePtr = FenceTime::NO_FENCE; + FenceWithFenceTime pastVsyncTimePtr() const { + FenceWithFenceTime pastFenceWithFenceTime; for (size_t i = 0; i < mFenceWithFenceTimes.size(); i++) { - const auto& [_, fenceTimePtr, expectedPresentTime] = mFenceWithFenceTimes[i]; - if (expectedPresentTime > mFrameBeginTime) { - return pastFenceTimePtr; + const auto& fenceWithFenceTime = mFenceWithFenceTimes[i]; + // TODO(b/354007767) Fix the below condition to avoid frame drop + if (fenceWithFenceTime.expectedPresentTime > mFrameBeginTime) { + return pastFenceWithFenceTime; } - pastFenceTimePtr = fenceTimePtr; + pastFenceWithFenceTime = fenceWithFenceTime; } - return pastFenceTimePtr; + return pastFenceWithFenceTime; } }; diff --git a/services/surfaceflinger/Scheduler/include/scheduler/FrameTime.h b/services/surfaceflinger/Scheduler/include/scheduler/FrameTime.h new file mode 100644 index 0000000000..ed5c8991f3 --- /dev/null +++ b/services/surfaceflinger/Scheduler/include/scheduler/FrameTime.h @@ -0,0 +1,26 @@ +/* + * Copyright 2024 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. + */ + +#pragma once + +#include <scheduler/Time.h> + +namespace android::scheduler { +struct FrameTime { + TimePoint signalTime; + TimePoint expectedPresentTime; +}; +} // namespace android::scheduler
\ No newline at end of file diff --git a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp index 60694b96a4..1d248fbbe2 100644 --- a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp +++ b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp @@ -33,12 +33,12 @@ TimePoint FrameTarget::pastVsyncTime(Period minFramePeriod) const { return mExpectedPresentTime - Period::fromNs(minFramePeriod.ns() << shift); } -FenceTimePtr FrameTarget::presentFenceForPastVsync(Period minFramePeriod) const { +FrameTarget::FenceWithFenceTime FrameTarget::presentFenceForPastVsync(Period minFramePeriod) const { if (FlagManager::getInstance().allow_n_vsyncs_in_targeter()) { return pastVsyncTimePtr(); } const size_t i = static_cast<size_t>(targetsVsyncsAhead<2>(minFramePeriod)); - return mPresentFences[i].fenceTime; + return mPresentFences[i]; } bool FrameTarget::wouldPresentEarly(Period minFramePeriod) const { @@ -51,7 +51,7 @@ bool FrameTarget::wouldPresentEarly(Period minFramePeriod) const { return true; } - const auto fence = presentFenceForPastVsync(minFramePeriod); + const auto fence = presentFenceForPastVsync(minFramePeriod).fenceTime; return fence->isValid() && fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING; } @@ -93,7 +93,7 @@ void FrameTargeter::beginFrame(const BeginFrameArgs& args, const IVsyncSource& v ticks<std::milli, float>(mExpectedPresentTime - TimePoint::now()), mExpectedPresentTime == args.expectedVsyncTime ? "" : " (adjusted)"); - const FenceTimePtr& pastPresentFence = presentFenceForPastVsync(minFramePeriod); + FenceWithFenceTime pastPresentFence = presentFenceForPastVsync(minFramePeriod); // In cases where the present fence is about to fire, give it a small grace period instead of // giving up on the frame. @@ -105,8 +105,8 @@ void FrameTargeter::beginFrame(const BeginFrameArgs& args, const IVsyncSource& v // Pending frames may trigger backpressure propagation. const auto& isFencePending = *isFencePendingFuncPtr; - mFramePending = pastPresentFence != FenceTime::NO_FENCE && - isFencePending(pastPresentFence, graceTimeForPresentFenceMs); + mFramePending = pastPresentFence.fenceTime != FenceTime::NO_FENCE && + isFencePending(pastPresentFence.fenceTime, graceTimeForPresentFenceMs); // A frame is missed if the prior frame is still pending. If no longer pending, then we still // count the frame as missed if the predicted present time was further in the past than when the @@ -114,9 +114,10 @@ void FrameTargeter::beginFrame(const BeginFrameArgs& args, const IVsyncSource& v // than a typical frame duration, but should not be so small that it reports reasonable drift as // a missed frame. mFrameMissed = mFramePending || [&] { - const nsecs_t pastPresentTime = pastPresentFence->getSignalTime(); + const nsecs_t pastPresentTime = pastPresentFence.fenceTime->getSignalTime(); if (pastPresentTime < 0) return false; - mLastSignaledFrameTime = TimePoint::fromNs(pastPresentTime); + mLastSignaledFrameTime = {.signalTime = TimePoint::fromNs(pastPresentTime), + .expectedPresentTime = pastPresentFence.expectedPresentTime}; const nsecs_t frameMissedSlop = vsyncPeriod.ns() / 2; return lastScheduledPresentTime.ns() < pastPresentTime - frameMissedSlop; }(); diff --git a/services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp b/services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp index 5448eecc60..190d0621d0 100644 --- a/services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp +++ b/services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp @@ -57,6 +57,10 @@ public: return target().wouldPresentEarly(minFramePeriod); } + FrameTarget::FenceWithFenceTime presentFenceForPastVsync(Period minFramePeriod) const { + return target().presentFenceForPastVsync(minFramePeriod); + } + struct Frame { Frame(FrameTargeterTestBase* testPtr, VsyncId vsyncId, TimePoint& frameBeginTime, Duration frameDuration, Fps refreshRate, Fps peakRefreshRate, @@ -181,7 +185,7 @@ TEST_F(FrameTargeterTest, recallsPastVsync) { const auto fence = frame.end(); EXPECT_EQ(target().pastVsyncTime(kPeriod), frameBeginTime + kFrameDuration - kPeriod); - EXPECT_EQ(target().presentFenceForPastVsync(kPeriod), fence); + EXPECT_EQ(presentFenceForPastVsync(kPeriod).fenceTime, fence); } } @@ -200,7 +204,7 @@ TEST_F(FrameTargeterTest, recallsPastVsyncTwoVsyncsAhead) { const auto fence = frame.end(); EXPECT_EQ(target().pastVsyncTime(kPeriod), frameBeginTime + kFrameDuration - 2 * kPeriod); - EXPECT_EQ(target().presentFenceForPastVsync(kPeriod), previousFence); + EXPECT_EQ(presentFenceForPastVsync(kPeriod).fenceTime, previousFence); previousFence = fence; } @@ -222,7 +226,7 @@ TEST_F(FrameTargeterTest, recallsPastNVsyncTwoVsyncsAhead) { const auto pastVsyncTime = frameBeginTime + kFrameDuration - 2 * kPeriod; EXPECT_EQ(target().pastVsyncTime(kPeriod), pastVsyncTime); - EXPECT_EQ(target().presentFenceForPastVsync(kFrameDuration), previousFence); + EXPECT_EQ(presentFenceForPastVsync(kFrameDuration).fenceTime, previousFence); frameBeginTime += kPeriod; previousFence = fence; @@ -248,7 +252,7 @@ TEST_F(FrameTargeterTest, recallsPastVsyncTwoVsyncsAheadVrr) { const auto fence = frame.end(); EXPECT_EQ(target().pastVsyncTime(kPeriod), frameBeginTime + kFrameDuration - 2 * kPeriod); - EXPECT_EQ(target().presentFenceForPastVsync(kPeriod), previousFence); + EXPECT_EQ(presentFenceForPastVsync(kPeriod).fenceTime, previousFence); previousFence = fence; } @@ -274,7 +278,7 @@ TEST_F(FrameTargeterTest, recallsPastNVsyncTwoVsyncsAheadVrr) { const auto pastVsyncTime = frameBeginTime + kFrameDuration - 2 * kPeriod; EXPECT_EQ(target().pastVsyncTime(kPeriod), pastVsyncTime); - EXPECT_EQ(target().presentFenceForPastVsync(kFrameDuration), previousFence); + EXPECT_EQ(presentFenceForPastVsync(kFrameDuration).fenceTime, previousFence); frameBeginTime += kPeriod; previousFence = fence; @@ -283,7 +287,7 @@ TEST_F(FrameTargeterTest, recallsPastNVsyncTwoVsyncsAheadVrr) { TEST_F(FrameTargeterTest, doesNotDetectEarlyPresentIfNoFence) { constexpr Period kPeriod = (60_Hz).getPeriod(); - EXPECT_EQ(target().presentFenceForPastVsync(kPeriod), FenceTime::NO_FENCE); + EXPECT_EQ(presentFenceForPastVsync(kPeriod).fenceTime, FenceTime::NO_FENCE); EXPECT_FALSE(wouldPresentEarly(kPeriod)); } diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp index fc54a8b74f..3df724a09e 100644 --- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp +++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp @@ -34,6 +34,7 @@ #include "mock/MockSchedulerCallback.h" #include <FrontEnd/LayerHierarchy.h> +#include <scheduler/FrameTime.h> #include <com_android_graphics_surfaceflinger_flags.h> #include "FpsOps.h" @@ -607,7 +608,8 @@ TEST_F(SchedulerTest, nextFrameIntervalTest) { TimePoint::fromNs(2000))); // Not crossing the min frame period - vrrTracker->onFrameBegin(TimePoint::fromNs(2000), TimePoint::fromNs(1500)); + vrrTracker->onFrameBegin(TimePoint::fromNs(2000), + {TimePoint::fromNs(1500), TimePoint::fromNs(1500)}); EXPECT_EQ(Fps::fromPeriodNsecs(1000), scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(), TimePoint::fromNs(2500))); diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp index 3b095545e9..b63f29990e 100644 --- a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp @@ -19,6 +19,7 @@ #include <gmock/gmock.h> #include <gtest/gtest.h> +#include <scheduler/FrameTime.h> #include <scheduler/Timer.h> #include "Scheduler/VSyncDispatchTimerQueue.h" @@ -51,7 +52,7 @@ public: bool isVSyncInPhase(nsecs_t, Fps) final { return false; } void setDisplayModePtr(ftl::NonNull<DisplayModePtr>) final {} void setRenderRate(Fps, bool) final {} - void onFrameBegin(TimePoint, TimePoint) final {} + void onFrameBegin(TimePoint, scheduler::FrameTime) final {} void onFrameMissed(TimePoint) final {} void dump(std::string&) const final {} bool isCurrentMode(const ftl::NonNull<DisplayModePtr>&) const final { return false; }; diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp index f36a8a6fd7..8690dba041 100644 --- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp @@ -901,17 +901,20 @@ TEST_F(VSyncPredictorTest, adjustsVrrTimeline) { EXPECT_EQ(1000, vrrTracker.nextAnticipatedVSyncTimeFrom(700)); EXPECT_EQ(2000, vrrTracker.nextAnticipatedVSyncTimeFrom(1000)); - vrrTracker.onFrameBegin(TimePoint::fromNs(2000), TimePoint::fromNs(1500)); + vrrTracker.onFrameBegin(TimePoint::fromNs(2000), + {TimePoint::fromNs(1500), TimePoint::fromNs(1500)}); EXPECT_EQ(3500, vrrTracker.nextAnticipatedVSyncTimeFrom(2000, 2000)); EXPECT_EQ(4500, vrrTracker.nextAnticipatedVSyncTimeFrom(3500, 3500)); // Miss when starting 4500 and expect the next vsync will be at 5000 (next one) - vrrTracker.onFrameBegin(TimePoint::fromNs(3500), TimePoint::fromNs(2500)); + vrrTracker.onFrameBegin(TimePoint::fromNs(3500), + {TimePoint::fromNs(2500), TimePoint::fromNs(2500)}); vrrTracker.onFrameMissed(TimePoint::fromNs(4500)); EXPECT_EQ(5000, vrrTracker.nextAnticipatedVSyncTimeFrom(4500, 4500)); EXPECT_EQ(6000, vrrTracker.nextAnticipatedVSyncTimeFrom(5000, 5000)); - vrrTracker.onFrameBegin(TimePoint::fromNs(7000), TimePoint::fromNs(6500)); + vrrTracker.onFrameBegin(TimePoint::fromNs(7000), + {TimePoint::fromNs(6500), TimePoint::fromNs(6500)}); EXPECT_EQ(10500, vrrTracker.nextAnticipatedVSyncTimeFrom(9000, 7000)); } @@ -943,7 +946,7 @@ TEST_F(VSyncPredictorTest, adjustsVrrTimelineTwoClients) { // SF starts to catch up EXPECT_EQ(3000, vrrTracker.nextAnticipatedVSyncTimeFrom(2700)); - vrrTracker.onFrameBegin(TimePoint::fromNs(3000), TimePoint::fromNs(0)); + vrrTracker.onFrameBegin(TimePoint::fromNs(3000), {TimePoint::fromNs(0), TimePoint::fromNs(0)}); // SF misses last frame (3000) and observes that when committing (4000) EXPECT_EQ(6000, vrrTracker.nextAnticipatedVSyncTimeFrom(5000, 5000)); @@ -952,17 +955,20 @@ TEST_F(VSyncPredictorTest, adjustsVrrTimelineTwoClients) { // SF wakes up again instead of the (4000) missed frame EXPECT_EQ(4500, vrrTracker.nextAnticipatedVSyncTimeFrom(4000, 4000)); - vrrTracker.onFrameBegin(TimePoint::fromNs(4500), TimePoint::fromNs(4500)); + vrrTracker.onFrameBegin(TimePoint::fromNs(4500), + {TimePoint::fromNs(4500), TimePoint::fromNs(4500)}); // Timeline shifted. The app needs to get the next frame at (7500) as its last frame (6500) will // be presented at (7500) EXPECT_EQ(7500, vrrTracker.nextAnticipatedVSyncTimeFrom(6000, 6000)); EXPECT_EQ(5500, vrrTracker.nextAnticipatedVSyncTimeFrom(4500, 4500)); - vrrTracker.onFrameBegin(TimePoint::fromNs(5500), TimePoint::fromNs(4500)); + vrrTracker.onFrameBegin(TimePoint::fromNs(5500), + {TimePoint::fromNs(4500), TimePoint::fromNs(4500)}); EXPECT_EQ(8500, vrrTracker.nextAnticipatedVSyncTimeFrom(7500, 7500)); EXPECT_EQ(6500, vrrTracker.nextAnticipatedVSyncTimeFrom(5500, 5500)); - vrrTracker.onFrameBegin(TimePoint::fromNs(6500), TimePoint::fromNs(5500)); + vrrTracker.onFrameBegin(TimePoint::fromNs(6500), + {TimePoint::fromNs(5500), TimePoint::fromNs(5500)}); } TEST_F(VSyncPredictorTest, renderRateIsPreservedForCommittedVsyncs) { @@ -1020,6 +1026,35 @@ TEST_F(VSyncPredictorTest, renderRateChangeAfterAppliedImmediately) { EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(9001), Eq(13000)); } +TEST_F(VSyncPredictorTest, timelineNotAdjustedForEarlyPresent) { + SET_FLAG_FOR_TEST(flags::vrr_config, true); + + const int32_t kGroup = 0; + const auto kResolution = ui::Size(1920, 1080); + const auto refreshRate = Fps::fromPeriodNsecs(500); + const auto minFrameRate = Fps::fromPeriodNsecs(1000); + hal::VrrConfig vrrConfig; + vrrConfig.minFrameIntervalNs = minFrameRate.getPeriodNsecs(); + const ftl::NonNull<DisplayModePtr> kMode = + ftl::as_non_null(createDisplayModeBuilder(DisplayModeId(0), refreshRate, kGroup, + kResolution, DEFAULT_DISPLAY_ID) + .setVrrConfig(std::move(vrrConfig)) + .build()); + + VSyncPredictor vrrTracker{std::make_unique<ClockWrapper>(mClock), kMode, kHistorySize, + kMinimumSamplesForPrediction, kOutlierTolerancePercent}; + + vrrTracker.setRenderRate(minFrameRate, /*applyImmediately*/ false); + vrrTracker.addVsyncTimestamp(0); + EXPECT_EQ(1000, vrrTracker.nextAnticipatedVSyncTimeFrom(700)); + + constexpr auto kLastConfirmedExpectedPresentTime = TimePoint::fromNs(1000); + constexpr auto kLastActualSignalTime = TimePoint::fromNs(700); // presented early + vrrTracker.onFrameBegin(TimePoint::fromNs(1400), + {kLastActualSignalTime, kLastConfirmedExpectedPresentTime}); + EXPECT_EQ(2000, vrrTracker.nextAnticipatedVSyncTimeFrom(1400, 1000)); + EXPECT_EQ(3000, vrrTracker.nextAnticipatedVSyncTimeFrom(2000, 1000)); +} } // namespace android::scheduler // TODO(b/129481165): remove the #pragma below and fix conversion issues diff --git a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h index 4f44d1b4fc..8d6d1d3cdc 100644 --- a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h +++ b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h @@ -18,6 +18,8 @@ #include <gmock/gmock.h> +#include <scheduler/FrameTime.h> + #include "Scheduler/VSyncTracker.h" namespace android::mock { @@ -37,7 +39,7 @@ public: MOCK_METHOD(bool, isVSyncInPhase, (nsecs_t, Fps), (override)); MOCK_METHOD(void, setDisplayModePtr, (ftl::NonNull<DisplayModePtr>), (override)); MOCK_METHOD(void, setRenderRate, (Fps, bool), (override)); - MOCK_METHOD(void, onFrameBegin, (TimePoint, TimePoint), (override)); + MOCK_METHOD(void, onFrameBegin, (TimePoint, scheduler::FrameTime), (override)); MOCK_METHOD(void, onFrameMissed, (TimePoint), (override)); MOCK_METHOD(void, dump, (std::string&), (const, override)); MOCK_METHOD(bool, isCurrentMode, (const ftl::NonNull<DisplayModePtr>&), (const, override)); |