diff options
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 726326f33b92..a5e5c246b4d9 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 0168d503d133..369f1ed775fe 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 1fe267f65617..9e61cab93eff 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); |