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

Commit 5cce9993 authored by Rachel Lee's avatar Rachel Lee
Browse files

API: add smooth switch in setFrameRateCategory

This allows the platform to have a different behavior depending on
whether a device is MRR or dVRR. When the bool is `true`, MRR devices
(those with DisplayModes that do not have vrr config) will not change
frame rates if it would cause jank. The expected usage is to mark the
bool true when an animation is running.

Bug: 300491171
Test: atest libsurfaceflinger_unittest
Change-Id: I4b28e5b100b7deecda27d4c9134e734bc9c51b47
parent 5b361c07
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -263,7 +263,7 @@ public final class SurfaceControl implements Parcelable {
    private static native void nativeSetDefaultFrameRateCompatibility(long transactionObj,
            long nativeObject, int compatibility);
    private static native void nativeSetFrameRateCategory(
            long transactionObj, long nativeObject, int category);
            long transactionObj, long nativeObject, int category, boolean smoothSwitchOnly);
    private static native void nativeSetFrameRateSelectionStrategy(
            long transactionObj, long nativeObject, int strategy);
    private static native long nativeGetHandle(long nativeObject);
@@ -3701,6 +3701,10 @@ public final class SurfaceControl implements Parcelable {
         * @param sc The SurfaceControl to specify the frame rate category of.
         * @param category The frame rate category of this surface. The category value may influence
         * the system's choice of display frame rate.
         * @param smoothSwitchOnly Set to {@code true} to indicate the display frame rate should not
         * change if changing it would cause jank. Else {@code false}.
         * This parameter is ignored when {@code category} is
         * {@link Surface#FRAME_RATE_CATEGORY_DEFAULT}.
         *
         * @return This transaction object.
         *
@@ -3709,10 +3713,10 @@ public final class SurfaceControl implements Parcelable {
         * @hide
         */
        @NonNull
        public Transaction setFrameRateCategory(
                @NonNull SurfaceControl sc, @Surface.FrameRateCategory int category) {
        public Transaction setFrameRateCategory(@NonNull SurfaceControl sc,
                @Surface.FrameRateCategory int category, boolean smoothSwitchOnly) {
            checkPreconditions(sc);
            nativeSetFrameRateCategory(mNativeObject, sc.mNativeObject, category);
            nativeSetFrameRateCategory(mNativeObject, sc.mNativeObject, category, smoothSwitchOnly);
            return this;
        }

+10 −2
Original line number Diff line number Diff line
@@ -211,7 +211,11 @@ public class SystemPerformanceHinter {
                    session.displayId);
            mTransaction.setFrameRateSelectionStrategy(displaySurfaceControl,
                    FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN);
            mTransaction.setFrameRateCategory(displaySurfaceControl, FRAME_RATE_CATEGORY_HIGH);
            // smoothSwitchOnly is false to request a higher framerate, even if it means switching
            // the display mode will cause would jank on non-VRR devices because keeping a lower
            // refresh rate would mean a poorer user experience.
            mTransaction.setFrameRateCategory(
                    displaySurfaceControl, FRAME_RATE_CATEGORY_HIGH, /* smoothSwitchOnly= */ false);
            transactionChanged = true;
            Trace.beginAsyncSection("PerfHint-framerate-" + session.displayId + "-"
                    + session.reason, session.traceCookie);
@@ -251,7 +255,11 @@ public class SystemPerformanceHinter {
                    session.displayId);
            mTransaction.setFrameRateSelectionStrategy(displaySurfaceControl,
                    FRAME_RATE_SELECTION_STRATEGY_SELF);
            mTransaction.setFrameRateCategory(displaySurfaceControl, FRAME_RATE_CATEGORY_DEFAULT);
            // smoothSwitchOnly is false to request a higher framerate, even if it means switching
            // the display mode will cause would jank on non-VRR devices because keeping a lower
            // refresh rate would mean a poorer user experience.
            mTransaction.setFrameRateCategory(displaySurfaceControl, FRAME_RATE_CATEGORY_DEFAULT,
                    /* smoothSwitchOnly= */ false);
            transactionChanged = true;
            Trace.endAsyncSection("PerfHint-framerate-" + session.displayId + "-" + session.reason,
                    session.traceCookie);
+4 −3
Original line number Diff line number Diff line
@@ -962,10 +962,11 @@ static void nativeSetDefaultFrameRateCompatibility(JNIEnv* env, jclass clazz, jl
}

static void nativeSetFrameRateCategory(JNIEnv* env, jclass clazz, jlong transactionObj,
                                       jlong nativeObject, jint category) {
                                       jlong nativeObject, jint category,
                                       jboolean smoothSwitchOnly) {
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
    const auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
    transaction->setFrameRateCategory(ctrl, static_cast<int8_t>(category));
    transaction->setFrameRateCategory(ctrl, static_cast<int8_t>(category), smoothSwitchOnly);
}

static void nativeSetFrameRateSelectionStrategy(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -2179,7 +2180,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            (void*)nativeSetFrameRate },
    {"nativeSetDefaultFrameRateCompatibility", "(JJI)V",
            (void*)nativeSetDefaultFrameRateCompatibility},
    {"nativeSetFrameRateCategory", "(JJI)V",
    {"nativeSetFrameRateCategory", "(JJIZ)V",
            (void*)nativeSetFrameRateCategory},
    {"nativeSetFrameRateSelectionStrategy", "(JJI)V",
            (void*)nativeSetFrameRateSelectionStrategy},
+27 −14
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -154,7 +155,8 @@ public class SystemPerformanceHinterTests {
                eq(FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN));
        verify(mTransaction).setFrameRateCategory(
                eq(mDefaultDisplayRoot),
                eq(FRAME_RATE_CATEGORY_HIGH));
                eq(FRAME_RATE_CATEGORY_HIGH),
                eq(false));
        verify(mTransaction).applyAsyncUnsafe();
    }

@@ -171,7 +173,8 @@ public class SystemPerformanceHinterTests {
                eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
        verify(mTransaction).setFrameRateCategory(
                eq(mDefaultDisplayRoot),
                eq(FRAME_RATE_CATEGORY_DEFAULT));
                eq(FRAME_RATE_CATEGORY_DEFAULT),
                eq(false));
        verify(mTransaction).applyAsyncUnsafe();
    }

@@ -241,7 +244,8 @@ public class SystemPerformanceHinterTests {
                eq(FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN));
        verify(mTransaction).setFrameRateCategory(
                eq(mDefaultDisplayRoot),
                eq(FRAME_RATE_CATEGORY_HIGH));
                eq(FRAME_RATE_CATEGORY_HIGH),
                eq(false));
        verify(mTransaction).setEarlyWakeupStart();
        verify(mTransaction).applyAsyncUnsafe();
        verify(mAdpfSession).sendHint(eq(CPU_LOAD_UP));
@@ -261,7 +265,8 @@ public class SystemPerformanceHinterTests {
                eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
        verify(mTransaction).setFrameRateCategory(
                eq(mDefaultDisplayRoot),
                eq(FRAME_RATE_CATEGORY_DEFAULT));
                eq(FRAME_RATE_CATEGORY_DEFAULT),
                eq(false));
        verify(mTransaction).setEarlyWakeupEnd();
        verify(mTransaction).applyAsyncUnsafe();
        verify(mAdpfSession).sendHint(eq(CPU_LOAD_RESET));
@@ -281,7 +286,8 @@ public class SystemPerformanceHinterTests {
                    eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
            verify(mTransaction).setFrameRateCategory(
                    eq(mDefaultDisplayRoot),
                    eq(FRAME_RATE_CATEGORY_DEFAULT));
                    eq(FRAME_RATE_CATEGORY_DEFAULT),
                    eq(false));
            verify(mTransaction).setEarlyWakeupEnd();
            verify(mTransaction).applyAsyncUnsafe();
            verify(mAdpfSession).sendHint(eq(CPU_LOAD_RESET));
@@ -299,7 +305,8 @@ public class SystemPerformanceHinterTests {
                eq(FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN));
        verify(mTransaction).setFrameRateCategory(
                eq(mDefaultDisplayRoot),
                eq(FRAME_RATE_CATEGORY_HIGH));
                eq(FRAME_RATE_CATEGORY_HIGH),
                eq(false));
        verify(mTransaction).setEarlyWakeupStart();
        verify(mTransaction).applyAsyncUnsafe();
        verify(mAdpfSession).sendHint(eq(CPU_LOAD_UP));
