diff options
Diffstat (limited to 'services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp')
-rw-r--r-- | services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp | 88 |
1 files changed, 52 insertions, 36 deletions
diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp index 8a3f561487..c6a41159c1 100644 --- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp +++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp @@ -73,7 +73,7 @@ public: mTokenManager = &mFrameTimeline->mTokenManager; mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter; maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames; - maxTokenRetentionTime = mTokenManager->kMaxRetentionTime; + maxTokens = mTokenManager->kMaxTokens; } // Each tracing session can be used for a single block of Start -> Stop. @@ -111,9 +111,11 @@ public: mFrameTimeline->setSfPresent(2500, presentFence1); } - void flushTokens(nsecs_t flushTime) { - std::lock_guard<std::mutex> lock(mTokenManager->mMutex); - mTokenManager->flushTokens(flushTime); + void flushTokens() { + for (size_t i = 0; i < maxTokens; i++) { + mTokenManager->generateTokenForPredictions({}); + } + EXPECT_EQ(getPredictions().size(), maxTokens); } SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) { @@ -132,7 +134,7 @@ public: a.presentTime == b.presentTime; } - const std::map<int64_t, TokenManagerPrediction>& getPredictions() const { + const std::map<int64_t, TimelineItem>& getPredictions() const { return mTokenManager->mPredictions; } @@ -155,7 +157,7 @@ public: TraceCookieCounter* mTraceCookieCounter; FenceToFenceTimeMap fenceFactory; uint32_t* maxDisplayFrames; - nsecs_t maxTokenRetentionTime; + size_t maxTokens; static constexpr pid_t kSurfaceFlingerPid = 666; static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count(); static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(2ns).count(); @@ -177,12 +179,11 @@ static constexpr int32_t sLayerIdTwo = 2; TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) { int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0}); EXPECT_EQ(getPredictions().size(), 1u); - flushTokens(systemTime() + maxTokenRetentionTime); + flushTokens(); int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30}); std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1); // token1 should have expired - EXPECT_EQ(getPredictions().size(), 1u); EXPECT_EQ(predictions.has_value(), false); predictions = mTokenManager->getPredictionsForToken(token2); @@ -212,7 +213,7 @@ TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) { TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) { int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0}); - flushTokens(systemTime() + maxTokenRetentionTime); + flushTokens(); auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne, sLayerIdOne, sLayerNameOne, sLayerNameOne, @@ -707,7 +708,7 @@ TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPres sLayerNameOne, /*isBuffer*/ true); surfaceFrame1->setAcquireFenceTime(45); // Trigger a prediction expiry - flushTokens(systemTime() + maxTokenRetentionTime); + flushTokens(); mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate); surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented); @@ -1065,7 +1066,7 @@ TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpecte tracingSession->StartBlocking(); int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30}); // Flush the token so that it would expire - flushTokens(systemTime() + maxTokenRetentionTime); + flushTokens(); // Set up the display frame mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11)); @@ -1283,7 +1284,7 @@ TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpecte mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime}); // Flush the token so that it would expire - flushTokens(systemTime() + maxTokenRetentionTime); + flushTokens(); auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0}, sPidOne, sUidOne, sLayerIdOne, sLayerNameOne, @@ -1359,7 +1360,7 @@ TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTraced mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime}); // Flush the token so that it would expire - flushTokens(systemTime() + maxTokenRetentionTime); + flushTokens(); auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0}, sPidOne, sUidOne, sLayerIdOne, sLayerNameOne, @@ -1561,13 +1562,22 @@ TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) /* * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed + * Case 3 - previous frame ran longer -> sf_stuffing + * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed */ auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); + auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); + auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); + auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); + auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40}); int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60}); + int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90}); + int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120}); + // case 1 - cpu time = 33 - 12 = 21, vsync period = 11 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11)); mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1); @@ -1578,12 +1588,12 @@ TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) // Fences haven't been flushed yet, so it should be 0 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0); - // case 2 - cpu time = 56 - 52 = 4, vsync period = 11 - mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11)); + // case 2 - cpu time = 56 - 52 = 4, vsync period = 30 + mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30)); mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2); auto displayFrame1 = getDisplayFrame(1); - gpuFence2->signalForTest(66); - presentFence2->signalForTest(71); + gpuFence2->signalForTest(76); + presentFence2->signalForTest(90); EXPECT_EQ(displayFrame1->getActuals().presentTime, 0); // Fences have flushed for first displayFrame, so the present timestamps should be updated @@ -1592,35 +1602,41 @@ TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish); EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed); - addEmptyDisplayFrame(); + // case 3 - cpu time = 86 - 82 = 4, vsync period = 30 + mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30)); + mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3); + auto displayFrame2 = getDisplayFrame(2); + gpuFence3->signalForTest(116); + presentFence3->signalForTest(120); + EXPECT_EQ(displayFrame2->getActuals().presentTime, 0); // Fences have flushed for second displayFrame, so the present timestamps should be updated - EXPECT_EQ(displayFrame1->getActuals().presentTime, 71); + EXPECT_EQ(displayFrame1->getActuals().presentTime, 90); EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent); EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish); EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed); -} -TEST_F(FrameTimelineTest, jankClassification_displayFrameLateStartLateFinishLatePresent) { - auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); - int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40}); - mFrameTimeline->setSfWakeUp(sfToken1, 26, Fps::fromPeriodNsecs(11)); - mFrameTimeline->setSfPresent(36, presentFence1); - auto displayFrame = getDisplayFrame(0); - presentFence1->signalForTest(52); + // case 4 - cpu time = 86 - 82 = 4, vsync period = 30 + mFrameTimeline->setSfWakeUp(sfToken4, 120, Fps::fromPeriodNsecs(30)); + mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4); + auto displayFrame3 = getDisplayFrame(3); + gpuFence4->signalForTest(156); + presentFence4->signalForTest(180); - // Fences haven't been flushed yet, so it should be 0 - EXPECT_EQ(displayFrame->getActuals().presentTime, 0); + EXPECT_EQ(displayFrame3->getActuals().presentTime, 0); + // Fences have flushed for third displayFrame, so the present timestamps should be updated + EXPECT_EQ(displayFrame2->getActuals().presentTime, 120); + EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent); + EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish); + EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing); addEmptyDisplayFrame(); - displayFrame = getDisplayFrame(0); - // Fences have flushed, so the present timestamps should be updated - EXPECT_EQ(displayFrame->getActuals().presentTime, 52); - EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::LateStart); - EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent); - EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish); - EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling); + // Fences have flushed for third displayFrame, so the present timestamps should be updated + EXPECT_EQ(displayFrame3->getActuals().presentTime, 180); + EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent); + EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish); + EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed); } TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) { |