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

Commit a1312ec4 authored by Ady Abraham's avatar Ady Abraham
Browse files

DisplayModeDirector: fix a bug with DesiredDisplayModeSpecs when switching is disabled

This CL dixes a bug that left DesiredDisplayModeSpecs inconsistent
when switching was disabled.

Bug: 267008497
Test: atest FrameRateOverrideHostTest
Test: atest DisplayModeDirectorTest
Change-Id: I8277991b3adc9d686ba7c3c393162993e0e42a68
parent 40986e3d
Loading
Loading
Loading
Loading
+24 −17
Original line number Diff line number Diff line
@@ -373,9 +373,13 @@ public class DisplayModeDirector {
        }
    }

    private void disableRenderRateSwitching(VoteSummary summary) {
    private void disableRenderRateSwitching(VoteSummary summary, float fps) {
        summary.minRenderFrameRate = summary.maxRenderFrameRate;

        if (!isRenderRateAchievable(fps, summary)) {
            summary.minRenderFrameRate = summary.maxRenderFrameRate = fps;
        }

        if (mLoggingEnabled) {
            Slog.i(TAG, "Disabled render rate switching on summary: " + summary);
        }
@@ -540,10 +544,10 @@ public class DisplayModeDirector {
                disableModeSwitching(primarySummary, fps);
                if (modeSwitchingDisabled) {
                    disableModeSwitching(appRequestSummary, fps);
                    disableRenderRateSwitching(primarySummary);
                    disableRenderRateSwitching(primarySummary, fps);

                    if (mModeSwitchingType == DisplayManager.SWITCHING_TYPE_NONE) {
                        disableRenderRateSwitching(appRequestSummary);
                        disableRenderRateSwitching(appRequestSummary, fps);
                    }
                }
            }
@@ -570,6 +574,22 @@ public class DisplayModeDirector {
        }
    }

    private boolean isRenderRateAchievable(float physicalRefreshRate, VoteSummary summary) {
        // Check whether the render frame rate range is achievable by the mode's physical
        // refresh rate, meaning that if a divisor of the physical refresh rate is in range
        // of the render frame rate.
        // For example for the render frame rate [50, 70]:
        //   - 120Hz is in range as we can render at 60hz by skipping every other frame,
        //     which is within the render rate range
        //   - 90hz is not in range as none of the even divisors (i.e. 90, 45, 30)
        //     fall within the acceptable render range.
        final int divisor =
                (int) Math.ceil((physicalRefreshRate / summary.maxRenderFrameRate)
                        - FLOAT_TOLERANCE);
        float adjustedPhysicalRefreshRate = physicalRefreshRate / divisor;
        return adjustedPhysicalRefreshRate >= (summary.minRenderFrameRate - FLOAT_TOLERANCE);
    }

    private ArrayList<Display.Mode> filterModes(Display.Mode[] supportedModes,
            VoteSummary summary) {
        if (summary.minRenderFrameRate > summary.maxRenderFrameRate + FLOAT_TOLERANCE) {
@@ -627,22 +647,9 @@ public class DisplayModeDirector {
                }
            }

            // Check whether the render frame rate range is achievable by the mode's physical
            // refresh rate, meaning that if a divisor of the physical refresh rate is in range
            // of the render frame rate.
            // For example for the render frame rate [50, 70]:
            //   - 120Hz is in range as we can render at 60hz by skipping every other frame,
            //     which is within the render rate range
            //   - 90hz is not in range as none of the even divisors (i.e. 90, 45, 30)
            //     fall within the acceptable render range.
            final int divisor =
                    (int) Math.ceil((physicalRefreshRate / summary.maxRenderFrameRate)
                            - FLOAT_TOLERANCE);
            float adjustedPhysicalRefreshRate = physicalRefreshRate / divisor;
            if (adjustedPhysicalRefreshRate < (summary.minRenderFrameRate - FLOAT_TOLERANCE)) {
            if (!isRenderRateAchievable(physicalRefreshRate, summary)) {
                if (mLoggingEnabled) {
                    Slog.w(TAG, "Discarding mode " + mode.getModeId()
                            + " with adjusted refresh rate: " + adjustedPhysicalRefreshRate
                            + ", outside frame rate bounds"
                            + ": minRenderFrameRate=" + summary.minRenderFrameRate
                            + ", maxRenderFrameRate=" + summary.maxRenderFrameRate
+32 −7
Original line number Diff line number Diff line
@@ -754,7 +754,7 @@ public class DisplayModeDirectorTest {

    @Test
    public void testVotingWithSwitchingTypeRenderFrameRateOnlyRenderRateIsNotPhysicalRefreshRate() {
        DisplayModeDirector director = createDirectorFromFpsRange(90, 120);
        DisplayModeDirector director = createDirectorFromFpsRange(60, 120);
        SparseArray<Vote> votes = new SparseArray<>();
        SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
        votesByDisplay.put(DISPLAY_ID, votes);
@@ -775,23 +775,23 @@ public class DisplayModeDirectorTest {
        assertThat(desiredSpecs.appRequest.physical.max).isPositiveInfinity();
        assertThat(desiredSpecs.appRequest.render.min).isWithin(FLOAT_TOLERANCE).of(0);
        assertThat(desiredSpecs.appRequest.render.max).isWithin(FLOAT_TOLERANCE).of(60);
        assertThat(desiredSpecs.baseModeId).isEqualTo(90);
        assertThat(desiredSpecs.baseModeId).isEqualTo(60);

        director.setModeSwitchingType(DisplayManager.SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY);
        assertThat(director.getModeSwitchingType())
                .isEqualTo(DisplayManager.SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY);

        desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
        assertThat(desiredSpecs.primary.physical.min).isWithin(FLOAT_TOLERANCE).of(90);
        assertThat(desiredSpecs.primary.physical.max).isWithin(FLOAT_TOLERANCE).of(90);
        assertThat(desiredSpecs.primary.physical.min).isWithin(FLOAT_TOLERANCE).of(60);
        assertThat(desiredSpecs.primary.physical.max).isWithin(FLOAT_TOLERANCE).of(60);
        assertThat(desiredSpecs.primary.render.min).isWithin(FLOAT_TOLERANCE).of(60);
        assertThat(desiredSpecs.primary.render.max).isWithin(FLOAT_TOLERANCE).of(60);
        assertThat(desiredSpecs.appRequest.physical.min).isWithin(FLOAT_TOLERANCE).of(90);
        assertThat(desiredSpecs.appRequest.physical.max).isWithin(FLOAT_TOLERANCE).of(90);
        assertThat(desiredSpecs.appRequest.physical.min).isWithin(FLOAT_TOLERANCE).of(60);
        assertThat(desiredSpecs.appRequest.physical.max).isWithin(FLOAT_TOLERANCE).of(60);
        assertThat(desiredSpecs.appRequest.render.min).isWithin(FLOAT_TOLERANCE).of(0);
        assertThat(desiredSpecs.appRequest.render.max).isWithin(FLOAT_TOLERANCE).of(60);

        assertThat(desiredSpecs.baseModeId).isEqualTo(90);
        assertThat(desiredSpecs.baseModeId).isEqualTo(60);
    }

    @Test
@@ -1731,6 +1731,31 @@ public class DisplayModeDirectorTest {
        assertThat(desiredSpecs.baseModeId).isEqualTo(90);
    }

    @Test
    public void testRenderFrameRateIsAchievableWhenSwitchingTypeNone() {
        Display.Mode[] modes = new Display.Mode[2];
        modes[0] = new Display.Mode(
                /*modeId=*/60, /*width=*/1000, /*height=*/1000, 60);
        modes[1] = new Display.Mode(
                /*modeId=*/90, /*width=*/1000, /*height=*/1000, 90);

        DisplayModeDirector director = createDirectorFromModeArray(modes, modes[1]);
        director.setModeSwitchingType(DisplayManager.SWITCHING_TYPE_NONE);

        SparseArray<Vote> votes = new SparseArray<>();
        SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
        votesByDisplay.put(DISPLAY_ID, votes);
        votes.put(Vote.PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE,
                Vote.forRenderFrameRates(0, 60));
        director.injectVotesByDisplay(votesByDisplay);
        DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
        assertThat(desiredSpecs.primary.physical.min).isWithin(FLOAT_TOLERANCE).of(90);
        assertThat(desiredSpecs.primary.physical.max).isWithin(FLOAT_TOLERANCE).of(90);
        assertThat(desiredSpecs.primary.render.min).isWithin(FLOAT_TOLERANCE).of(90);
        assertThat(desiredSpecs.primary.render.max).isWithin(FLOAT_TOLERANCE).of(90);
        assertThat(desiredSpecs.baseModeId).isEqualTo(90);
    }

    @Test
    public void testProximitySensorVoting() {
        DisplayModeDirector director =