@@ -310,7 +317,7 @@ public class SystemPerformanceHinterTests {
                mHinter.startSession(HINT_ALL, DEFAULT_DISPLAY_ID, TEST_OTHER_REASON);
        // Verify we never call SF and perf manager since session1 is already running
        verify(mTransaction, never()).setFrameRateSelectionStrategy(any(), anyInt());
        verify(mTransaction, never()).setFrameRateCategory(any(), anyInt());
        verify(mTransaction, never()).setFrameRateCategory(any(), anyInt(), anyBoolean());
        verify(mTransaction, never()).setEarlyWakeupEnd();
        verify(mTransaction, never()).applyAsyncUnsafe();
        verify(mAdpfSession, never()).sendHint(anyInt());
@@ -318,7 +325,7 @@ public class SystemPerformanceHinterTests {
        session2.close();
        // Verify we have not cleaned up because session1 is still running
        verify(mTransaction, never()).setFrameRateSelectionStrategy(any(), anyInt());
        verify(mTransaction, never()).setFrameRateCategory(any(), anyInt());
        verify(mTransaction, never()).setFrameRateCategory(any(), anyInt(), anyBoolean());
        verify(mTransaction, never()).setEarlyWakeupEnd();
        verify(mTransaction, never()).applyAsyncUnsafe();
        verify(mAdpfSession, never()).sendHint(anyInt());
@@ -330,7 +337,8 @@ public class SystemPerformanceHinterTests {
                eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
        verify(mTransaction).setFrameRateCategory(
                eq(mDefaultDisplayRoot),
                eq(FRAME_RATE_CATEGORY_DEFAULT));
                eq(FRAME_RATE_CATEGORY_DEFAULT),
                eq(false));
        verify(mTransaction).setEarlyWakeupEnd();
        verify(mTransaction).applyAsyncUnsafe();
        verify(mAdpfSession).sendHint(eq(CPU_LOAD_RESET));
@@ -348,7 +356,8 @@ public class SystemPerformanceHinterTests {
                eq(FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN));
        verify(mTransaction).setFrameRateCategory(
                eq(mDefaultDisplayRoot),
                eq(FRAME_RATE_CATEGORY_HIGH));
                eq(FRAME_RATE_CATEGORY_HIGH),
                eq(false));
        verify(mTransaction).setEarlyWakeupStart();
        verify(mTransaction).applyAsyncUnsafe();
        verify(mAdpfSession).sendHint(eq(CPU_LOAD_UP));
@@ -363,7 +372,8 @@ public class SystemPerformanceHinterTests {
                eq(FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN));
        verify(mTransaction).setFrameRateCategory(
                eq(mSecondaryDisplayRoot),
                eq(FRAME_RATE_CATEGORY_HIGH));
                eq(FRAME_RATE_CATEGORY_HIGH),
                eq(false));
        verify(mTransaction, never()).setEarlyWakeupStart();
        verify(mTransaction).applyAsyncUnsafe();
        verify(mAdpfSession, never()).sendHint(anyInt());
