summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Wright <michaelwr@google.com>2014-07-22 19:46:03 -0700
committerMichael Wright <michaelwr@google.com>2014-08-06 02:03:49 +0000
commit3f145a2f958320766ae9240c7a57debc20d578aa (patch)
treeccf987da849c0008a75c4dd8923cda8e631f75f6
parent06c41a3e7ffd26894b6df3a0e4bfcfa47c48c739 (diff)
downloadframeworks_base-3f145a2f958320766ae9240c7a57debc20d578aa.zip
frameworks_base-3f145a2f958320766ae9240c7a57debc20d578aa.tar.gz
frameworks_base-3f145a2f958320766ae9240c7a57debc20d578aa.tar.bz2
Add supported refresh rate to displays
Change-Id: I51231dd6dd231d57dd1ac499349d6335121f07d5
-rw-r--r--api/current.txt2
-rw-r--r--core/java/android/hardware/display/DisplayManagerInternal.java19
-rw-r--r--core/java/android/view/Display.java13
-rw-r--r--core/java/android/view/DisplayInfo.java16
-rw-r--r--core/java/android/view/WindowManager.java23
-rw-r--r--services/core/java/com/android/server/display/DisplayDevice.java6
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceInfo.java15
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java22
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java71
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplay.java26
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java11
11 files changed, 202 insertions, 22 deletions
diff --git a/api/current.txt b/api/current.txt
index 7438d18..ea69ebc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -33013,6 +33013,7 @@ package android.view {
method public int getRotation();
method public void getSize(android.graphics.Point);
method public int getState();
+ method public float[] getSupportedRefreshRates();
method public deprecated int getWidth();
method public boolean isValid();
field public static final int DEFAULT_DISPLAY = 0; // 0x0
@@ -35656,6 +35657,7 @@ package android.view {
field public float horizontalWeight;
field public deprecated int memoryType;
field public java.lang.String packageName;
+ field public float preferredRefreshRate;
field public int rotationAnimation;
field public float screenBrightness;
field public int screenOrientation;
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 99af2e7..8447dde 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -106,21 +106,30 @@ public abstract class DisplayManagerInternal {
public abstract void performTraversalInTransactionFromWindowManager();
/**
- * Tells the display manager whether there is interesting unique content on the
- * specified logical display. This is used to control automatic mirroring.
+ * Tells the display manager about properties of the display that depend on the windows on it.
+ * This includes whether there is interesting unique content on the specified logical display,
+ * and whether the one of the windows has a preferred refresh rate.
* <p>
* If the display has unique content, then the display manager arranges for it
* to be presented on a physical display if appropriate. Otherwise, the display manager
* may choose to make the physical display mirror some other logical display.
* </p>
*
+ * <p>
+ * If one of the windows on the display has a preferred refresh rate that's supported by the
+ * display, then the display manager will request its use.
+ * </p>
+ *
* @param displayId The logical display id to update.
- * @param hasContent True if the logical display has content.
+ * @param hasContent True if the logical display has content. This is used to control automatic
+ * mirroring.
+ * @param requestedRefreshRate The preferred refresh rate for the top-most visible window that
+ * has a preference.
* @param inTraversal True if called from WindowManagerService during a window traversal
* prior to call to performTraversalInTransactionFromWindowManager.
*/
- public abstract void setDisplayHasContent(int displayId, boolean hasContent,
- boolean inTraversal);
+ public abstract void setDisplayProperties(int displayId, boolean hasContent,
+ float requestedRefreshRate, boolean inTraversal);
/**
* Describes the requested power state of the display.
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 154d227..cfb0297 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -26,6 +26,8 @@ import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.util.Log;
+import java.util.Arrays;
+
/**
* Provides information about the size and density of a logical display.
* <p>
@@ -613,6 +615,17 @@ public final class Display {
}
/**
+ * Get the supported refresh rates of this display in frames per second.
+ */
+ public float[] getSupportedRefreshRates() {
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ final float[] refreshRates = mDisplayInfo.supportedRefreshRates;
+ return Arrays.copyOf(refreshRates, refreshRates.length);
+ }
+ }
+
+ /**
* Gets the app VSYNC offset, in nanoseconds. This is a positive value indicating
* the phase offset of the VSYNC events provided by Choreographer relative to the
* display refresh. For example, if Choreographer reports that the refresh occurred
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 98696c7..56a05fe 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -22,6 +22,9 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.util.DisplayMetrics;
+import java.util.Arrays;
+
+import libcore.util.EmptyArray;
import libcore.util.Objects;
/**
@@ -156,6 +159,11 @@ public final class DisplayInfo implements Parcelable {
public float refreshRate;
/**
+ * The supported refresh rates of this display at the current resolution in frames per second.
+ */
+ public float[] supportedRefreshRates = EmptyArray.FLOAT;
+
+ /**
* The logical display density which is the basis for density-independent
* pixels.
*/
@@ -299,6 +307,8 @@ public final class DisplayInfo implements Parcelable {
overscanBottom = other.overscanBottom;
rotation = other.rotation;
refreshRate = other.refreshRate;
+ supportedRefreshRates = Arrays.copyOf(
+ other.supportedRefreshRates, other.supportedRefreshRates.length);
logicalDensityDpi = other.logicalDensityDpi;
physicalXDpi = other.physicalXDpi;
physicalYDpi = other.physicalYDpi;
@@ -329,6 +339,7 @@ public final class DisplayInfo implements Parcelable {
overscanBottom = source.readInt();
rotation = source.readInt();
refreshRate = source.readFloat();
+ supportedRefreshRates = source.createFloatArray();
logicalDensityDpi = source.readInt();
physicalXDpi = source.readFloat();
physicalYDpi = source.readFloat();
@@ -360,6 +371,7 @@ public final class DisplayInfo implements Parcelable {
dest.writeInt(overscanBottom);
dest.writeInt(rotation);
dest.writeFloat(refreshRate);
+ dest.writeFloatArray(supportedRefreshRates);
dest.writeInt(logicalDensityDpi);
dest.writeFloat(physicalXDpi);
dest.writeFloat(physicalYDpi);
@@ -462,7 +474,9 @@ public final class DisplayInfo implements Parcelable {
sb.append(smallestNominalAppHeight);
sb.append(", ");
sb.append(refreshRate);
- sb.append(" fps, rotation ");
+ sb.append(" fps, supportedRefreshRates ");
+ sb.append(Arrays.toString(supportedRefreshRates));
+ sb.append(", rotation ");
sb.append(rotation);
sb.append(", density ");
sb.append(logicalDensityDpi);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 46b9e03..47ee52e 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1418,6 +1418,16 @@ public interface WindowManager extends ViewManager {
public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
/**
+ * The preferred refresh rate for the window.
+ *
+ * This must be one of the supported refresh rates obtained for the display(s) the window
+ * is on.
+ *
+ * @see Display#getSupportedRefreshRates()
+ */
+ public float preferredRefreshRate;
+
+ /**
* Control the visibility of the status bar.
*
* @see View#STATUS_BAR_VISIBLE
@@ -1576,6 +1586,7 @@ public interface WindowManager extends ViewManager {
out.writeString(packageName);
TextUtils.writeToParcel(mTitle, out, parcelableFlags);
out.writeInt(screenOrientation);
+ out.writeFloat(preferredRefreshRate);
out.writeInt(systemUiVisibility);
out.writeInt(subtreeSystemUiVisibility);
out.writeInt(hasSystemUiListeners ? 1 : 0);
@@ -1622,6 +1633,7 @@ public interface WindowManager extends ViewManager {
packageName = in.readString();
mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
screenOrientation = in.readInt();
+ preferredRefreshRate = in.readFloat();
systemUiVisibility = in.readInt();
subtreeSystemUiVisibility = in.readInt();
hasSystemUiListeners = in.readInt() != 0;
@@ -1664,6 +1676,8 @@ public interface WindowManager extends ViewManager {
/** {@hide} */
public static final int SURFACE_INSETS_CHANGED = 1<<20;
/** {@hide} */
+ public static final int PREFERRED_REFRESH_RATE_CHANGED = 1 << 21;
+ /** {@hide} */
public static final int EVERYTHING_CHANGED = 0xffffffff;
// internal buffer to backup/restore parameters under compatibility mode.
@@ -1776,6 +1790,11 @@ public interface WindowManager extends ViewManager {
changes |= SCREEN_ORIENTATION_CHANGED;
}
+ if (preferredRefreshRate != o.preferredRefreshRate) {
+ preferredRefreshRate = o.preferredRefreshRate;
+ changes |= PREFERRED_REFRESH_RATE_CHANGED;
+ }
+
if (systemUiVisibility != o.systemUiVisibility
|| subtreeSystemUiVisibility != o.subtreeSystemUiVisibility) {
systemUiVisibility = o.systemUiVisibility;
@@ -1884,6 +1903,10 @@ public interface WindowManager extends ViewManager {
sb.append(" rotAnim=");
sb.append(rotationAnimation);
}
+ if (preferredRefreshRate != 0) {
+ sb.append(" preferredRefreshRate=");
+ sb.append(preferredRefreshRate);
+ }
if (systemUiVisibility != 0) {
sb.append(" sysui=0x");
sb.append(Integer.toHexString(systemUiVisibility));
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index a5f9822..16554d3 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -113,6 +113,12 @@ abstract class DisplayDevice {
}
/**
+ * Sets the refresh rate, if supported.
+ */
+ public void requestRefreshRateLocked(float refreshRate) {
+ }
+
+ /**
* Sets the display layer stack while in a transaction.
*/
public final void setLayerStackInTransactionLocked(int layerStack) {
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index c7f4f6a..f48428a 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -21,6 +21,9 @@ import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Surface;
+import java.util.Arrays;
+
+import libcore.util.EmptyArray;
import libcore.util.Objects;
/**
@@ -124,6 +127,11 @@ final class DisplayDeviceInfo {
public float refreshRate;
/**
+ * The supported refresh rates of the display at the current resolution in frames per second.
+ */
+ public float[] supportedRefreshRates = EmptyArray.FLOAT;
+
+ /**
* The nominal apparent density of the display in DPI used for layout calculations.
* This density is sensitive to the viewing distance. A big TV and a tablet may have
* the same apparent density even though the pixels on the TV are much bigger than
@@ -230,6 +238,7 @@ final class DisplayDeviceInfo {
&& width == other.width
&& height == other.height
&& refreshRate == other.refreshRate
+ && Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)
&& densityDpi == other.densityDpi
&& xDpi == other.xDpi
&& yDpi == other.yDpi
@@ -255,6 +264,7 @@ final class DisplayDeviceInfo {
width = other.width;
height = other.height;
refreshRate = other.refreshRate;
+ supportedRefreshRates = other.supportedRefreshRates;
densityDpi = other.densityDpi;
xDpi = other.xDpi;
yDpi = other.yDpi;
@@ -276,8 +286,9 @@ final class DisplayDeviceInfo {
StringBuilder sb = new StringBuilder();
sb.append("DisplayDeviceInfo{\"");
sb.append(name).append("\": ").append(width).append(" x ").append(height);
- sb.append(", ").append(refreshRate).append(" fps, ");
- sb.append("density ").append(densityDpi);
+ sb.append(", ").append(refreshRate).append(" fps");
+ sb.append(", supportedRefreshRates ").append(Arrays.toString(supportedRefreshRates));
+ sb.append(", density ").append(densityDpi);
sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
sb.append(", presDeadline ").append(presentationDeadlineNanos);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 7d3738c..2dd150a 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -777,11 +777,14 @@ public final class DisplayManagerService extends SystemService {
}
}
- private void setDisplayHasContentInternal(int displayId, boolean hasContent,
- boolean inTraversal) {
+ private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
+ float requestedRefreshRate, boolean inTraversal) {
synchronized (mSyncRoot) {
LogicalDisplay display = mLogicalDisplays.get(displayId);
- if (display != null && display.hasContentLocked() != hasContent) {
+ if (display == null) {
+ return;
+ }
+ if (display.hasContentLocked() != hasContent) {
if (DEBUG) {
Slog.d(TAG, "Display " + displayId + " hasContent flag changed: "
+ "hasContent=" + hasContent + ", inTraversal=" + inTraversal);
@@ -790,6 +793,14 @@ public final class DisplayManagerService extends SystemService {
display.setHasContentLocked(hasContent);
scheduleTraversalLocked(inTraversal);
}
+ if (display.getRequestedRefreshRateLocked() != requestedRefreshRate) {
+ if (DEBUG) {
+ Slog.d(TAG, "Display " + displayId + " has requested a new refresh rate: "
+ + requestedRefreshRate + "fps");
+ }
+ display.setRequestedRefreshRateLocked(requestedRefreshRate);
+ scheduleTraversalLocked(inTraversal);
+ }
}
}
@@ -1482,8 +1493,9 @@ public final class DisplayManagerService extends SystemService {
}
@Override
- public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) {
- setDisplayHasContentInternal(displayId, hasContent, inTraversal);
+ public void setDisplayProperties(int displayId, boolean hasContent,
+ float requestedRefreshRate, boolean inTraversal) {
+ setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate, inTraversal);
}
}
}
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 2bed143..4fd006d 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -21,6 +21,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.SystemProperties;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
@@ -29,6 +30,7 @@ import android.view.Surface;
import android.view.SurfaceControl;
import java.io.PrintWriter;
+import java.util.Arrays;
/**
* A display adapter for the local displays managed by Surface Flinger.
@@ -88,10 +90,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
if (device == null) {
// Display was added.
device = new LocalDisplayDevice(displayToken, builtInDisplayId,
- configs[activeConfig]);
+ configs, activeConfig);
mDevices.put(builtInDisplayId, device);
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
- } else if (device.updatePhysicalDisplayInfoLocked(configs[activeConfig])) {
+ } else if (device.updatePhysicalDisplayInfoLocked(configs, activeConfig)) {
// Display properties changed.
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED);
}
@@ -127,21 +129,31 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private final class LocalDisplayDevice extends DisplayDevice {
private final int mBuiltInDisplayId;
private final SurfaceControl.PhysicalDisplayInfo mPhys;
+ private final int mDefaultPhysicalDisplayInfo;
private DisplayDeviceInfo mInfo;
private boolean mHavePendingChanges;
private int mState = Display.STATE_UNKNOWN;
+ private float[] mSupportedRefreshRates;
+ private int[] mRefreshRateConfigIndices;
+ private float mLastRequestedRefreshRate;
public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
- SurfaceControl.PhysicalDisplayInfo phys) {
+ SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
super(LocalDisplayAdapter.this, displayToken);
mBuiltInDisplayId = builtInDisplayId;
- mPhys = new SurfaceControl.PhysicalDisplayInfo(phys);
+ mPhys = new SurfaceControl.PhysicalDisplayInfo(
+ physicalDisplayInfos[activeDisplayInfo]);
+ mDefaultPhysicalDisplayInfo = activeDisplayInfo;
+ updateSupportedRefreshRatesLocked(physicalDisplayInfos, mPhys);
}
- public boolean updatePhysicalDisplayInfoLocked(SurfaceControl.PhysicalDisplayInfo phys) {
- if (!mPhys.equals(phys)) {
- mPhys.copyFrom(phys);
+ public boolean updatePhysicalDisplayInfoLocked(
+ SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
+ SurfaceControl.PhysicalDisplayInfo newPhys = physicalDisplayInfos[activeDisplayInfo];
+ if (!mPhys.equals(newPhys)) {
+ mPhys.copyFrom(newPhys);
+ updateSupportedRefreshRatesLocked(physicalDisplayInfos, mPhys);
mHavePendingChanges = true;
return true;
}
@@ -163,6 +175,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
mInfo.width = mPhys.width;
mInfo.height = mPhys.height;
mInfo.refreshRate = mPhys.refreshRate;
+ mInfo.supportedRefreshRates = mSupportedRefreshRates;
mInfo.appVsyncOffsetNanos = mPhys.appVsyncOffsetNanos;
mInfo.presentationDeadlineNanos = mPhys.presentationDeadlineNanos;
mInfo.state = mState;
@@ -219,6 +232,26 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
@Override
+ public void requestRefreshRateLocked(float refreshRate) {
+ if (mLastRequestedRefreshRate == refreshRate) {
+ return;
+ }
+ mLastRequestedRefreshRate = refreshRate;
+ if (refreshRate != 0) {
+ final int N = mSupportedRefreshRates.length;
+ for (int i = 0; i < N; i++) {
+ if (refreshRate == mSupportedRefreshRates[i]) {
+ final int configIndex = mRefreshRateConfigIndices[i];
+ SurfaceControl.setActiveConfig(getDisplayTokenLocked(), configIndex);
+ return;
+ }
+ }
+ Slog.w(TAG, "Requested refresh rate " + refreshRate + " is unsupported.");
+ }
+ SurfaceControl.setActiveConfig(getDisplayTokenLocked(), mDefaultPhysicalDisplayInfo);
+ }
+
+ @Override
public void dumpLocked(PrintWriter pw) {
super.dumpLocked(pw);
pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
@@ -230,6 +263,30 @@ final class LocalDisplayAdapter extends DisplayAdapter {
mInfo = null;
sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
}
+
+ private void updateSupportedRefreshRatesLocked(
+ SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos,
+ SurfaceControl.PhysicalDisplayInfo activePhys) {
+ final int N = physicalDisplayInfos.length;
+ int idx = 0;
+ mSupportedRefreshRates = new float[N];
+ mRefreshRateConfigIndices = new int[N];
+ for (int i = 0; i < N; i++) {
+ final SurfaceControl.PhysicalDisplayInfo phys = physicalDisplayInfos[i];
+ if (activePhys.width == phys.width
+ && activePhys.height == phys.height
+ && activePhys.density == phys.density
+ && activePhys.xDpi == phys.xDpi
+ && activePhys.yDpi == phys.yDpi) {
+ mSupportedRefreshRates[idx] = phys.refreshRate;
+ mRefreshRateConfigIndices[idx++] = i;
+ }
+ }
+ if (idx != N) {
+ mSupportedRefreshRates = Arrays.copyOfRange(mSupportedRefreshRates, 0, idx);
+ mRefreshRateConfigIndices = Arrays.copyOfRange(mRefreshRateConfigIndices, 0, idx);
+ }
+ }
}
private final class HotplugDisplayEventReceiver extends DisplayEventReceiver {
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 284780d..00ff1cf 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -22,6 +22,7 @@ import android.view.DisplayInfo;
import android.view.Surface;
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.List;
import libcore.util.Objects;
@@ -72,6 +73,9 @@ final class LogicalDisplay {
// True if the logical display has unique content.
private boolean mHasContent;
+ // The pending requested refresh rate. 0 if no request is pending.
+ private float mRequestedRefreshRate;
+
// Temporary rectangle used when needed.
private final Rect mTempLayerStackRect = new Rect();
private final Rect mTempDisplayRect = new Rect();
@@ -210,6 +214,8 @@ final class LogicalDisplay {
mBaseDisplayInfo.logicalHeight = deviceInfo.height;
mBaseDisplayInfo.rotation = Surface.ROTATION_0;
mBaseDisplayInfo.refreshRate = deviceInfo.refreshRate;
+ mBaseDisplayInfo.supportedRefreshRates = Arrays.copyOf(
+ deviceInfo.supportedRefreshRates, deviceInfo.supportedRefreshRates.length);
mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
@@ -253,6 +259,9 @@ final class LogicalDisplay {
// Set the layer stack.
device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack);
+ // Set the refresh rate
+ device.requestRefreshRateLocked(mRequestedRefreshRate);
+
// Set the viewport.
// This is the area of the logical display that we intend to show on the
// display device. For now, it is always the full size of the logical display.
@@ -328,6 +337,23 @@ final class LogicalDisplay {
mHasContent = hasContent;
}
+ /**
+ * Requests the given refresh rate.
+ * @param requestedRefreshRate The desired refresh rate.
+ */
+ public void setRequestedRefreshRateLocked(float requestedRefreshRate) {
+ mRequestedRefreshRate = requestedRefreshRate;
+ }
+
+ /**
+ * Gets the pending requested refresh rate.
+ *
+ * @return The pending refresh rate requested
+ */
+ public float getRequestedRefreshRateLocked() {
+ return mRequestedRefreshRate;
+ }
+
public void dumpLocked(PrintWriter pw) {
pw.println("mDisplayId=" + mDisplayId);
pw.println("mLayerStack=" + mLayerStack);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index cdb5e58..304d2d4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -619,6 +619,8 @@ public class WindowManagerService extends IWindowManager.Stub
// Only set while traversing the default display based on its content.
// Affects the behavior of mirroring on secondary displays.
boolean mObscureApplicationContentOnSecondaryDisplays = false;
+
+ float mPreferredRefreshRate = 0;
}
final LayoutFields mInnerFields = new LayoutFields();
@@ -9091,6 +9093,10 @@ public class WindowManagerService extends IWindowManager.Stub
// Allow full screen keyguard presentation dialogs to be seen.
mInnerFields.mDisplayHasContent = true;
}
+ if (mInnerFields.mPreferredRefreshRate == 0
+ && w.mAttrs.preferredRefreshRate != 0) {
+ mInnerFields.mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
+ }
}
}
}
@@ -9215,6 +9221,7 @@ public class WindowManagerService extends IWindowManager.Stub
// Reset for each display.
mInnerFields.mDisplayHasContent = false;
+ mInnerFields.mPreferredRefreshRate = 0;
int repeats = 0;
do {
@@ -9434,8 +9441,8 @@ public class WindowManagerService extends IWindowManager.Stub
updateResizingWindows(w);
}
- mDisplayManagerInternal.setDisplayHasContent(displayId,
- mInnerFields.mDisplayHasContent,
+ mDisplayManagerInternal.setDisplayProperties(displayId,
+ mInnerFields.mDisplayHasContent, mInnerFields.mPreferredRefreshRate,
true /* inTraversal, must call performTraversalInTrans... below */);
getDisplayContentLocked(displayId).stopDimmingIfNeeded();