Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit defbb74c authored by Pascal Mütschard's avatar Pascal Mütschard
Browse files

Simplify the exposed jank types.

This is in preparation of making the jank API public. See go/jank-api.

Bug: b/293949943
Flag: EXEMPT refactor
Test: FrameworksCoreTests manual
Change-Id: Ibde381cc3d3acac71c95efecdfd8c1b1b9ba79e3
parent 046855a0
Loading
Loading
Loading
Loading
+18 −31
Original line number Diff line number Diff line
@@ -412,41 +412,28 @@ public final class SurfaceControl implements Parcelable {
     */
    public static class JankData {

        /** @hide */
        @IntDef(flag = true, value = {JANK_NONE,
                DISPLAY_HAL,
                JANK_SURFACEFLINGER_DEADLINE_MISSED,
                JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED,
                JANK_APP_DEADLINE_MISSED,
                PREDICTION_ERROR,
                SURFACE_FLINGER_SCHEDULING})
        /**
         * Needs to be kept in sync with android_view_SurfaceControl.cpp's
         * JankDataListenerWrapper::onJankDataAvailable.
         * @hide
         */
        @IntDef(flag = true, value = {
            JANK_NONE,
            JANK_COMPOSER,
            JANK_APPLICATION,
            JANK_OTHER,
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface JankType {}

        // Needs to be kept in sync with frameworks/native/libs/gui/include/gui/JankInfo.h

        // No Jank
        public static final int JANK_NONE = 0x0;

        // Jank not related to SurfaceFlinger or the App
        public static final int DISPLAY_HAL = 0x1;
        // SF took too long on the CPU
        public static final int JANK_SURFACEFLINGER_DEADLINE_MISSED = 0x2;
        // SF took too long on the GPU
        public static final int JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED = 0x4;
        // Either App or GPU took too long on the frame
        public static final int JANK_APP_DEADLINE_MISSED = 0x8;
        // Vsync predictions have drifted beyond the threshold from the actual HWVsync
        public static final int PREDICTION_ERROR = 0x10;
        // Latching a buffer early might cause an early present of the frame
        public static final int SURFACE_FLINGER_SCHEDULING = 0x20;
        // A buffer is said to be stuffed if it was expected to be presented on a vsync but was
        // presented later because the previous buffer was presented in its expected vsync. This
        // usually happens if there is an unexpectedly long frame causing the rest of the buffers
        // to enter a stuffed state.
        public static final int BUFFER_STUFFING = 0x40;
        // Jank due to unknown reasons.
        public static final int UNKNOWN = 0x80;
        public static final int JANK_NONE = 0;
        // Jank caused by the composer missing a deadline
        public static final int JANK_COMPOSER = 1 << 0;
        // Jank caused by the application missing the composer's deadline
        public static final int JANK_APPLICATION = 1 << 1;
        // Jank due to other unknown reasons
        public static final int JANK_OTHER = 1 << 2;

        public JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs,
                long scheduledAppFrameTimeNs, long actualAppFrameTimeNs) {
+8 −28
Original line number Diff line number Diff line
@@ -16,13 +16,9 @@

package com.android.internal.jank;

import static android.view.SurfaceControl.JankData.DISPLAY_HAL;
import static android.view.SurfaceControl.JankData.JANK_APP_DEADLINE_MISSED;
import static android.view.SurfaceControl.JankData.JANK_APPLICATION;
import static android.view.SurfaceControl.JankData.JANK_COMPOSER;
import static android.view.SurfaceControl.JankData.JANK_NONE;
import static android.view.SurfaceControl.JankData.JANK_SURFACEFLINGER_DEADLINE_MISSED;
import static android.view.SurfaceControl.JankData.JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED;
import static android.view.SurfaceControl.JankData.PREDICTION_ERROR;
import static android.view.SurfaceControl.JankData.SURFACE_FLINGER_SCHEDULING;

import static com.android.internal.jank.DisplayRefreshRate.UNKNOWN_REFRESH_RATE;
import static com.android.internal.jank.DisplayRefreshRate.VARIABLE_REFRESH_RATE;
@@ -181,23 +177,11 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai
                case JANK_NONE:
                    str.append("JANK_NONE");
                    break;
                case JANK_APP_DEADLINE_MISSED:
                    str.append("JANK_APP_DEADLINE_MISSED");
                case JANK_APPLICATION:
                    str.append("JANK_APPLICATION");
                    break;
                case JANK_SURFACEFLINGER_DEADLINE_MISSED:
                    str.append("JANK_SURFACEFLINGER_DEADLINE_MISSED");
                    break;
                case JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED:
                    str.append("JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED");
                    break;
                case DISPLAY_HAL:
                    str.append("DISPLAY_HAL");
                    break;
                case PREDICTION_ERROR:
                    str.append("PREDICTION_ERROR");
                    break;
                case SURFACE_FLINGER_SCHEDULING:
                    str.append("SURFACE_FLINGER_SCHEDULING");
                case JANK_COMPOSER:
                    str.append("JANK_COMPOSER");
                    break;
                default:
                    str.append("UNKNOWN: ").append(jankType);
@@ -608,16 +592,12 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai
            if (info.surfaceControlCallbackFired) {
                totalFramesCount++;
                boolean missedFrame = false;
                if ((info.jankType & JANK_APP_DEADLINE_MISSED) != 0) {
                if ((info.jankType & JANK_APPLICATION) != 0) {
                    Log.w(TAG, "Missed App frame:" + info + ", CUJ=" + name);
                    missedAppFramesCount++;
                    missedFrame = true;
                }
                if ((info.jankType & DISPLAY_HAL) != 0
                        || (info.jankType & JANK_SURFACEFLINGER_DEADLINE_MISSED) != 0
                        || (info.jankType & JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED) != 0
                        || (info.jankType & SURFACE_FLINGER_SCHEDULING) != 0
                        || (info.jankType & PREDICTION_ERROR) != 0) {
                if ((info.jankType & JANK_COMPOSER) != 0) {
                    Log.w(TAG, "Missed SF frame:" + info + ", CUJ=" + name);
                    missedSfFramesCount++;
                    missedFrame = true;
+23 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <android_runtime/android_view_SurfaceSession.h>
#include <cutils/ashmem.h>
#include <gui/ISurfaceComposer.h>
#include <gui/JankInfo.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <jni.h>
@@ -2161,9 +2162,30 @@ public:
        jobjectArray jJankDataArray = env->NewObjectArray(jankData.size(),
                gJankDataClassInfo.clazz, nullptr);
        for (size_t i = 0; i < jankData.size(); i++) {
            // The exposed constants in SurfaceControl are simplified, so we need to translate the
            // jank type we get from SF to what is exposed in Java.
            int sfJankType = jankData[i].jankType;
            int javaJankType = 0x0; // SurfaceControl.JankData.JANK_NONE
            if (sfJankType &
                (JankType::DisplayHAL | JankType::SurfaceFlingerCpuDeadlineMissed |
                 JankType::SurfaceFlingerGpuDeadlineMissed | JankType::PredictionError |
                 JankType::SurfaceFlingerScheduling)) {
                javaJankType |= 0x1; // SurfaceControl.JankData.JANK_COMPOSER
            }
            if (sfJankType & JankType::AppDeadlineMissed) {
                javaJankType |= 0x2; // SurfaceControl.JankData.JANK_APPLICATION
            }
            if (sfJankType &
                ~(JankType::DisplayHAL | JankType::SurfaceFlingerCpuDeadlineMissed |
                  JankType::SurfaceFlingerGpuDeadlineMissed | JankType::AppDeadlineMissed |
                  JankType::PredictionError | JankType::SurfaceFlingerScheduling |
                  JankType::BufferStuffing | JankType::SurfaceFlingerStuffing)) {
                javaJankType |= 0x4; // SurfaceControl.JankData.JANK_OTHER
            }

            jobject jJankData =
                    env->NewObject(gJankDataClassInfo.clazz, gJankDataClassInfo.ctor,
                                   jankData[i].frameVsyncId, jankData[i].jankType,
                                   jankData[i].frameVsyncId, javaJankType,
                                   jankData[i].frameIntervalNs, jankData[i].scheduledAppFrameTimeNs,
                                   jankData[i].actualAppFrameTimeNs);
            env->SetObjectArrayElement(jJankDataArray, i, jJankData);
+20 −20
Original line number Diff line number Diff line
@@ -16,9 +16,9 @@

package com.android.internal.jank;

import static android.view.SurfaceControl.JankData.JANK_APP_DEADLINE_MISSED;
import static android.view.SurfaceControl.JankData.JANK_APPLICATION;
import static android.view.SurfaceControl.JankData.JANK_COMPOSER;
import static android.view.SurfaceControl.JankData.JANK_NONE;
import static android.view.SurfaceControl.JankData.JANK_SURFACEFLINGER_DEADLINE_MISSED;

import static com.android.internal.jank.FrameTracker.SurfaceControlWrapper;
import static com.android.internal.jank.FrameTracker.ViewRootWrapper;
@@ -164,7 +164,7 @@ public class FrameTrackerTest {
        verify(mRenderer, only()).addObserver(any());

        // send first frame with a long duration - should not be taken into account
        sendFirstWindowFrame(tracker, 100, JANK_APP_DEADLINE_MISSED, 100L);
        sendFirstWindowFrame(tracker, 100, JANK_APPLICATION, 100L);

        // send another frame with a short duration - should not be considered janky
        sendFrame(tracker, 5, JANK_NONE, 101L);
@@ -173,7 +173,7 @@ public class FrameTrackerTest {
        when(mChoreographer.getVsyncId()).thenReturn(102L);
        tracker.end(FrameTracker.REASON_END_NORMAL);
        sendFrame(tracker, 5, JANK_NONE, 102L);
        sendFrame(tracker, 500, JANK_APP_DEADLINE_MISSED, 103L);
        sendFrame(tracker, 500, JANK_APPLICATION, 103L);

        verify(tracker).removeObservers();
        verify(mTrackerListener, never()).triggerPerfetto(any());
@@ -202,7 +202,7 @@ public class FrameTrackerTest {
        sendFrame(tracker, 4, JANK_NONE, 100L);

        // send another frame - should be considered janky
        sendFrame(tracker, 40, JANK_SURFACEFLINGER_DEADLINE_MISSED, 101L);
        sendFrame(tracker, 40, JANK_COMPOSER, 101L);

        // end the trace session
        when(mChoreographer.getVsyncId()).thenReturn(102L);
@@ -236,7 +236,7 @@ public class FrameTrackerTest {
        verify(mRenderer, only()).addObserver(any());

        // send first frame - janky
        sendFrame(tracker, 40, JANK_APP_DEADLINE_MISSED, 100L);
        sendFrame(tracker, 40, JANK_APPLICATION, 100L);

        // send another frame - not jank
        sendFrame(tracker, 4, JANK_NONE, 101L);
@@ -275,7 +275,7 @@ public class FrameTrackerTest {
        sendFrame(tracker, 4, JANK_NONE, 100L);

        // send another frame - should be considered janky
        sendFrame(tracker, 40, JANK_APP_DEADLINE_MISSED, 101L);
        sendFrame(tracker, 40, JANK_APPLICATION, 101L);

        // end the trace session
        when(mChoreographer.getVsyncId()).thenReturn(102L);
@@ -317,7 +317,7 @@ public class FrameTrackerTest {
        // end the trace session, simulate one more valid callback came after the end call.
        when(mChoreographer.getVsyncId()).thenReturn(102L);
        tracker.end(FrameTracker.REASON_END_NORMAL);
        sendFrame(tracker, 50, JANK_APP_DEADLINE_MISSED, 102L);
        sendFrame(tracker, 50, JANK_APPLICATION, 102L);

        // One more callback with VSYNC after the end() vsync id.
        sendFrame(tracker, 4, JANK_NONE, 103L);
@@ -365,7 +365,7 @@ public class FrameTrackerTest {
        sendSfFrame(tracker, 4, 102L, JANK_NONE);

        // Send janky but complete callbck fo 103L
        sendFrame(tracker, 50, JANK_APP_DEADLINE_MISSED, 103L);
        sendFrame(tracker, 50, JANK_APPLICATION, 103L);

        verify(tracker).removeObservers();
        verify(mTrackerListener, never()).triggerPerfetto(any());
@@ -397,7 +397,7 @@ public class FrameTrackerTest {
        sendFrame(tracker, 4, JANK_NONE, 101L);

        // a janky frame
        sendFrame(tracker, 50, JANK_APP_DEADLINE_MISSED, 102L);
        sendFrame(tracker, 50, JANK_APPLICATION, 102L);

        tracker.cancel(FrameTracker.REASON_CANCEL_NORMAL);
        verify(tracker).removeObservers();
@@ -481,7 +481,7 @@ public class FrameTrackerTest {
        // normal frame - not janky
        sendFrame(tracker, JANK_NONE, 101L);
        // a janky frame
        sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 102L);
        sendFrame(tracker, JANK_APPLICATION, 102L);

        when(mChoreographer.getVsyncId()).thenReturn(102L);
        tracker.end(FrameTracker.REASON_CANCEL_NORMAL);
@@ -514,7 +514,7 @@ public class FrameTrackerTest {
        verify(mSurfaceControlWrapper).addJankStatsListener(any(), any());

        // First frame - janky
        sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 100L);
        sendFrame(tracker, JANK_APPLICATION, 100L);
        // normal frame - not janky
        sendFrame(tracker, JANK_NONE, 101L);
        // normal frame - not janky
@@ -561,7 +561,7 @@ public class FrameTrackerTest {
        tracker.end(FrameTracker.REASON_CANCEL_NORMAL);

        // janky frame, should be ignored, trigger finish
        sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 103L);
        sendFrame(tracker, JANK_APPLICATION, 103L);

        verify(mJankStatsRegistration).removeAfter(anyLong());
        verify(mTrackerListener, never()).triggerPerfetto(any());
@@ -623,16 +623,16 @@ public class FrameTrackerTest {
        tracker.begin();
        mRunnableArgumentCaptor.getValue().run();
        verify(mSurfaceControlWrapper).addJankStatsListener(any(), any());
        sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 100L);
        sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 101L);
        sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 102L);
        sendFrame(tracker, JANK_COMPOSER, 100L);
        sendFrame(tracker, JANK_COMPOSER, 101L);
        sendFrame(tracker, JANK_APPLICATION, 102L);
        sendFrame(tracker, JANK_NONE, 103L);
        sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 104L);
        sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 105L);
        sendFrame(tracker, JANK_APPLICATION, 104L);
        sendFrame(tracker, JANK_APPLICATION, 105L);
        when(mChoreographer.getVsyncId()).thenReturn(106L);
        tracker.end(FrameTracker.REASON_END_NORMAL);
        sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 106L);
        sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 107L);
        sendFrame(tracker, JANK_COMPOSER, 106L);
        sendFrame(tracker, JANK_COMPOSER, 107L);
        verify(mJankStatsRegistration).removeAfter(anyLong());
        verify(mTrackerListener).triggerPerfetto(any());
        verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),