From 3a9b4c8b112c3fbd59bca17228ecc772e0879cb3 Mon Sep 17 00:00:00 2001 From: Dake Gu Date: Thu, 2 Jun 2022 17:42:55 -0700 Subject: [PATCH] Detect doubleStuffed frame when duration is over 2*interval Current doubleStuffed deadline calculation is based on the assumption that frame duration cannot go beyond 2*interval. But we see on TV with many >2*interval cases and device is still rendering without frame drop. See details in go/jank-tracker-deadline-fix-on-s Test: build adt3_gtv-userdebug on T, verified gfxinfo is no longer reporting a high number of "deadline missed" Test: new test in JankTrackerTests Bug: 189942694 Change-Id: Id9be2d0d232b89c6e145ecec513054ca8c752814 --- libs/hwui/JankTracker.cpp | 5 +- libs/hwui/tests/unit/JankTrackerTests.cpp | 65 +++++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp index 1e5be6c3eed7a..4b0ddd2fa2eff 100644 --- a/libs/hwui/JankTracker.cpp +++ b/libs/hwui/JankTracker.cpp @@ -201,8 +201,9 @@ void JankTracker::finishFrame(FrameInfo& frame, std::unique_ptrtotalFrameCount()); ASSERT_EQ(2, container.get()->jankFrameCount()); } + +TEST(JankTracker, doubleStuffedTwoIntervalBehind) { + std::mutex mutex; + ProfileDataContainer container(mutex); + JankTracker jankTracker(&container); + std::unique_ptr reporter = std::make_unique(); + + uint64_t frameNumber = 0; + uint32_t surfaceId = 0; + + // First frame janks + FrameInfo* info = jankTracker.startFrame(); + info->set(FrameInfoIndex::IntendedVsync) = 100_ms; + info->set(FrameInfoIndex::Vsync) = 101_ms; + info->set(FrameInfoIndex::SwapBuffersCompleted) = 107_ms; + info->set(FrameInfoIndex::GpuCompleted) = 117_ms; + info->set(FrameInfoIndex::FrameCompleted) = 117_ms; + info->set(FrameInfoIndex::FrameInterval) = 16_ms; + info->set(FrameInfoIndex::FrameDeadline) = 116_ms; + jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId); + + ASSERT_EQ(1, container.get()->jankFrameCount()); + + // Second frame is long, but doesn't jank because double-stuffed. + // Second frame duration is between 1*interval ~ 2*interval + info = jankTracker.startFrame(); + info->set(FrameInfoIndex::IntendedVsync) = 116_ms; + info->set(FrameInfoIndex::Vsync) = 116_ms; + info->set(FrameInfoIndex::SwapBuffersCompleted) = 129_ms; + info->set(FrameInfoIndex::GpuCompleted) = 133_ms; + info->set(FrameInfoIndex::FrameCompleted) = 133_ms; + info->set(FrameInfoIndex::FrameInterval) = 16_ms; + info->set(FrameInfoIndex::FrameDeadline) = 132_ms; + jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId); + + ASSERT_EQ(1, container.get()->jankFrameCount()); + + // Third frame is even longer, cause a jank + // Third frame duration is between 2*interval ~ 3*interval + info = jankTracker.startFrame(); + info->set(FrameInfoIndex::IntendedVsync) = 132_ms; + info->set(FrameInfoIndex::Vsync) = 132_ms; + info->set(FrameInfoIndex::SwapBuffersCompleted) = 160_ms; + info->set(FrameInfoIndex::GpuCompleted) = 165_ms; + info->set(FrameInfoIndex::FrameCompleted) = 165_ms; + info->set(FrameInfoIndex::FrameInterval) = 16_ms; + info->set(FrameInfoIndex::FrameDeadline) = 148_ms; + jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId); + + ASSERT_EQ(2, container.get()->jankFrameCount()); + + // 4th frame is double-stuffed with a 2 * interval latency + // 4th frame duration is between 2*interval ~ 3*interval + info = jankTracker.startFrame(); + info->set(FrameInfoIndex::IntendedVsync) = 148_ms; + info->set(FrameInfoIndex::Vsync) = 148_ms; + info->set(FrameInfoIndex::SwapBuffersCompleted) = 170_ms; + info->set(FrameInfoIndex::GpuCompleted) = 181_ms; + info->set(FrameInfoIndex::FrameCompleted) = 181_ms; + info->set(FrameInfoIndex::FrameInterval) = 16_ms; + info->set(FrameInfoIndex::FrameDeadline) = 164_ms; + jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId); + + ASSERT_EQ(2, container.get()->jankFrameCount()); +}