summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/test-current.txt1
-rw-r--r--core/java/android/hardware/display/DisplayManager.java11
-rw-r--r--services/core/java/com/android/server/display/DisplayModeDirector.java26
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java65
5 files changed, 99 insertions, 12 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index e9f9136c768c..f0763950ba37 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1252,6 +1252,7 @@ package android.hardware.display {
method @RequiresPermission(android.Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS) public boolean shouldAlwaysRespectAppRequestedMode();
field public static final int SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS = 2; // 0x2
field public static final int SWITCHING_TYPE_NONE = 0; // 0x0
+ field public static final int SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY = 3; // 0x3
field public static final int SWITCHING_TYPE_WITHIN_GROUPS = 1; // 0x1
field public static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 512; // 0x200
}
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 831119040842..9b07d3a9f8fb 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -439,12 +439,13 @@ public final class DisplayManager {
SWITCHING_TYPE_NONE,
SWITCHING_TYPE_WITHIN_GROUPS,
SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS,
+ SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY,
})
@Retention(RetentionPolicy.SOURCE)
public @interface SwitchingType {}
/**
- * No mode switching will happen.
+ * No display mode switching will happen.
* @hide
*/
@TestApi
@@ -467,6 +468,13 @@ public final class DisplayManager {
public static final int SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS = 2;
/**
+ * Allow render frame rate switches, but not physical modes.
+ * @hide
+ */
+ @TestApi
+ public static final int SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY = 3;
+
+ /**
* @hide
*/
@LongDef(flag = true, prefix = {"EVENT_FLAG_"}, value = {
@@ -1308,6 +1316,7 @@ public final class DisplayManager {
switch (switchingType) {
case SWITCHING_TYPE_NONE:
return MATCH_CONTENT_FRAMERATE_NEVER;
+ case SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY:
case SWITCHING_TYPE_WITHIN_GROUPS:
return MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY;
case SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS:
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index aa9f2dc2d7cb..c3c7d0731ef2 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -526,22 +526,28 @@ public class DisplayModeDirector {
ranges, ranges);
}
- if (mModeSwitchingType == DisplayManager.SWITCHING_TYPE_NONE
- || primarySummary.disableRefreshRateSwitching) {
+ boolean modeSwitchingDisabled =
+ mModeSwitchingType == DisplayManager.SWITCHING_TYPE_NONE
+ || mModeSwitchingType
+ == DisplayManager.SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY;
+
+ if (modeSwitchingDisabled || primarySummary.disableRefreshRateSwitching) {
float fps = baseMode.getRefreshRate();
primarySummary.minPhysicalRefreshRate = primarySummary.maxPhysicalRefreshRate = fps;
- if (mRenderFrameRateIsPhysicalRefreshRate) {
- primarySummary.minRenderFrameRate = primarySummary.maxRenderFrameRate = fps;
- }
- if (mModeSwitchingType == DisplayManager.SWITCHING_TYPE_NONE) {
- primarySummary.minRenderFrameRate = primarySummary.maxRenderFrameRate = fps;
+ if (modeSwitchingDisabled) {
appRequestSummary.minPhysicalRefreshRate =
appRequestSummary.maxPhysicalRefreshRate = fps;
- appRequestSummary.minRenderFrameRate =
- appRequestSummary.maxRenderFrameRate = fps;
}
}
+ if (mModeSwitchingType == DisplayManager.SWITCHING_TYPE_NONE
+ || mRenderFrameRateIsPhysicalRefreshRate) {
+ primarySummary.minRenderFrameRate = primarySummary.minPhysicalRefreshRate;
+ primarySummary.maxRenderFrameRate = primarySummary.maxPhysicalRefreshRate;
+ appRequestSummary.minRenderFrameRate = appRequestSummary.minPhysicalRefreshRate;
+ appRequestSummary.maxRenderFrameRate = appRequestSummary.maxPhysicalRefreshRate;
+ }
+
boolean allowGroupSwitching =
mModeSwitchingType == DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS;
@@ -842,6 +848,8 @@ public class DisplayModeDirector {
return "SWITCHING_TYPE_WITHIN_GROUPS";
case DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS:
return "SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS";
+ case DisplayManager.SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY:
+ return "SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY";
default:
return "Unknown SwitchingType " + type;
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f30c4355306c..8d1c40a08942 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -25,6 +25,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.graphics.GraphicsProtos.dumpPointProto;
import static android.hardware.display.DisplayManager.SWITCHING_TYPE_NONE;
+import static android.hardware.display.DisplayManager.SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import static android.os.PowerManager.DRAW_WAKE_LOCK;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
@@ -201,6 +202,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.gui.TouchOcclusionMode;
+import android.hardware.display.DisplayManager;
import android.os.Binder;
import android.os.Build;
import android.os.Debug;
@@ -5475,8 +5477,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// If refresh rate switching is disabled there is no point to set the frame rate on the
// surface as the refresh rate will be limited by display manager to a single value
// and SurfaceFlinger wouldn't be able to change it anyways.
- if (mWmService.mDisplayManagerInternal.getRefreshRateSwitchingType()
- != SWITCHING_TYPE_NONE) {
+ @DisplayManager.SwitchingType int refreshRateSwitchingType =
+ mWmService.mDisplayManagerInternal.getRefreshRateSwitchingType();
+ if (refreshRateSwitchingType != SWITCHING_TYPE_NONE
+ && refreshRateSwitchingType != SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY) {
final float refreshRate = refreshRatePolicy.getPreferredRefreshRate(this);
if (mAppPreferredFrameRate != refreshRate) {
mAppPreferredFrameRate = refreshRate;
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 2b069e354795..5939114c45d5 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -795,6 +795,71 @@ public class DisplayModeDirectorTest {
}
@Test
+ @Parameters({
+ "true",
+ "false"
+ })
+ public void testVotingWithSwitchingTypeRenderFrameRateOnly(boolean frameRateIsRefreshRate) {
+ when(mInjector.renderFrameRateIsPhysicalRefreshRate()).thenReturn(frameRateIsRefreshRate);
+ DisplayModeDirector director = createDirectorFromFpsRange(0, 90);
+ 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_NONE);
+ DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
+
+ assertThat(desiredSpecs.primary.physical.min).isWithin(FLOAT_TOLERANCE).of(30);
+ if (frameRateIsRefreshRate) {
+ assertThat(desiredSpecs.primary.physical.max).isWithin(FLOAT_TOLERANCE).of(60);
+ } else {
+ 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);
+ if (frameRateIsRefreshRate) {
+ assertThat(desiredSpecs.appRequest.physical.max).isWithin(FLOAT_TOLERANCE).of(
+ 60);
+ } else {
+ 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(30);
+
+ 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(30);
+ assertThat(desiredSpecs.primary.physical.max).isWithin(FLOAT_TOLERANCE).of(30);
+ assertThat(desiredSpecs.primary.render.min).isWithin(FLOAT_TOLERANCE).of(30);
+ if (frameRateIsRefreshRate) {
+ assertThat(desiredSpecs.primary.render.max).isWithin(FLOAT_TOLERANCE).of(30);
+ } else {
+ assertThat(desiredSpecs.primary.render.max).isWithin(FLOAT_TOLERANCE).of(60);
+ }
+ assertThat(desiredSpecs.appRequest.physical.min).isWithin(FLOAT_TOLERANCE).of(30);
+ assertThat(desiredSpecs.appRequest.physical.max).isWithin(FLOAT_TOLERANCE).of(30);
+ if (frameRateIsRefreshRate) {
+ assertThat(desiredSpecs.appRequest.render.min).isWithin(FLOAT_TOLERANCE).of(30);
+ assertThat(desiredSpecs.appRequest.render.max).isWithin(FLOAT_TOLERANCE).of(30);
+ } else {
+ assertThat(desiredSpecs.appRequest.render.min).isWithin(FLOAT_TOLERANCE).of(0);
+ assertThat(desiredSpecs.appRequest.render.max).isWithin(FLOAT_TOLERANCE).of(60);
+ }
+
+ assertThat(desiredSpecs.baseModeId).isEqualTo(30);
+ }
+
+ @Test
public void testVotingWithSwitchingTypeWithinGroups() {
DisplayModeDirector director = createDirectorFromFpsRange(0, 90);