Loading services/surfaceflinger/FrameTimeline/FrameTimeline.cpp +6 −0 Original line number Original line Diff line number Diff line Loading @@ -1095,6 +1095,12 @@ void FrameTimeline::DisplayFrame::traceActuals(pid_t surfaceFlingerPid, } } void FrameTimeline::DisplayFrame::trace(pid_t surfaceFlingerPid, nsecs_t monoBootOffset) const { 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) { if (mToken == FrameTimelineInfo::INVALID_VSYNC_ID) { // DisplayFrame should not have an invalid token. // DisplayFrame should not have an invalid token. ALOGE("Cannot trace DisplayFrame with invalid token"); ALOGE("Cannot trace DisplayFrame with invalid token"); Loading services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp +25 −11 Original line number Original line Diff line number Diff line Loading @@ -44,6 +44,17 @@ using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType; namespace android::frametimeline { 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 { class FrameTimelineTest : public testing::Test { public: public: FrameTimelineTest() { FrameTimelineTest() { Loading Loading @@ -106,6 +117,14 @@ public: return packets; return packets; } } void addEmptySurfaceFrame() { auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne, sLayerNameOne, sLayerNameOne, /*isBuffer*/ false, sGameMode); mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame)); } void addEmptyDisplayFrame() { void addEmptyDisplayFrame() { auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); // Trigger a flushPresentFence by calling setSfPresent for the next frame // Trigger a flushPresentFence by calling setSfPresent for the next frame Loading Loading @@ -168,17 +187,6 @@ public: kStartThreshold}; 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) { TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) { int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0}); int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0}); EXPECT_EQ(getPredictions().size(), 1u); EXPECT_EQ(getPredictions().size(), 1u); Loading Loading @@ -1054,6 +1062,9 @@ TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) { auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); tracingSession->StartBlocking(); tracingSession->StartBlocking(); // Add an empty surface frame so that display frame would get traced. addEmptySurfaceFrame(); int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30}); int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30}); // Set up the display frame // Set up the display frame Loading Loading @@ -1135,6 +1146,9 @@ TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpecte // Flush the token so that it would expire // Flush the token so that it would expire flushTokens(); flushTokens(); // Add an empty surface frame so that display frame would get traced. addEmptySurfaceFrame(); // Set up the display frame // Set up the display frame mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11)); mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11)); mFrameTimeline->setSfPresent(26, presentFence1); mFrameTimeline->setSfPresent(26, presentFence1); Loading Loading
services/surfaceflinger/FrameTimeline/FrameTimeline.cpp +6 −0 Original line number Original line Diff line number Diff line Loading @@ -1095,6 +1095,12 @@ void FrameTimeline::DisplayFrame::traceActuals(pid_t surfaceFlingerPid, } } void FrameTimeline::DisplayFrame::trace(pid_t surfaceFlingerPid, nsecs_t monoBootOffset) const { 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) { if (mToken == FrameTimelineInfo::INVALID_VSYNC_ID) { // DisplayFrame should not have an invalid token. // DisplayFrame should not have an invalid token. ALOGE("Cannot trace DisplayFrame with invalid token"); ALOGE("Cannot trace DisplayFrame with invalid token"); Loading
services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp +25 −11 Original line number Original line Diff line number Diff line Loading @@ -44,6 +44,17 @@ using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType; namespace android::frametimeline { 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 { class FrameTimelineTest : public testing::Test { public: public: FrameTimelineTest() { FrameTimelineTest() { Loading Loading @@ -106,6 +117,14 @@ public: return packets; return packets; } } void addEmptySurfaceFrame() { auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne, sLayerNameOne, sLayerNameOne, /*isBuffer*/ false, sGameMode); mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame)); } void addEmptyDisplayFrame() { void addEmptyDisplayFrame() { auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); // Trigger a flushPresentFence by calling setSfPresent for the next frame // Trigger a flushPresentFence by calling setSfPresent for the next frame Loading Loading @@ -168,17 +187,6 @@ public: kStartThreshold}; 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) { TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) { int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0}); int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0}); EXPECT_EQ(getPredictions().size(), 1u); EXPECT_EQ(getPredictions().size(), 1u); Loading Loading @@ -1054,6 +1062,9 @@ TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) { auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); tracingSession->StartBlocking(); tracingSession->StartBlocking(); // Add an empty surface frame so that display frame would get traced. addEmptySurfaceFrame(); int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30}); int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30}); // Set up the display frame // Set up the display frame Loading Loading @@ -1135,6 +1146,9 @@ TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpecte // Flush the token so that it would expire // Flush the token so that it would expire flushTokens(); flushTokens(); // Add an empty surface frame so that display frame would get traced. addEmptySurfaceFrame(); // Set up the display frame // Set up the display frame mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11)); mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11)); mFrameTimeline->setSfPresent(26, presentFence1); mFrameTimeline->setSfPresent(26, presentFence1); Loading