diff options
| -rw-r--r-- | services/core/java/com/android/server/display/mode/DisplayModeDirector.java | 14 | ||||
| -rw-r--r-- | services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java | 31 |
2 files changed, 44 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java index 8707000ce962..82461fa647b3 100644 --- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java @@ -388,6 +388,14 @@ public class DisplayModeDirector { boolean allowGroupSwitching = mModeSwitchingType == DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS; + // Some external displays physical refresh rate modes are slightly above 60hz. + // SurfaceFlinger will not enable these display modes unless it is configured to allow + // render rate at least at this frame rate. + if (mDisplayObserver.isExternalDisplayLocked(displayId)) { + primarySummary.maxRenderFrameRate = Math.max(baseMode.getRefreshRate(), + primarySummary.maxRenderFrameRate); + } + return new DesiredDisplayModeSpecs(baseMode.getModeId(), allowGroupSwitching, new RefreshRateRanges( @@ -1311,6 +1319,10 @@ public class DisplayModeDirector { updateUserSettingDisplayPreferredSize(displayInfo); } + boolean isExternalDisplayLocked(int displayId) { + return mExternalDisplaysConnected.contains(displayId); + } + @Nullable private DisplayInfo getDisplayInfo(int displayId) { DisplayInfo info = new DisplayInfo(); @@ -1419,7 +1431,7 @@ public class DisplayModeDirector { return; } synchronized (mLock) { - if (!mExternalDisplaysConnected.contains(displayId)) { + if (!isExternalDisplayLocked(displayId)) { return; } mExternalDisplaysConnected.remove(displayId); diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java index dd8c6a23b829..c556aca1313a 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java @@ -1699,6 +1699,37 @@ public class DisplayModeDirectorTest { } @Test + @Parameters({ + "true, true, 60", + "false, true, 50", + "true, false, 50" + }) + public void testExternalDisplayMaxRefreshRate(boolean isRefreshRateSynchronizationEnabled, + boolean isExternalDisplay, float expectedMaxRenderFrameRate) { + when(mDisplayManagerFlags.isDisplaysRefreshRatesSynchronizationEnabled()) + .thenReturn(isRefreshRateSynchronizationEnabled); + when(mResources.getBoolean(R.bool.config_refreshRateSynchronizationEnabled)) + .thenReturn(isRefreshRateSynchronizationEnabled); + mInjector.mDisplayInfo.type = + isExternalDisplay ? Display.TYPE_EXTERNAL : Display.TYPE_INTERNAL; + mInjector.mDisplayInfo.displayId = DISPLAY_ID_2; + + DisplayModeDirector director = createDirectorFromModeArray(TEST_MODES, DEFAULT_MODE_60); + + SparseArray<Vote> votes = new SparseArray<>(); + votes.put(Vote.PRIORITY_LOW_POWER_MODE, Vote.forRenderFrameRates(0, 50f)); + + SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>(); + votesByDisplay.put(DISPLAY_ID_2, votes); + + director.getDisplayObserver().onDisplayAdded(DISPLAY_ID_2); + director.injectVotesByDisplay(votesByDisplay); + + var desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID_2); + assertThat(desiredSpecs.primary.render.max).isEqualTo(expectedMaxRenderFrameRate); + } + + @Test public void testMinRefreshRate_FlagEnabled() { when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled()) .thenReturn(true); |