summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/display/mode/DisplayModeDirector.java14
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java31
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);