Loading services/core/java/com/android/server/display/DisplayManagerService.java +11 −4 Original line number Original line Diff line number Diff line Loading @@ -1181,7 +1181,10 @@ public final class DisplayManagerService extends SystemService { private DisplayInfo getDisplayInfoForFrameRateOverride(DisplayEventReceiver.FrameRateOverride[] private DisplayInfo getDisplayInfoForFrameRateOverride(DisplayEventReceiver.FrameRateOverride[] frameRateOverrides, DisplayInfo info, int callingUid) { frameRateOverrides, DisplayInfo info, int callingUid) { // Start with the display frame rate float frameRateHz = info.renderFrameRate; float frameRateHz = info.renderFrameRate; // If the app has a specific override, use that instead for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) { for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) { if (frameRateOverride.uid == callingUid) { if (frameRateOverride.uid == callingUid) { frameRateHz = frameRateOverride.frameRateHz; frameRateHz = frameRateOverride.frameRateHz; Loading @@ -1200,18 +1203,21 @@ public final class DisplayManagerService extends SystemService { DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE, callingUid); DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE, callingUid); // Override the refresh rate only if it is a divisor of the current // 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 // in RefreshRateSelector::getFrameRateDivisor Display.Mode currentMode = info.getMode(); Display.Mode currentMode = info.getMode(); float numPeriods = currentMode.getRefreshRate() / frameRateHz; float vsyncRate = currentMode.getVsyncRate(); float numPeriods = vsyncRate / frameRateHz; float numPeriodsRound = Math.round(numPeriods); float numPeriodsRound = Math.round(numPeriods); if (Math.abs(numPeriods - numPeriodsRound) > THRESHOLD_FOR_REFRESH_RATES_DIVISORS) { if (Math.abs(numPeriods - numPeriodsRound) > THRESHOLD_FOR_REFRESH_RATES_DIVISORS) { return info; return info; } } frameRateHz = currentMode.getRefreshRate() / numPeriodsRound; frameRateHz = vsyncRate / numPeriodsRound; DisplayInfo overriddenInfo = new DisplayInfo(); DisplayInfo overriddenInfo = new DisplayInfo(); overriddenInfo.copyFrom(info); overriddenInfo.copyFrom(info); // If there is a mode that matches the override, use that one for (Display.Mode mode : info.supportedModes) { for (Display.Mode mode : info.supportedModes) { if (!mode.equalsExceptRefreshRate(currentMode)) { if (!mode.equalsExceptRefreshRate(currentMode)) { continue; continue; Loading @@ -1231,8 +1237,9 @@ public final class DisplayManagerService extends SystemService { return overriddenInfo; return overriddenInfo; } } } } overriddenInfo.refreshRateOverride = frameRateHz; overriddenInfo.refreshRateOverride = frameRateHz; // Create a fake mode for app compat if (!displayModeReturnsPhysicalRefreshRate) { if (!displayModeReturnsPhysicalRefreshRate) { overriddenInfo.supportedModes = Arrays.copyOf(info.supportedModes, overriddenInfo.supportedModes = Arrays.copyOf(info.supportedModes, info.supportedModes.length + 1); info.supportedModes.length + 1); Loading services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java +41 −2 Original line number Original line Diff line number Diff line Loading @@ -2079,6 +2079,31 @@ public class DisplayManagerServiceTest { assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); } } /** * 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 * Tests that the mode reflects the render frame rate is in compat mode */ */ Loading Loading @@ -3348,13 +3373,26 @@ public class DisplayManagerServiceTest { } } private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, float[] refreshRates) { float[] refreshRates) { return createFakeDisplayDevice(displayManager, refreshRates, Display.TYPE_UNKNOWN); return createFakeDisplayDevice(displayManager, refreshRates, Display.TYPE_UNKNOWN); } } private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, float[] refreshRates, 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) { int displayType) { FakeDisplayDevice displayDevice = new FakeDisplayDevice(); FakeDisplayDevice displayDevice = new FakeDisplayDevice(); DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); Loading @@ -3363,7 +3401,8 @@ public class DisplayManagerServiceTest { displayDeviceInfo.supportedModes = new Display.Mode[refreshRates.length]; displayDeviceInfo.supportedModes = new Display.Mode[refreshRates.length]; for (int i = 0; i < refreshRates.length; i++) { for (int i = 0; i < refreshRates.length; i++) { displayDeviceInfo.supportedModes[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.modeId = 1; displayDeviceInfo.type = displayType; displayDeviceInfo.type = displayType; Loading Loading
services/core/java/com/android/server/display/DisplayManagerService.java +11 −4 Original line number Original line Diff line number Diff line Loading @@ -1181,7 +1181,10 @@ public final class DisplayManagerService extends SystemService { private DisplayInfo getDisplayInfoForFrameRateOverride(DisplayEventReceiver.FrameRateOverride[] private DisplayInfo getDisplayInfoForFrameRateOverride(DisplayEventReceiver.FrameRateOverride[] frameRateOverrides, DisplayInfo info, int callingUid) { frameRateOverrides, DisplayInfo info, int callingUid) { // Start with the display frame rate float frameRateHz = info.renderFrameRate; float frameRateHz = info.renderFrameRate; // If the app has a specific override, use that instead for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) { for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) { if (frameRateOverride.uid == callingUid) { if (frameRateOverride.uid == callingUid) { frameRateHz = frameRateOverride.frameRateHz; frameRateHz = frameRateOverride.frameRateHz; Loading @@ -1200,18 +1203,21 @@ public final class DisplayManagerService extends SystemService { DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE, callingUid); DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE, callingUid); // Override the refresh rate only if it is a divisor of the current // 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 // in RefreshRateSelector::getFrameRateDivisor Display.Mode currentMode = info.getMode(); Display.Mode currentMode = info.getMode(); float numPeriods = currentMode.getRefreshRate() / frameRateHz; float vsyncRate = currentMode.getVsyncRate(); float numPeriods = vsyncRate / frameRateHz; float numPeriodsRound = Math.round(numPeriods); float numPeriodsRound = Math.round(numPeriods); if (Math.abs(numPeriods - numPeriodsRound) > THRESHOLD_FOR_REFRESH_RATES_DIVISORS) { if (Math.abs(numPeriods - numPeriodsRound) > THRESHOLD_FOR_REFRESH_RATES_DIVISORS) { return info; return info; } } frameRateHz = currentMode.getRefreshRate() / numPeriodsRound; frameRateHz = vsyncRate / numPeriodsRound; DisplayInfo overriddenInfo = new DisplayInfo(); DisplayInfo overriddenInfo = new DisplayInfo(); overriddenInfo.copyFrom(info); overriddenInfo.copyFrom(info); // If there is a mode that matches the override, use that one for (Display.Mode mode : info.supportedModes) { for (Display.Mode mode : info.supportedModes) { if (!mode.equalsExceptRefreshRate(currentMode)) { if (!mode.equalsExceptRefreshRate(currentMode)) { continue; continue; Loading @@ -1231,8 +1237,9 @@ public final class DisplayManagerService extends SystemService { return overriddenInfo; return overriddenInfo; } } } } overriddenInfo.refreshRateOverride = frameRateHz; overriddenInfo.refreshRateOverride = frameRateHz; // Create a fake mode for app compat if (!displayModeReturnsPhysicalRefreshRate) { if (!displayModeReturnsPhysicalRefreshRate) { overriddenInfo.supportedModes = Arrays.copyOf(info.supportedModes, overriddenInfo.supportedModes = Arrays.copyOf(info.supportedModes, info.supportedModes.length + 1); info.supportedModes.length + 1); Loading
services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java +41 −2 Original line number Original line Diff line number Diff line Loading @@ -2079,6 +2079,31 @@ public class DisplayManagerServiceTest { assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); } } /** * 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 * Tests that the mode reflects the render frame rate is in compat mode */ */ Loading Loading @@ -3348,13 +3373,26 @@ public class DisplayManagerServiceTest { } } private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, float[] refreshRates) { float[] refreshRates) { return createFakeDisplayDevice(displayManager, refreshRates, Display.TYPE_UNKNOWN); return createFakeDisplayDevice(displayManager, refreshRates, Display.TYPE_UNKNOWN); } } private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, float[] refreshRates, 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) { int displayType) { FakeDisplayDevice displayDevice = new FakeDisplayDevice(); FakeDisplayDevice displayDevice = new FakeDisplayDevice(); DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); Loading @@ -3363,7 +3401,8 @@ public class DisplayManagerServiceTest { displayDeviceInfo.supportedModes = new Display.Mode[refreshRates.length]; displayDeviceInfo.supportedModes = new Display.Mode[refreshRates.length]; for (int i = 0; i < refreshRates.length; i++) { for (int i = 0; i < refreshRates.length; i++) { displayDeviceInfo.supportedModes[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.modeId = 1; displayDeviceInfo.type = displayType; displayDeviceInfo.type = displayType; Loading