SF: treat prediction expired as app missed deadline
We are keeping enough vsyncIds for a reasonable app to
send back their vsyncId. If we can't find the vsync id of that
app, we can be pretty confident that the app had a huge schedule
delay.
Bug: 211763914
Test: SF unit tests
Change-Id: I046a87e566844bb140df75df3d06f809b7d99155
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index 86e96d7..81747d5 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -492,17 +492,22 @@
void SurfaceFrame::classifyJankLocked(int32_t displayFrameJankType, const Fps& refreshRate,
nsecs_t& deadlineDelta) {
- if (mPredictionState == PredictionState::Expired ||
- mActuals.presentTime == Fence::SIGNAL_TIME_INVALID) {
+ if (mActuals.presentTime == Fence::SIGNAL_TIME_INVALID) {
// Cannot do any classification for invalid present time.
- // For prediction expired case, we do not know what happened here to classify this
- // correctly. This could potentially be AppDeadlineMissed but that's assuming no app will
- // request frames 120ms apart.
mJankType = JankType::Unknown;
deadlineDelta = -1;
return;
}
+ if (mPredictionState == PredictionState::Expired) {
+ // We classify prediction expired as AppDeadlineMissed as the
+ // TokenManager::kMaxTokens we store is large enough to account for a
+ // reasonable app, so prediction expire would mean a huge scheduling delay.
+ mJankType = JankType::AppDeadlineMissed;
+ deadlineDelta = -1;
+ return;
+ }
+
if (mPredictionState == PredictionState::None) {
// Cannot do jank classification on frames that don't have a token.
return;
diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
index 397c619..834a560 100644
--- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
@@ -1279,7 +1279,7 @@
validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
}
-TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
+TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
auto tracingSession = getTracingSessionForTest();
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
@@ -1312,7 +1312,7 @@
createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
displayFrameToken, sPidOne, sLayerNameOne,
FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
- false, FrameTimelineEvent::JANK_UNKNOWN,
+ false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
FrameTimelineEvent::PREDICTION_EXPIRED, true);
auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);