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

Commit 287fb6de authored by Ady Abraham's avatar Ady Abraham
Browse files

Fix bugs with SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY

 * The maximal render frame rate cannot be higher than the maximal
   physical refresh rate, as it is impossible to render faster than
   the display refreshes. This invariant is not kept when
   SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY is used.
 * The render frame rate range might not include the physical
   refresh rate of the mode id. When the render frame rate switching
   is disabled, it should be just limited to the max render frame rate
   instead.

Test: atest DisplayModeDirectorTest
Bug: 260874985
Change-Id: Ie854922d54676628035853369b1674771813dade
parent 9e39ea7c
Loading
Loading
Loading
Loading
+39 −23
Original line number Diff line number Diff line
@@ -263,6 +263,18 @@ public class DisplayModeDirector {
            disableRefreshRateSwitching = false;
            appRequestBaseModeRefreshRate = 0f;
        }

        @Override
        public String toString() {
            return  "minPhysicalRefreshRate=" + minPhysicalRefreshRate
                    + ", maxPhysicalRefreshRate=" + maxPhysicalRefreshRate
                    + ", minRenderFrameRate=" + minRenderFrameRate
                    + ", maxRenderFrameRate=" + maxRenderFrameRate
                    + ", width=" + width
                    + ", height=" + height
                    + ", disableRefreshRateSwitching=" + disableRefreshRateSwitching
                    + ", appRequestBaseModeRefreshRate=" + appRequestBaseModeRefreshRate;
        }
    }

    // VoteSummary is returned as an output param to cut down a bit on the number of temporary
@@ -316,18 +328,8 @@ public class DisplayModeDirector {
            }

            if (mLoggingEnabled) {
                Slog.w(TAG, "Vote summary for priority "
                        + Vote.priorityToString(priority)
                        + ": width=" + summary.width
                        + ", height=" + summary.height
                        + ", minPhysicalRefreshRate=" + summary.minPhysicalRefreshRate
                        + ", maxPhysicalRefreshRate=" + summary.maxPhysicalRefreshRate
                        + ", minRenderFrameRate=" + summary.minRenderFrameRate
                        + ", maxRenderFrameRate=" + summary.maxRenderFrameRate
                        + ", disableRefreshRateSwitching="
                        + summary.disableRefreshRateSwitching
                        + ", appRequestBaseModeRefreshRate="
                        + summary.appRequestBaseModeRefreshRate);
                Slog.w(TAG, "Vote summary for priority " + Vote.priorityToString(priority)
                        + ": " + summary);
            }
        }
    }
