Loading libs/gui/include/gui/JankInfo.h +2 −2 Original line number Diff line number Diff line Loading @@ -24,9 +24,9 @@ enum JankType { None = 0x0, // Jank that occurs in the layers below SurfaceFlinger DisplayHAL = 0x1, // SF took too long on the CPU // SF took too long on the CPU; deadline missed during HWC SurfaceFlingerCpuDeadlineMissed = 0x2, // SF took too long on the GPU // SF took too long on the GPU; deadline missed during GPU composition SurfaceFlingerGpuDeadlineMissed = 0x4, // Either App or GPU took too long on the frame AppDeadlineMissed = 0x8, Loading services/surfaceflinger/FrameTimeline/FrameTimeline.cpp +4 −7 Original line number Diff line number Diff line Loading @@ -109,11 +109,11 @@ std::string jankTypeBitmaskToString(int32_t jankType) { jankType &= ~JankType::DisplayHAL; } if (jankType & JankType::SurfaceFlingerCpuDeadlineMissed) { janks.emplace_back("SurfaceFlinger CPU Deadline Missed"); janks.emplace_back("SurfaceFlinger deadline missed (while in HWC)"); jankType &= ~JankType::SurfaceFlingerCpuDeadlineMissed; } if (jankType & JankType::SurfaceFlingerGpuDeadlineMissed) { janks.emplace_back("SurfaceFlinger GPU Deadline Missed"); janks.emplace_back("SurfaceFlinger deadline missed (while in GPU comp)"); jankType &= ~JankType::SurfaceFlingerGpuDeadlineMissed; } if (jankType & JankType::AppDeadlineMissed) { Loading Loading @@ -986,11 +986,8 @@ void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& mJankClassificationThresholds.presentThreshold) { // Classify CPU vs GPU if SF wasn't stuffed or if SF was stuffed but this frame // was presented more than a vsync late. if (mGpuFence != FenceTime::NO_FENCE && mSurfaceFlingerActuals.endTime - mSurfaceFlingerActuals.startTime < mRefreshRate.getPeriodNsecs()) { // If SF was in GPU composition and the CPU work finished before the vsync // period, classify it as GPU deadline missed. if (mGpuFence != FenceTime::NO_FENCE) { // If SF was in GPU composition, classify it as GPU deadline missed. mJankType = JankType::SurfaceFlingerGpuDeadlineMissed; } else { mJankType = JankType::SurfaceFlingerCpuDeadlineMissed; Loading services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp +45 −1 Original line number Diff line number Diff line Loading @@ -1680,7 +1680,7 @@ TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) EXPECT_EQ(displayFrame0->getActuals().presentTime, 52); EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent); EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish); EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed); EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed); // case 3 - cpu time = 86 - 82 = 4, vsync period = 30 mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30)); Loading Loading @@ -2184,6 +2184,50 @@ TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffin EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing); } TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) { auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40}); int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60}); // Case 1: cpu time = 33 - 12 = 21, vsync period = 11 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11)); mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1); auto displayFrame = getDisplayFrame(0); gpuFence1->signalForTest(36); presentFence1->signalForTest(52); // Fences haven't been flushed yet, so it should be 0 EXPECT_EQ(displayFrame->getActuals().presentTime, 0); addEmptyDisplayFrame(); displayFrame = getDisplayFrame(0); // Fences have flushed, so the present timestamps should be updated EXPECT_EQ(displayFrame->getActuals().presentTime, 52); EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent); EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish); EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed); // Case 2: No GPU fence so it will not use GPU composition. mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30)); mFrameTimeline->setSfPresent(66, presentFence2); auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame presentFence2->signalForTest(90); // Fences for the frame haven't been flushed yet, so it should be 0 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0); addEmptyDisplayFrame(); // Fences have flushed, so the present timestamps should be updated EXPECT_EQ(displayFrame2->getActuals().presentTime, 90); EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent); EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish); EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed); } TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) { EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f); } Loading Loading
libs/gui/include/gui/JankInfo.h +2 −2 Original line number Diff line number Diff line Loading @@ -24,9 +24,9 @@ enum JankType { None = 0x0, // Jank that occurs in the layers below SurfaceFlinger DisplayHAL = 0x1, // SF took too long on the CPU // SF took too long on the CPU; deadline missed during HWC SurfaceFlingerCpuDeadlineMissed = 0x2, // SF took too long on the GPU // SF took too long on the GPU; deadline missed during GPU composition SurfaceFlingerGpuDeadlineMissed = 0x4, // Either App or GPU took too long on the frame AppDeadlineMissed = 0x8, Loading
services/surfaceflinger/FrameTimeline/FrameTimeline.cpp +4 −7 Original line number Diff line number Diff line Loading @@ -109,11 +109,11 @@ std::string jankTypeBitmaskToString(int32_t jankType) { jankType &= ~JankType::DisplayHAL; } if (jankType & JankType::SurfaceFlingerCpuDeadlineMissed) { janks.emplace_back("SurfaceFlinger CPU Deadline Missed"); janks.emplace_back("SurfaceFlinger deadline missed (while in HWC)"); jankType &= ~JankType::SurfaceFlingerCpuDeadlineMissed; } if (jankType & JankType::SurfaceFlingerGpuDeadlineMissed) { janks.emplace_back("SurfaceFlinger GPU Deadline Missed"); janks.emplace_back("SurfaceFlinger deadline missed (while in GPU comp)"); jankType &= ~JankType::SurfaceFlingerGpuDeadlineMissed; } if (jankType & JankType::AppDeadlineMissed) { Loading Loading @@ -986,11 +986,8 @@ void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& mJankClassificationThresholds.presentThreshold) { // Classify CPU vs GPU if SF wasn't stuffed or if SF was stuffed but this frame // was presented more than a vsync late. if (mGpuFence != FenceTime::NO_FENCE && mSurfaceFlingerActuals.endTime - mSurfaceFlingerActuals.startTime < mRefreshRate.getPeriodNsecs()) { // If SF was in GPU composition and the CPU work finished before the vsync // period, classify it as GPU deadline missed. if (mGpuFence != FenceTime::NO_FENCE) { // If SF was in GPU composition, classify it as GPU deadline missed. mJankType = JankType::SurfaceFlingerGpuDeadlineMissed; } else { mJankType = JankType::SurfaceFlingerCpuDeadlineMissed; Loading
services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp +45 −1 Original line number Diff line number Diff line Loading @@ -1680,7 +1680,7 @@ TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) EXPECT_EQ(displayFrame0->getActuals().presentTime, 52); EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent); EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish); EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed); EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed); // case 3 - cpu time = 86 - 82 = 4, vsync period = 30 mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30)); Loading Loading @@ -2184,6 +2184,50 @@ TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffin EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing); } TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) { auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40}); int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60}); // Case 1: cpu time = 33 - 12 = 21, vsync period = 11 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11)); mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1); auto displayFrame = getDisplayFrame(0); gpuFence1->signalForTest(36); presentFence1->signalForTest(52); // Fences haven't been flushed yet, so it should be 0 EXPECT_EQ(displayFrame->getActuals().presentTime, 0); addEmptyDisplayFrame(); displayFrame = getDisplayFrame(0); // Fences have flushed, so the present timestamps should be updated EXPECT_EQ(displayFrame->getActuals().presentTime, 52); EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent); EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish); EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed); // Case 2: No GPU fence so it will not use GPU composition. mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30)); mFrameTimeline->setSfPresent(66, presentFence2); auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame presentFence2->signalForTest(90); // Fences for the frame haven't been flushed yet, so it should be 0 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0); addEmptyDisplayFrame(); // Fences have flushed, so the present timestamps should be updated EXPECT_EQ(displayFrame2->getActuals().presentTime, 90); EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent); EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish); EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed); } TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) { EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f); } Loading