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

Commit d0ea7711 authored by Pascal Mütschard's avatar Pascal Mütschard Committed by Android (Google) Code Review
Browse files

Merge "Simplify the exposed jank types." into main

parents 5f18cce7 defbb74c
Loading
Loading
Loading
Loading
+18 −31
Original line number Original line Diff line number Diff line
@@ -412,41 +412,28 @@ public final class SurfaceControl implements Parcelable {
     */
     */
    public static class JankData {
    public static class JankData {


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


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

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

        // Jank caused by the composer missing a deadline
        // Jank not related to SurfaceFlinger or the App
        public static final int JANK_COMPOSER = 1 << 0;
        public static final int DISPLAY_HAL = 0x1;
        // Jank caused by the application missing the composer's deadline
        // SF took too long on the CPU
        public static final int JANK_APPLICATION = 1 << 1;
        public static final int JANK_SURFACEFLINGER_DEADLINE_MISSED = 0x2;
        // Jank due to other unknown reasons
        // SF took too long on the GPU
        public static final int JANK_OTHER = 1 << 2;
        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 JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs,
        public JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs,
                long scheduledAppFrameTimeNs, long actualAppFrameTimeNs) {
                long scheduledAppFrameTimeNs, long actualAppFrameTimeNs) {
+8 −28
Original line number Original line Diff line number Diff line
@@ -16,13 +16,9 @@


package com.android.internal.jank;
package com.android.internal.jank;


import static android.view.SurfaceControl.JankData.DISPLAY_HAL;
import static android.view.SurfaceControl.JankData.JANK_APPLICATION;
import static android.view.SurfaceControl.JankData.JANK_APP_DEADLINE_MISSED;
import static android.view.SurfaceControl.JankData.JANK_COMPOSER;
import static android.view.SurfaceControl.JankData.JANK_NONE;
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.UNKNOWN_REFRESH_RATE;
import static com.android.internal.jank.DisplayRefreshRate.VARIABLE_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:
                case JANK_NONE:
                    str.append("JANK_NONE");
                    str.append("JANK_NONE");
                    break;
                    break;
                case JANK_APP_DEADLINE_MISSED:
                case JANK_APPLICATION:
                    str.append("JANK_APP_DEADLINE_MISSED");
                    str.append("JANK_APPLICATION");
                    break;
                    break;
                case JANK_SURFACEFLINGER_DEADLINE_MISSED:
                case JANK_COMPOSER:
                    str.append("JANK_SURFACEFLINGER_DEADLINE_MISSED");
                    str.append("JANK_COMPOSER");
                    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");
                    break;
                    break;
                default:
                default:
                    str.append("UNKNOWN: ").append(jankType);
                    str.append("UNKNOWN: ").append(jankType);
@@ -628,16 +612,12 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai
            if (info.surfaceControlCallbackFired) {
            if (info.surfaceControlCallbackFired) {
                totalFramesCount++;
                totalFramesCount++;
                boolean missedFrame = false;
                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);
                    Log.w(TAG, "Missed App frame:" + info + ", CUJ=" + name);
                    missedAppFramesCount++;
                    missedAppFramesCount++;
                    missedFrame = true;
                    missedFrame = true;
                }
                }
                if ((info.jankType & DISPLAY_HAL) != 0
                if ((info.jankType & JANK_COMPOSER) != 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) {
                    Log.w(TAG, "Missed SF frame:" + info + ", CUJ=" + name);
                    Log.w(TAG, "Missed SF frame:" + info + ", CUJ=" + name);
                    missedSfFramesCount++;
                    missedSfFramesCount++;
                    missedFrame = true;
                    missedFrame = true;
+23 −1
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@
#include <android_runtime/android_view_SurfaceSession.h>
#include <android_runtime/android_view_SurfaceSession.h>
#include <cutils/ashmem.h>
#include <cutils/ashmem.h>
#include <gui/ISurfaceComposer.h>
#include <gui/ISurfaceComposer.h>
#include <gui/JankInfo.h>
#include <gui/Surface.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SurfaceComposerClient.h>
#include <jni.h>
#include <jni.h>
@@ -2161,9 +2162,30 @@ public:
        jobjectArray jJankDataArray = env->NewObjectArray(jankData.size(),
        jobjectArray jJankDataArray = env->NewObjectArray(jankData.size(),
                gJankDataClassInfo.clazz, nullptr);
                gJankDataClassInfo.clazz, nullptr);
        for (size_t i = 0; i < jankData.size(); i++) {
        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 =
            jobject jJankData =
                    env->NewObject(gJankDataClassInfo.clazz, gJankDataClassInfo.ctor,
                    env->NewObject(gJankDataClassInfo.clazz, gJankDataClassInfo.ctor,
                                   jankData[i].frameVsyncId, jankData[i].jankType,
                                   jankData[i].frameVsyncId, javaJankType,
                                   jankData[i].frameIntervalNs, jankData[i].scheduledAppFrameTimeNs,
                                   jankData[i].frameIntervalNs, jankData[i].scheduledAppFrameTimeNs,
                                   jankData[i].actualAppFrameTimeNs);
                                   jankData[i].actualAppFrameTimeNs);
            env->SetObjectArrayElement(jJankDataArray, i, jJankData);
            env->SetObjectArrayElement(jJankDataArray, i, jJankData);
+20 −20
Original line number Original line Diff line number Diff line
@@ -16,9 +16,9 @@


package com.android.internal.jank;
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_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.SurfaceControlWrapper;
import static com.android.internal.jank.FrameTracker.ViewRootWrapper;
import static com.android.internal.jank.FrameTracker.ViewRootWrapper;
@@ -164,7 +164,7 @@ public class FrameTrackerTest {
        verify(mRenderer, only()).addObserver(any());
        verify(mRenderer, only()).addObserver(any());


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


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


        // send another frame - should be considered janky
        // 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
        // end the trace session
        when(mChoreographer.getVsyncId()).thenReturn(102L);
        when(mChoreographer.getVsyncId()).thenReturn(102L);
@@ -236,7 +236,7 @@ public class FrameTrackerTest {
        verify(mRenderer, only()).addObserver(any());
        verify(mRenderer, only()).addObserver(any());


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


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


        // send another frame - should be considered janky
        // 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
        // end the trace session
        when(mChoreographer.getVsyncId()).thenReturn(102L);
        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.
        // end the trace session, simulate one more valid callback came after the end call.
        when(mChoreographer.getVsyncId()).thenReturn(102L);
        when(mChoreographer.getVsyncId()).thenReturn(102L);
        tracker.end(FrameTracker.REASON_END_NORMAL);
        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.
        // One more callback with VSYNC after the end() vsync id.
        sendFrame(tracker, 4, JANK_NONE, 103L);
        sendFrame(tracker, 4, JANK_NONE, 103L);
@@ -365,7 +365,7 @@ public class FrameTrackerTest {
        sendSfFrame(tracker, 4, 102L, JANK_NONE);
        sendSfFrame(tracker, 4, 102L, JANK_NONE);


        // Send janky but complete callbck fo 103L
        // 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(tracker).removeObservers();
        verify(mTrackerListener, never()).triggerPerfetto(any());
        verify(mTrackerListener, never()).triggerPerfetto(any());
@@ -397,7 +397,7 @@ public class FrameTrackerTest {
        sendFrame(tracker, 4, JANK_NONE, 101L);
        sendFrame(tracker, 4, JANK_NONE, 101L);


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


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


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


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


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


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