diff options
| author | 2024-09-03 11:06:58 +0200 | |
|---|---|---|
| committer | 2024-09-03 11:11:03 +0200 | |
| commit | e109ae2ffc3a115e5b548c9247e429db24d53c1c (patch) | |
| tree | 2d507d1d755476f8b112bbc6478aed5cbeb4fbcd | |
| parent | 5ff76a1a8e988edc85f3e5dc07b0dcdae5fa8ba0 (diff) | |
Add the expected and actual frame duration to the SF jank data.
Adds the expected and actual frame duration, that is the frame durations
as shown in the frame timeline in Perfetto, to the jank data exposed by
SurfaceFlinger.
This reverts commit e0af07b8e6f6008ea3eb6b1f9ee72c86d19a5b5f.
Bug: b/354763298
Test: FrameworksCoreTests manual
Flag: com.android.internal.jank.use_sf_frame_duration
Change-Id: I0b7a2baeb20cac2e0c012c3a54a79d43652c60fa
4 files changed, 46 insertions, 36 deletions
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 9e4b27d3fa55..2dda835436bc 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -445,16 +445,20 @@ public final class SurfaceControl implements Parcelable { // Jank due to unknown reasons. public static final int UNKNOWN = 0x80; - public JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs) { + public JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs, + long scheduledAppFrameTimeNs, long actualAppFrameTimeNs) { this.frameVsyncId = frameVsyncId; this.jankType = jankType; this.frameIntervalNs = frameIntervalNs; - + this.scheduledAppFrameTimeNs = scheduledAppFrameTimeNs; + this.actualAppFrameTimeNs = actualAppFrameTimeNs; } public final long frameVsyncId; public final @JankType int jankType; public final long frameIntervalNs; + public final long scheduledAppFrameTimeNs; + public final long actualAppFrameTimeNs; } /** diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java index 53ef49bd3f65..2254e944c669 100644 --- a/core/java/com/android/internal/jank/FrameTracker.java +++ b/core/java/com/android/internal/jank/FrameTracker.java @@ -127,7 +127,7 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai private Runnable mWaitForFinishTimedOut; private static class JankInfo { - long frameVsyncId; + final long frameVsyncId; long totalDurationNanos; boolean isFirstFrame; boolean hwuiCallbackFired; @@ -135,29 +135,37 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai @JankType int jankType; @RefreshRate int refreshRate; - static JankInfo createFromHwuiCallback(long frameVsyncId, long totalDurationNanos, - boolean isFirstFrame) { - return new JankInfo(frameVsyncId, true, false, JANK_NONE, UNKNOWN_REFRESH_RATE, - totalDurationNanos, isFirstFrame); + static JankInfo createFromHwuiCallback( + long frameVsyncId, long totalDurationNanos, boolean isFirstFrame) { + return new JankInfo(frameVsyncId).update(totalDurationNanos, isFirstFrame); } - static JankInfo createFromSurfaceControlCallback(long frameVsyncId, - @JankType int jankType, @RefreshRate int refreshRate) { - return new JankInfo( - frameVsyncId, false, true, jankType, refreshRate, 0, false /* isFirstFrame */); + static JankInfo createFromSurfaceControlCallback(SurfaceControl.JankData jankStat) { + return new JankInfo(jankStat.frameVsyncId).update(jankStat); } - private JankInfo(long frameVsyncId, boolean hwuiCallbackFired, - boolean surfaceControlCallbackFired, @JankType int jankType, - @RefreshRate int refreshRate, - long totalDurationNanos, boolean isFirstFrame) { + private JankInfo(long frameVsyncId) { this.frameVsyncId = frameVsyncId; - this.hwuiCallbackFired = hwuiCallbackFired; - this.surfaceControlCallbackFired = surfaceControlCallbackFired; - this.jankType = jankType; - this.refreshRate = refreshRate; + this.hwuiCallbackFired = false; + this.surfaceControlCallbackFired = false; + this.jankType = JANK_NONE; + this.refreshRate = UNKNOWN_REFRESH_RATE; + this.totalDurationNanos = 0; + this.isFirstFrame = false; + } + + private JankInfo update(SurfaceControl.JankData jankStat) { + this.surfaceControlCallbackFired = true; + this.jankType = jankStat.jankType; + this.refreshRate = DisplayRefreshRate.getRefreshRate(jankStat.frameIntervalNs); + return this; + } + + private JankInfo update(long totalDurationNanos, boolean isFirstFrame) { + this.hwuiCallbackFired = true; this.totalDurationNanos = totalDurationNanos; this.isFirstFrame = isFirstFrame; + return this; } @Override @@ -457,16 +465,12 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai if (!isInRange(jankStat.frameVsyncId)) { continue; } - int refreshRate = DisplayRefreshRate.getRefreshRate(jankStat.frameIntervalNs); JankInfo info = findJankInfo(jankStat.frameVsyncId); if (info != null) { - info.surfaceControlCallbackFired = true; - info.jankType = jankStat.jankType; - info.refreshRate = refreshRate; + info.update(jankStat); } else { mJankInfos.put((int) jankStat.frameVsyncId, - JankInfo.createFromSurfaceControlCallback( - jankStat.frameVsyncId, jankStat.jankType, refreshRate)); + JankInfo.createFromSurfaceControlCallback(jankStat)); } } processJankInfos(); @@ -513,9 +517,7 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai } JankInfo info = findJankInfo(frameVsyncId); if (info != null) { - info.hwuiCallbackFired = true; - info.totalDurationNanos = totalDurationNanos; - info.isFirstFrame = isFirstFrame; + info.update(totalDurationNanos, isFirstFrame); } else { mJankInfos.put((int) frameVsyncId, JankInfo.createFromHwuiCallback( frameVsyncId, totalDurationNanos, isFirstFrame)); diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 0f531641903a..17c89f88b441 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -2089,9 +2089,11 @@ public: jobjectArray jJankDataArray = env->NewObjectArray(jankData.size(), gJankDataClassInfo.clazz, nullptr); for (size_t i = 0; i < jankData.size(); i++) { - jobject jJankData = env->NewObject(gJankDataClassInfo.clazz, gJankDataClassInfo.ctor, - jankData[i].frameVsyncId, jankData[i].jankType, - jankData[i].frameIntervalNs); + jobject jJankData = + env->NewObject(gJankDataClassInfo.clazz, gJankDataClassInfo.ctor, + jankData[i].frameVsyncId, jankData[i].jankType, + jankData[i].frameIntervalNs, jankData[i].scheduledAppFrameTimeNs, + jankData[i].actualAppFrameTimeNs); env->SetObjectArrayElement(jJankDataArray, i, jJankData); env->DeleteLocalRef(jJankData); } @@ -2727,7 +2729,7 @@ int register_android_view_SurfaceControl(JNIEnv* env) jclass jankDataClazz = FindClassOrDie(env, "android/view/SurfaceControl$JankData"); gJankDataClassInfo.clazz = MakeGlobalRefOrDie(env, jankDataClazz); - gJankDataClassInfo.ctor = GetMethodIDOrDie(env, gJankDataClassInfo.clazz, "<init>", "(JIJ)V"); + gJankDataClassInfo.ctor = GetMethodIDOrDie(env, gJankDataClassInfo.clazz, "<init>", "(JIJJJ)V"); jclass onJankDataListenerClazz = FindClassOrDie(env, "android/view/SurfaceControl$OnJankDataListener"); gJankDataListenerClassInfo.clazz = MakeGlobalRefOrDie(env, onJankDataListenerClazz); diff --git a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java index 499caf5e12d3..c3a5b19c9442 100644 --- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java +++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java @@ -359,7 +359,7 @@ public class FrameTrackerTest { tracker.end(FrameTracker.REASON_END_NORMAL); // Send incomplete callback for 102L - sendSfFrame(tracker, 102L, JANK_NONE); + sendSfFrame(tracker, 4, 102L, JANK_NONE); // Send janky but complete callbck fo 103L sendFrame(tracker, 50, JANK_APP_DEADLINE_MISSED, 103L); @@ -629,7 +629,7 @@ public class FrameTrackerTest { if (!tracker.mSurfaceOnly) { sendHwuiFrame(tracker, durationMillis, vsyncId, firstWindowFrame); } - sendSfFrame(tracker, vsyncId, jankType); + sendSfFrame(tracker, durationMillis, vsyncId, jankType); } private void sendHwuiFrame(FrameTracker tracker, long durationMillis, long vsyncId, @@ -645,11 +645,13 @@ public class FrameTrackerTest { captor.getValue().run(); } - private void sendSfFrame(FrameTracker tracker, long vsyncId, @JankType int jankType) { + private void sendSfFrame( + FrameTracker tracker, long durationMillis, long vsyncId, @JankType int jankType) { final ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class); doNothing().when(tracker).postCallback(captor.capture()); mListenerCapture.getValue().onJankDataAvailable(new JankData[] { - new JankData(vsyncId, jankType, FRAME_TIME_60Hz) + new JankData(vsyncId, jankType, FRAME_TIME_60Hz, FRAME_TIME_60Hz, + TimeUnit.MILLISECONDS.toNanos(durationMillis)) }); captor.getValue().run(); } |