@@ -361,6 +363,23 @@ public class DisplayModeDirector {
        return !availableModes.isEmpty() ? availableModes.get(0) : null;
    }

    private void disableModeSwitching(VoteSummary summary, float fps) {
        summary.minPhysicalRefreshRate = summary.maxPhysicalRefreshRate = fps;
        summary.maxRenderFrameRate = Math.min(summary.maxRenderFrameRate, fps);

        if (mLoggingEnabled) {
            Slog.i(TAG, "Disabled mode switching on summary: " + summary);
        }
    }

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

        if (mLoggingEnabled) {
            Slog.i(TAG, "Disabled render rate switching on summary: " + summary);
        }
    }

    /**
     * Calculates the refresh rate ranges and display modes that the system is allowed to freely
     * switch between based on global and display-specific constraints.
@@ -389,7 +408,7 @@ public class DisplayModeDirector {
            int highestConsideredPriority = Vote.MAX_PRIORITY;

            if (mAlwaysRespectAppRequest) {
                lowestConsideredPriority = Vote.PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE;
                lowestConsideredPriority = Vote.PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE;
                highestConsideredPriority = Vote.PRIORITY_APP_REQUEST_SIZE;
            }

@@ -517,18 +536,15 @@ public class DisplayModeDirector {

            if (modeSwitchingDisabled || primarySummary.disableRefreshRateSwitching) {
                float fps = baseMode.getRefreshRate();
                primarySummary.minPhysicalRefreshRate = primarySummary.maxPhysicalRefreshRate = fps;
                disableModeSwitching(primarySummary, fps);
                if (modeSwitchingDisabled) {
                    appRequestSummary.minPhysicalRefreshRate =
                            appRequestSummary.maxPhysicalRefreshRate = fps;
                }
            }
                    disableModeSwitching(appRequestSummary, fps);
                    disableRenderRateSwitching(primarySummary);

                    if (mModeSwitchingType == DisplayManager.SWITCHING_TYPE_NONE) {
                primarySummary.minRenderFrameRate = primarySummary.minPhysicalRefreshRate;
                primarySummary.maxRenderFrameRate = primarySummary.maxPhysicalRefreshRate;
                appRequestSummary.minRenderFrameRate = appRequestSummary.minPhysicalRefreshRate;
                appRequestSummary.maxRenderFrameRate = appRequestSummary.maxPhysicalRefreshRate;
                        disableRenderRateSwitching(appRequestSummary);
                    }
                }
            }

            boolean allowGroupSwitching =
+45 −3
Original line number Diff line number Diff line
@@ -707,7 +707,7 @@ public class DisplayModeDirectorTest {

        director.injectVotesByDisplay(votesByDisplay);
        assertThat(director.getModeSwitchingType())
                .isNotEqualTo(DisplayManager.SWITCHING_TYPE_NONE);
                .isNotEqualTo(DisplayManager.SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY);
        DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);

        assertThat(desiredSpecs.primary.physical.min).isWithin(FLOAT_TOLERANCE).of(30);
@@ -728,15 +728,57 @@ public class DisplayModeDirectorTest {
        assertThat(desiredSpecs.primary.physical.min).isWithin(FLOAT_TOLERANCE).of(30);
        assertThat(desiredSpecs.primary.physical.max).isWithin(FLOAT_TOLERANCE).of(30);
        assertThat(desiredSpecs.primary.render.min).isWithin(FLOAT_TOLERANCE).of(30);
        assertThat(desiredSpecs.primary.render.max).isWithin(FLOAT_TOLERANCE).of(60);
        assertThat(desiredSpecs.primary.render.max).isWithin(FLOAT_TOLERANCE).of(30);
        assertThat(desiredSpecs.appRequest.physical.min).isWithin(FLOAT_TOLERANCE).of(30);
        assertThat(desiredSpecs.appRequest.physical.max).isWithin(FLOAT_TOLERANCE).of(30);
        assertThat(desiredSpecs.appRequest.render.min).isWithin(FLOAT_TOLERANCE).of(0);
        assertThat(desiredSpecs.appRequest.render.max).isWithin(FLOAT_TOLERANCE).of(60);
        assertThat(desiredSpecs.appRequest.render.max).isWithin(FLOAT_TOLERANCE).of(30);

        assertThat(desiredSpecs.baseModeId).isEqualTo(30);
    }

    @Test
    public void testVotingWithSwitchingTypeRenderFrameRateOnlyRenderRateIsNotPhysicalRefreshRate() {
        DisplayModeDirector director = createDirectorFromFpsRange(90, 120);
        SparseArray<Vote> votes = new SparseArray<>();
        SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
        votesByDisplay.put(DISPLAY_ID, votes);
        votes.put(Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE,
                Vote.forRenderFrameRates(30, 90));
        votes.put(Vote.PRIORITY_LOW_POWER_MODE, Vote.forRenderFrameRates(0, 60));

        director.injectVotesByDisplay(votesByDisplay);
        assertThat(director.getModeSwitchingType())
                .isNotEqualTo(DisplayManager.SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY);
        DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);

        assertThat(desiredSpecs.primary.physical.min).isWithin(FLOAT_TOLERANCE).of(30);
        assertThat(desiredSpecs.primary.physical.max).isPositiveInfinity();
        assertThat(desiredSpecs.primary.render.min).isWithin(FLOAT_TOLERANCE).of(30);
        assertThat(desiredSpecs.primary.render.max).isWithin(FLOAT_TOLERANCE).of(60);
        assertThat(desiredSpecs.appRequest.physical.min).isWithin(FLOAT_TOLERANCE).of(0);
        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);

        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.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.render.min).isWithin(FLOAT_TOLERANCE).of(0);
        assertThat(desiredSpecs.appRequest.render.max).isWithin(FLOAT_TOLERANCE).of(60);

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

    @Test
    public void testVotingWithSwitchingTypeWithinGroups() {
        DisplayModeDirector director = createDirectorFromFpsRange(0, 90);