@@ -378,13 +388,15 @@ public class SystemPerformanceHinterTests {
                eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
        verify(mTransaction).setFrameRateCategory(
                eq(mDefaultDisplayRoot),
                eq(FRAME_RATE_CATEGORY_DEFAULT));
                eq(FRAME_RATE_CATEGORY_DEFAULT),
                eq(false));
        verify(mTransaction, never()).setFrameRateSelectionStrategy(
                eq(mSecondaryDisplayRoot),
                anyInt());
        verify(mTransaction, never()).setFrameRateCategory(
                eq(mSecondaryDisplayRoot),
                anyInt());
                anyInt(),
                eq(false));
        verify(mTransaction, never()).setEarlyWakeupEnd();
        verify(mTransaction).applyAsyncUnsafe();
        verify(mAdpfSession, never()).sendHint(anyInt());
@@ -401,7 +413,8 @@ public class SystemPerformanceHinterTests {
                eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
        verify(mTransaction).setFrameRateCategory(
                eq(mSecondaryDisplayRoot),
                eq(FRAME_RATE_CATEGORY_DEFAULT));
                eq(FRAME_RATE_CATEGORY_DEFAULT),
                eq(false));
        verify(mTransaction).setEarlyWakeupEnd();
        verify(mTransaction).applyAsyncUnsafe();
        verify(mAdpfSession).sendHint(eq(CPU_LOAD_RESET));
+1 −1
Original line number Diff line number Diff line
@@ -247,7 +247,7 @@ public class GraphicsActivity extends Activity {

            int rc = 0;
            try (SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()) {
                transaction.setFrameRateCategory(mSurfaceControl, category);
                transaction.setFrameRateCategory(mSurfaceControl, category, false);
                transaction.apply();
            }
            return rc;