diff options
| -rw-r--r-- | services/core/java/com/android/server/display/DisplayManagerService.java | 15 | ||||
| -rw-r--r-- | services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java | 43 |
2 files changed, 52 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 55a6ce7142f3..187caba4db03 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -1181,7 +1181,10 @@ public final class DisplayManagerService extends SystemService { private DisplayInfo getDisplayInfoForFrameRateOverride(DisplayEventReceiver.FrameRateOverride[] frameRateOverrides, DisplayInfo info, int callingUid) { + // Start with the display frame rate float frameRateHz = info.renderFrameRate; + + // If the app has a specific override, use that instead for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) { if (frameRateOverride.uid == callingUid) { frameRateHz = frameRateOverride.frameRateHz; @@ -1200,18 +1203,21 @@ public final class DisplayManagerService extends SystemService { DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE, callingUid); // Override the refresh rate only if it is a divisor of the current - // refresh rate. This calculation needs to be in sync with the native code + // vsync rate. This calculation needs to be in sync with the native code // in RefreshRateSelector::getFrameRateDivisor Display.Mode currentMode = info.getMode(); - float numPeriods = currentMode.getRefreshRate() / frameRateHz; + float vsyncRate = currentMode.getVsyncRate(); + float numPeriods = vsyncRate / frameRateHz; float numPeriodsRound = Math.round(numPeriods); if (Math.abs(numPeriods - numPeriodsRound) > THRESHOLD_FOR_REFRESH_RATES_DIVISORS) { return info; } - frameRateHz = currentMode.getRefreshRate() / numPeriodsRound; + frameRateHz = vsyncRate / numPeriodsRound; DisplayInfo overriddenInfo = new DisplayInfo(); overriddenInfo.copyFrom(info); + + // If there is a mode that matches the override, use that one for (Display.Mode mode : info.supportedModes) { if (!mode.equalsExceptRefreshRate(currentMode)) { continue; @@ -1231,8 +1237,9 @@ public final class DisplayManagerService extends SystemService { return overriddenInfo; } } - overriddenInfo.refreshRateOverride = frameRateHz; + + // Create a fake mode for app compat if (!displayModeReturnsPhysicalRefreshRate) { overriddenInfo.supportedModes = Arrays.copyOf(info.supportedModes, info.supportedModes.length + 1); diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java index bbf2ecbb9380..026fcc486a92 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -2080,6 +2080,31 @@ public class DisplayManagerServiceTest { } /** + * Tests that the DisplayInfo is updated correctly with a render frame rate even if it not + * a divisor of the peak refresh rate. + */ + @Test + public void testDisplayInfoRenderFrameRateNonPeakDivisor() { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, mShortMockedInjector); + DisplayManagerService.BinderService displayManagerBinderService = + displayManager.new BinderService(); + registerDefaultDisplays(displayManager); + displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); + + FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, + new float[]{120f}, new float[]{240f}); + int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, + displayDevice); + DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); + assertEquals(120f, displayInfo.getRefreshRate(), 0.01f); + + updateRenderFrameRate(displayManager, displayDevice, 80f); + displayInfo = displayManagerBinderService.getDisplayInfo(displayId); + assertEquals(80f, displayInfo.getRefreshRate(), 0.01f); + } + + /** * Tests that the mode reflects the render frame rate is in compat mode */ @Test @@ -3348,13 +3373,26 @@ public class DisplayManagerServiceTest { } private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, - float[] refreshRates) { return createFakeDisplayDevice(displayManager, refreshRates, Display.TYPE_UNKNOWN); } private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, float[] refreshRates, + float[] vsyncRates) { + return createFakeDisplayDevice(displayManager, refreshRates, vsyncRates, + Display.TYPE_UNKNOWN); + } + + private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, + float[] refreshRates, + int displayType) { + return createFakeDisplayDevice(displayManager, refreshRates, refreshRates, displayType); + } + + private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, + float[] refreshRates, + float[] vsyncRates, int displayType) { FakeDisplayDevice displayDevice = new FakeDisplayDevice(); DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); @@ -3363,7 +3401,8 @@ public class DisplayManagerServiceTest { displayDeviceInfo.supportedModes = new Display.Mode[refreshRates.length]; for (int i = 0; i < refreshRates.length; i++) { displayDeviceInfo.supportedModes[i] = - new Display.Mode(i + 1, width, height, refreshRates[i]); + new Display.Mode(i + 1, width, height, refreshRates[i], vsyncRates[i], + new float[0], new int[0]); } displayDeviceInfo.modeId = 1; displayDeviceInfo.type = displayType; |