Loading services/surfaceflinger/Scheduler/src/FrameTargeter.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -61,8 +61,10 @@ bool FrameTarget::wouldPresentEarly(Period vsyncPeriod, Period minFramePeriod) c const auto [wouldBackpressure, fence] = expectedSignaledPresentFence(vsyncPeriod, minFramePeriod); return wouldBackpressure && fence.fenceTime->isValid() && fence.fenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; return !wouldBackpressure || (fence.fenceTime->isValid() && fence.fenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING); } const FenceTimePtr& FrameTarget::presentFenceForPreviousFrame() const { Loading services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp +33 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,39 @@ TEST_F(FrameTargeterTest, detectsEarlyPresent) { target().expectedPresentTime() - kPeriod - kHwcMinWorkDuration); } TEST_F(FrameTargeterTest, detectsEarlyPresentAfterLongPeriod) { VsyncId vsyncId{333}; TimePoint frameBeginTime(3000ms); constexpr Fps kRefreshRate = 60_Hz; constexpr Period kPeriod = kRefreshRate.getPeriod(); // The target is not early while past present fences are pending. for (int n = 3; n-- > 0;) { { const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate); } EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod)); EXPECT_FALSE(target().earliestPresentTime()); } // The target is early if the past present fence was signaled. { Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate); const auto fence = frame.end(); fence->signalForTest(frameBeginTime.ns()); } frameBeginTime += 10 * kPeriod; Frame finalFrame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate); // `finalFrame` would present early, so it has an earliest present time. EXPECT_TRUE(wouldPresentEarly(kPeriod, kPeriod)); ASSERT_NE(std::nullopt, target().earliestPresentTime()); EXPECT_EQ(*target().earliestPresentTime(), target().expectedPresentTime() - kPeriod - kHwcMinWorkDuration); } // Same as `detectsEarlyPresent`, above, but verifies that we do not set an earliest present time // when there is expected present time support. TEST_F(FrameTargeterWithExpectedPresentSupportTest, detectsEarlyPresent) { Loading Loading
services/surfaceflinger/Scheduler/src/FrameTargeter.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -61,8 +61,10 @@ bool FrameTarget::wouldPresentEarly(Period vsyncPeriod, Period minFramePeriod) c const auto [wouldBackpressure, fence] = expectedSignaledPresentFence(vsyncPeriod, minFramePeriod); return wouldBackpressure && fence.fenceTime->isValid() && fence.fenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; return !wouldBackpressure || (fence.fenceTime->isValid() && fence.fenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING); } const FenceTimePtr& FrameTarget::presentFenceForPreviousFrame() const { Loading
services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp +33 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,39 @@ TEST_F(FrameTargeterTest, detectsEarlyPresent) { target().expectedPresentTime() - kPeriod - kHwcMinWorkDuration); } TEST_F(FrameTargeterTest, detectsEarlyPresentAfterLongPeriod) { VsyncId vsyncId{333}; TimePoint frameBeginTime(3000ms); constexpr Fps kRefreshRate = 60_Hz; constexpr Period kPeriod = kRefreshRate.getPeriod(); // The target is not early while past present fences are pending. for (int n = 3; n-- > 0;) { { const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate); } EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod)); EXPECT_FALSE(target().earliestPresentTime()); } // The target is early if the past present fence was signaled. { Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate); const auto fence = frame.end(); fence->signalForTest(frameBeginTime.ns()); } frameBeginTime += 10 * kPeriod; Frame finalFrame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate); // `finalFrame` would present early, so it has an earliest present time. EXPECT_TRUE(wouldPresentEarly(kPeriod, kPeriod)); ASSERT_NE(std::nullopt, target().earliestPresentTime()); EXPECT_EQ(*target().earliestPresentTime(), target().expectedPresentTime() - kPeriod - kHwcMinWorkDuration); } // Same as `detectsEarlyPresent`, above, but verifies that we do not set an earliest present time // when there is expected present time support. TEST_F(FrameTargeterWithExpectedPresentSupportTest, detectsEarlyPresent) { Loading