diff options
-rw-r--r-- | services/core/java/com/android/server/display/DisplayModeDirector.java | 41 | ||||
-rw-r--r-- | services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java | 39 |
2 files changed, 56 insertions, 24 deletions
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index dece0507f02c..0536ce893ad9 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -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 diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java index 3a3a5078aac7..a35f4eab1772 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java @@ -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 @@ -1732,6 +1732,31 @@ public class DisplayModeDirectorTest { } @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 = createDirectorFromRefreshRateArray(new float[]{60.f, 90.f}, 0); |