diff options
5 files changed, 74 insertions, 19 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index df51734bc17d..a9b95fce8777 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -94,6 +94,7 @@ public final class DisplayManagerGlobal { // Guarded by mLock private boolean mDispatchNativeCallbacks = false; + private float mNativeCallbackReportedRefreshRate; private final Object mLock = new Object(); @UnsupportedAppUsage @@ -404,10 +405,11 @@ public final class DisplayManagerGlobal { // We can likely save a binder hop if we attach the refresh rate onto the // listener. DisplayInfo display = getDisplayInfoLocked(displayId); - if (display != null) { - float refreshRate = display.getRefreshRate(); + if (display != null + && mNativeCallbackReportedRefreshRate != display.getRefreshRate()) { + mNativeCallbackReportedRefreshRate = display.getRefreshRate(); // Signal native callbacks if we ever set a refresh rate. - nSignalNativeCallbacks(refreshRate); + nSignalNativeCallbacks(mNativeCallbackReportedRefreshRate); } } } @@ -1055,8 +1057,8 @@ public final class DisplayManagerGlobal { if (display != null) { // We need to tell AChoreographer instances the current refresh rate so that apps // can get it for free once a callback first registers. - float refreshRate = display.getRefreshRate(); - nSignalNativeCallbacks(refreshRate); + mNativeCallbackReportedRefreshRate = display.getRefreshRate(); + nSignalNativeCallbacks(mNativeCallbackReportedRefreshRate); } } } diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index dce3fefff285..c739c6a53167 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -287,6 +287,12 @@ public abstract class DisplayManagerInternal { public abstract void ignoreProximitySensorUntilChanged(); /** + * Returns the refresh rate switching type. + */ + @DisplayManager.SwitchingType + public abstract int getRefreshRateSwitchingType(); + + /** * Describes the requested power state of the display. * * This object is intended to describe the general characteristics of the diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index d4920f56a27e..13b7ebc47301 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -3250,6 +3250,11 @@ public final class DisplayManagerService extends SystemService { mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) .ignoreProximitySensorUntilChanged(); } + + @Override + public int getRefreshRateSwitchingType() { + return getRefreshRateSwitchingTypeInternal(); + } } class DesiredDisplayModeSpecsObserver diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 299cde8ad1d8..03762b3ee8bf 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.app.WindowConfiguration.isSplitScreenWindowingMode; 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.input.InputManager.BLOCK_UNTRUSTED_TOUCHES; import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS; import static android.os.PowerManager.DRAW_WAKE_LOCK; @@ -5448,12 +5449,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mFrameRateSelectionPriority); } - final float refreshRate = refreshRatePolicy.getPreferredRefreshRate(this); - if (mAppPreferredFrameRate != refreshRate) { - mAppPreferredFrameRate = refreshRate; - getPendingTransaction().setFrameRate( - mSurfaceControl, mAppPreferredFrameRate, - Surface.FRAME_RATE_COMPATIBILITY_EXACT, Surface.CHANGE_FRAME_RATE_ALWAYS); + // 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) { + final float refreshRate = refreshRatePolicy.getPreferredRefreshRate(this); + if (mAppPreferredFrameRate != refreshRate) { + mAppPreferredFrameRate = refreshRate; + getPendingTransaction().setFrameRate( + mSurfaceControl, mAppPreferredFrameRate, + Surface.FRAME_RATE_COMPATIBILITY_EXACT, Surface.CHANGE_FRAME_RATE_ALWAYS); + } } } diff --git a/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java b/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java index 1ee646c57b14..e6348a50566c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java @@ -29,6 +29,7 @@ import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import android.hardware.display.DisplayManager; import android.platform.test.annotations.Presubmit; import android.view.Display.Mode; import android.view.DisplayInfo; @@ -56,6 +57,13 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { private RefreshRatePolicy mRefreshRatePolicy; private HighRefreshRateDenylist mDenylist = mock(HighRefreshRateDenylist.class); + WindowState createWindow(String name) { + WindowState window = createWindow(null, TYPE_APPLICATION, name); + when(window.mWmService.mDisplayManagerInternal.getRefreshRateSwitchingType()) + .thenReturn(DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS); + return window; + } + @Before public void setUp() { DisplayInfo di = new DisplayInfo(mDisplayInfo); @@ -73,7 +81,7 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { @Test public void basicTest() { - final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); + final WindowState appWindow = createWindow("appWindow"); assertNotNull("Window state is created", appWindow); assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); @@ -97,7 +105,7 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { @Test public void testApplicationInFocusWithoutModeId() { - final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); + final WindowState appWindow = createWindow("appWindow"); assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); assertEquals(appWindow.getDisplayContent().getDisplayPolicy().getRefreshRatePolicy() .getPreferredModeId(appWindow), 0); @@ -128,7 +136,7 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { @Test public void testApplicationInFocusWithModeId() { - final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); + final WindowState appWindow = createWindow("appWindow"); assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); assertEquals(appWindow.mAppPreferredFrameRate, 0, FLOAT_TOLERANCE); @@ -165,11 +173,11 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { @Test public void testApplicationNotInFocusWithModeId() { - final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); + final WindowState appWindow = createWindow("appWindow"); assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); assertEquals(appWindow.mAppPreferredFrameRate, 0, FLOAT_TOLERANCE); - final WindowState inFocusWindow = createWindow(null, TYPE_APPLICATION, "inFocus"); + final WindowState inFocusWindow = createWindow("inFocus"); appWindow.mToken.mDisplayContent.mCurrentFocus = inFocusWindow; appWindow.updateFrameRateSelectionPriorityIfNeeded(); @@ -194,11 +202,11 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { @Test public void testApplicationNotInFocusWithoutModeId() { - final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); + final WindowState appWindow = createWindow("appWindow"); assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); assertEquals(appWindow.mAppPreferredFrameRate, 0, FLOAT_TOLERANCE); - final WindowState inFocusWindow = createWindow(null, TYPE_APPLICATION, "inFocus"); + final WindowState inFocusWindow = createWindow("inFocus"); appWindow.mToken.mDisplayContent.mCurrentFocus = inFocusWindow; appWindow.updateFrameRateSelectionPriorityIfNeeded(); @@ -221,7 +229,7 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { @Test public void testPreferredRefreshRate() { - final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); + final WindowState appWindow = createWindow("appWindow"); assertNotNull("Window state is created", appWindow); when(appWindow.getDisplayContent().getDisplayPolicy()).thenReturn(mDisplayPolicy); @@ -246,4 +254,31 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase { appWindow.getSurfaceControl(), 60, Surface.FRAME_RATE_COMPATIBILITY_EXACT, Surface.CHANGE_FRAME_RATE_ALWAYS); } + + @Test + public void testSwitchingTypeNone() { + final WindowState appWindow = createWindow("appWindow"); + when(appWindow.mWmService.mDisplayManagerInternal.getRefreshRateSwitchingType()) + .thenReturn(DisplayManager.SWITCHING_TYPE_NONE); + + assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET); + assertEquals(appWindow.mAppPreferredFrameRate, 0, FLOAT_TOLERANCE); + + // Update the mode ID to a requested number. + appWindow.mAttrs.preferredDisplayModeId = 1; + appWindow.updateFrameRateSelectionPriorityIfNeeded(); + + assertEquals(appWindow.mAppPreferredFrameRate, 0, FLOAT_TOLERANCE); + + // Remove the mode ID request. + appWindow.mAttrs.preferredDisplayModeId = 0; + appWindow.updateFrameRateSelectionPriorityIfNeeded(); + + assertEquals(appWindow.mAppPreferredFrameRate, 0, FLOAT_TOLERANCE); + + verify(appWindow.getPendingTransaction()).setFrameRateSelectionPriority( + appWindow.getSurfaceControl(), RefreshRatePolicy.LAYER_PRIORITY_UNSET); + verify(appWindow.getPendingTransaction(), never()).setFrameRate( + any(SurfaceControl.class), anyInt(), anyInt(), anyInt()); + } } |