diff options
| -rw-r--r-- | services/surfaceflinger/FrameTimeline/FrameTimeline.cpp | 6 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp | 36 |
2 files changed, 31 insertions, 11 deletions
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp index 27a099cd1f..925f111dc6 100644 --- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp +++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp @@ -1095,6 +1095,12 @@ void FrameTimeline::DisplayFrame::traceActuals(pid_t surfaceFlingerPid, } void FrameTimeline::DisplayFrame::trace(pid_t surfaceFlingerPid, nsecs_t monoBootOffset) const { + if (mSurfaceFrames.empty()) { + // We don't want to trace display frames without any surface frames updates as this cannot + // be janky + return; + } + if (mToken == FrameTimelineInfo::INVALID_VSYNC_ID) { // DisplayFrame should not have an invalid token. ALOGE("Cannot trace DisplayFrame with invalid token"); diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp index f47ac6dc43..abd77894af 100644 --- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp +++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp @@ -44,6 +44,17 @@ using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType; namespace android::frametimeline { +static const std::string sLayerNameOne = "layer1"; +static const std::string sLayerNameTwo = "layer2"; + +constexpr const uid_t sUidOne = 0; +constexpr pid_t sPidOne = 10; +constexpr pid_t sPidTwo = 20; +constexpr int32_t sInputEventId = 5; +constexpr int32_t sLayerIdOne = 1; +constexpr int32_t sLayerIdTwo = 2; +constexpr GameMode sGameMode = GameMode::Unsupported; + class FrameTimelineTest : public testing::Test { public: FrameTimelineTest() { @@ -106,6 +117,14 @@ public: return packets; } + void addEmptySurfaceFrame() { + auto surfaceFrame = + mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne, + sLayerNameOne, sLayerNameOne, + /*isBuffer*/ false, sGameMode); + mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame)); + } + void addEmptyDisplayFrame() { auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); // Trigger a flushPresentFence by calling setSfPresent for the next frame @@ -168,17 +187,6 @@ public: kStartThreshold}; }; -static const std::string sLayerNameOne = "layer1"; -static const std::string sLayerNameTwo = "layer2"; - -constexpr const uid_t sUidOne = 0; -constexpr pid_t sPidOne = 10; -constexpr pid_t sPidTwo = 20; -constexpr int32_t sInputEventId = 5; -constexpr int32_t sLayerIdOne = 1; -constexpr int32_t sLayerIdTwo = 2; -constexpr GameMode sGameMode = GameMode::Unsupported; - TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) { int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0}); EXPECT_EQ(getPredictions().size(), 1u); @@ -1054,6 +1062,9 @@ TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) { auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); tracingSession->StartBlocking(); + + // Add an empty surface frame so that display frame would get traced. + addEmptySurfaceFrame(); int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30}); // Set up the display frame @@ -1135,6 +1146,9 @@ TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpecte // Flush the token so that it would expire flushTokens(); + // Add an empty surface frame so that display frame would get traced. + addEmptySurfaceFrame(); + // Set up the display frame mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11)); mFrameTimeline->setSfPresent(26, presentFence1); |