summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java15
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java43
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;