Loading services/core/java/com/android/server/display/DisplayModeDirector.java +24 −17 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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); } } } Loading @@ -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) { Loading Loading @@ -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 Loading services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +32 −7 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 Loading Loading @@ -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 = Loading Loading
services/core/java/com/android/server/display/DisplayModeDirector.java +24 −17 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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); } } } Loading @@ -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) { Loading Loading @@ -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 Loading
services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +32 −7 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 Loading Loading @@ -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 = Loading