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

Commit d3757a2c authored by Rachel Lee's avatar Rachel Lee
Browse files

Add setFrameRate compatibility value "GTE"

Allows opinionated users to request a frame rate greater than or equal
to the frameRate value. This is also useful for toolkit scroll.

Bug: 306080972
Test: atest SetFrameRateTest
Test: atest CtsSurfaceControlTestsStaging
Change-Id: I72cf29e14b7b8ddc9b3dba4da4218b1dd90b3bba
parent e3be17ae
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -197,7 +197,9 @@ public class Surface implements Parcelable {
    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"FRAME_RATE_COMPATIBILITY_"},
            value = {FRAME_RATE_COMPATIBILITY_DEFAULT, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE})
            value = {FRAME_RATE_COMPATIBILITY_DEFAULT, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
                    FRAME_RATE_COMPATIBILITY_EXACT, FRAME_RATE_COMPATIBILITY_NO_VOTE,
                    FRAME_RATE_COMPATIBILITY_MIN, FRAME_RATE_COMPATIBILITY_GTE})
    public @interface FrameRateCompatibility {}

    // From native_window.h. Keep these in sync.
@@ -242,6 +244,13 @@ public class Surface implements Parcelable {
     */
    public static final int FRAME_RATE_COMPATIBILITY_MIN = 102;

    // From window.h. Keep these in sync.
    /**
     * The surface requests a frame rate that is greater than or equal to {@code frameRate}.
     * @hide
     */
    public static final int FRAME_RATE_COMPATIBILITY_GTE = 103;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"CHANGE_FRAME_RATE_"},
+51 −7
Original line number Diff line number Diff line
@@ -235,13 +235,17 @@ public class GraphicsActivity extends Activity {
        }

        public int setFrameRate(float frameRate) {
            return setFrameRate(frameRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT);
        }

        public int setFrameRate(
                float frameRate, @Surface.FrameRateCompatibility int compatibility) {
            Log.i(TAG,
                    String.format("Setting frame rate for %s: frameRate=%.2f", mName, frameRate));

            int rc = 0;
            try (SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()) {
                transaction.setFrameRate(
                        mSurfaceControl, frameRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT);
                transaction.setFrameRate(mSurfaceControl, frameRate, compatibility);
                transaction.apply();
            }
            return rc;
@@ -668,12 +672,34 @@ public class GraphicsActivity extends Activity {
        }
    }

    private void testSurfaceControlFrameRateCategoryInternal(int category)
            throws InterruptedException {
    private void testSurfaceControlFrameRateCompatibilityInternal(
            @Surface.FrameRateCompatibility int compatibility) throws InterruptedException {
        runOneSurfaceTest((TestSurface surface) -> {
            Log.i(TAG,
                    "**** Running testSurfaceControlFrameRateCompatibility with compatibility "
                            + compatibility);

            float expectedFrameRate = getExpectedFrameRateForCompatibility(compatibility);
            int initialNumEvents = mModeChangedEvents.size();
            surface.setFrameRate(30.f, compatibility);
            verifyExactAndStableFrameRate(expectedFrameRate, surface);
            verifyModeSwitchesDontChangeResolution(initialNumEvents, mModeChangedEvents.size());
        });
    }

    public void testSurfaceControlFrameRateCompatibility(
            @Surface.FrameRateCompatibility int compatibility) throws InterruptedException {
        runTestsWithPreconditions(
                () -> testSurfaceControlFrameRateCompatibilityInternal(compatibility),
                "frame rate compatibility=" + compatibility);
    }

    private void testSurfaceControlFrameRateCategoryInternal(
            @Surface.FrameRateCategory int category) throws InterruptedException {
        runOneSurfaceTest((TestSurface surface) -> {
            Log.i(TAG, "**** Running testSurfaceControlFrameRateCategory for category " + category);

            float expectedFrameRate = getExpectedFrameRate(category);
            float expectedFrameRate = getExpectedFrameRateForCategory(category);
            int initialNumEvents = mModeChangedEvents.size();
            surface.setFrameRateCategory(category);
            verifyCompatibleAndStableFrameRate(expectedFrameRate, surface);
@@ -681,7 +707,8 @@ public class GraphicsActivity extends Activity {
        });
    }

    public void testSurfaceControlFrameRateCategory(int category) throws InterruptedException {
    public void testSurfaceControlFrameRateCategory(@Surface.FrameRateCategory int category)
            throws InterruptedException {
        runTestsWithPreconditions(()
                -> testSurfaceControlFrameRateCategoryInternal(category),
                "frame rate category=" + category);
@@ -744,7 +771,24 @@ public class GraphicsActivity extends Activity {
                "frame rate strategy=" + parentStrategy);
    }

    private float getExpectedFrameRate(int category) {
    private float getExpectedFrameRateForCompatibility(int compatibility) {
        assumeTrue("**** testSurfaceControlFrameRateCompatibility SKIPPED for compatibility "
                        + compatibility,
                compatibility == Surface.FRAME_RATE_COMPATIBILITY_GTE);

        Display display = getDisplay();
        Optional<Float> expectedFrameRate = getRefreshRates(display.getMode(), display)
                                                    .stream()
                                                    .filter(rate -> rate >= 30.f)
                                                    .min(Comparator.naturalOrder());

        assumeTrue("**** testSurfaceControlFrameRateCompatibility SKIPPED because no refresh rate "
                        + "is >= 30",
                expectedFrameRate.isPresent());
        return expectedFrameRate.get();
    }

    private float getExpectedFrameRateForCategory(int category) {
        Display display = getDisplay();
        List<Float> frameRates = getRefreshRates(display.getMode(), display);

+6 −0
Original line number Diff line number Diff line
@@ -80,6 +80,12 @@ public class SurfaceControlTest {
                .dropShellPermissionIdentity();
    }

    @Test
    public void testSurfaceControlFrameRateCompatibilityGte() throws InterruptedException {
        GraphicsActivity activity = mActivityRule.getActivity();
        activity.testSurfaceControlFrameRateCompatibility(Surface.FRAME_RATE_COMPATIBILITY_GTE);
    }

    @Test
    public void testSurfaceControlFrameRateCategoryHigh() throws InterruptedException {
        GraphicsActivity activity = mActivityRule.getActivity();