summaryrefslogtreecommitdiffstats
path: root/services/core/java/com/android
diff options
context:
space:
mode:
authorP.Y. Laligand <pylaligand@google.com>2015-05-11 15:02:07 -0700
committerP.Y. Laligand <pylaligand@google.com>2015-05-11 15:02:07 -0700
commitb3b9eb3cfc5b3b3609a5d01258315798b38a5cf9 (patch)
tree9d1d777fceb08094b7accab63c4f1b135e687a2e /services/core/java/com/android
parented1ef7d4eb8934f6940a2e828ebd0e6878e1af89 (diff)
downloadframeworks_base-b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9.zip
frameworks_base-b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9.tar.gz
frameworks_base-b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9.tar.bz2
DO NOT MERGE - Display mode switches.
Knowledge of the various modes of a display is now available to apps, and they can request a specific mode for their windows. b/18241736 Change-Id: I8eb16ff713e878512faca3ca6662254f08a9be7f (cherry picked from commit 5c7773d86484aac5737667c604bd8fe8150c2136)
Diffstat (limited to 'services/core/java/com/android')
-rw-r--r--services/core/java/com/android/server/display/DisplayAdapter.java12
-rw-r--r--services/core/java/com/android/server/display/DisplayDevice.java5
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceInfo.java29
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java20
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java186
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplay.java42
-rw-r--r--services/core/java/com/android/server/display/OverlayDisplayAdapter.java7
-rw-r--r--services/core/java/com/android/server/display/OverlayDisplayWindow.java5
-rw-r--r--services/core/java/com/android/server/display/VirtualDisplayAdapter.java12
-rw-r--r--services/core/java/com/android/server/display/WifiDisplayAdapter.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java8
11 files changed, 216 insertions, 117 deletions
diff --git a/services/core/java/com/android/server/display/DisplayAdapter.java b/services/core/java/com/android/server/display/DisplayAdapter.java
index b411a0d..6ba25a5 100644
--- a/services/core/java/com/android/server/display/DisplayAdapter.java
+++ b/services/core/java/com/android/server/display/DisplayAdapter.java
@@ -18,8 +18,10 @@ package com.android.server.display;
import android.content.Context;
import android.os.Handler;
+import android.view.Display;
import java.io.PrintWriter;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* A display adapter makes zero or more display devices available to the system
@@ -42,6 +44,11 @@ abstract class DisplayAdapter {
public static final int DISPLAY_DEVICE_EVENT_CHANGED = 2;
public static final int DISPLAY_DEVICE_EVENT_REMOVED = 3;
+ /**
+ * Used to generate globally unique display mode ids.
+ */
+ private static final AtomicInteger NEXT_DISPLAY_MODE_ID = new AtomicInteger(1); // 0 = no mode.
+
// Called with SyncRoot lock held.
public DisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener, String name) {
@@ -122,6 +129,11 @@ abstract class DisplayAdapter {
});
}
+ public static Display.Mode createMode(int width, int height, float refreshRate) {
+ return new Display.Mode(
+ NEXT_DISPLAY_MODE_ID.getAndIncrement(), width, height, refreshRate);
+ }
+
public interface Listener {
public void onDisplayDeviceEvent(DisplayDevice device, int event);
public void onTraversalRequested();
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index ee36972..93bda46 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -19,6 +19,7 @@ package com.android.server.display;
import android.graphics.Rect;
import android.hardware.display.DisplayViewport;
import android.os.IBinder;
+import android.view.Display;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -132,9 +133,9 @@ abstract class DisplayDevice {
}
/**
- * Sets the refresh rate, if supported.
+ * Sets the mode, if supported.
*/
- public void requestRefreshRateLocked(float refreshRate) {
+ public void requestModeInTransactionLocked(int id) {
}
/**
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index ebf6e4e..0db3e3f 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -23,7 +23,6 @@ import android.view.Surface;
import java.util.Arrays;
-import libcore.util.EmptyArray;
import libcore.util.Objects;
/**
@@ -137,14 +136,19 @@ final class DisplayDeviceInfo {
public int height;
/**
- * The refresh rate of the display, in frames per second.
+ * The active mode of the display.
*/
- public float refreshRate;
+ public int modeId;
/**
- * The supported refresh rates of the display at the current resolution in frames per second.
+ * The default mode of the display.
*/
- public float[] supportedRefreshRates = EmptyArray.FLOAT;
+ public int defaultModeId;
+
+ /**
+ * The supported modes of the display.
+ */
+ public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
/**
* The nominal apparent density of the display in DPI used for layout calculations.
@@ -264,8 +268,9 @@ final class DisplayDeviceInfo {
|| !Objects.equal(uniqueId, other.uniqueId)
|| width != other.width
|| height != other.height
- || refreshRate != other.refreshRate
- || !Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)
+ || modeId != other.modeId
+ || defaultModeId != other.defaultModeId
+ || !Arrays.equals(supportedModes, other.supportedModes)
|| densityDpi != other.densityDpi
|| xDpi != other.xDpi
|| yDpi != other.yDpi
@@ -293,8 +298,9 @@ final class DisplayDeviceInfo {
uniqueId = other.uniqueId;
width = other.width;
height = other.height;
- refreshRate = other.refreshRate;
- supportedRefreshRates = other.supportedRefreshRates;
+ modeId = other.modeId;
+ defaultModeId = other.defaultModeId;
+ supportedModes = other.supportedModes;
densityDpi = other.densityDpi;
xDpi = other.xDpi;
yDpi = other.yDpi;
@@ -317,8 +323,9 @@ final class DisplayDeviceInfo {
sb.append("DisplayDeviceInfo{\"");
sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", ");
sb.append(width).append(" x ").append(height);
- sb.append(", ").append(refreshRate).append(" fps");
- sb.append(", supportedRefreshRates ").append(Arrays.toString(supportedRefreshRates));
+ sb.append(", modeId ").append(modeId);
+ sb.append(", defaultModeId ").append(defaultModeId);
+ sb.append(", supportedModes ").append(Arrays.toString(supportedModes));
sb.append(", density ").append(densityDpi);
sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 1e87433..7440b8c 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -842,7 +842,7 @@ public final class DisplayManagerService extends SystemService {
}
private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
- float requestedRefreshRate, boolean inTraversal) {
+ float requestedRefreshRate, int requestedModeId, boolean inTraversal) {
synchronized (mSyncRoot) {
LogicalDisplay display = mLogicalDisplays.get(displayId);
if (display == null) {
@@ -857,12 +857,17 @@ public final class DisplayManagerService extends SystemService {
display.setHasContentLocked(hasContent);
scheduleTraversalLocked(inTraversal);
}
- if (display.getRequestedRefreshRateLocked() != requestedRefreshRate) {
+ if (requestedModeId == 0 && requestedRefreshRate != 0) {
+ // Scan supported modes returned by display.getInfo() to find a mode with the same
+ // size as the default display mode but with the specified refresh rate instead.
+ requestedModeId = display.getDisplayInfoLocked().findDefaultModeByRefreshRate(
+ requestedRefreshRate);
+ }
+ if (display.getRequestedModeIdLocked() != requestedModeId) {
if (DEBUG) {
- Slog.d(TAG, "Display " + displayId + " has requested a new refresh rate: "
- + requestedRefreshRate + "fps");
+ Slog.d(TAG, "Display " + displayId + " switching to mode " + requestedModeId);
}
- display.setRequestedRefreshRateLocked(requestedRefreshRate);
+ display.setRequestedModeIdLocked(requestedModeId);
scheduleTraversalLocked(inTraversal);
}
}
@@ -1564,8 +1569,9 @@ public final class DisplayManagerService extends SystemService {
@Override
public void setDisplayProperties(int displayId, boolean hasContent,
- float requestedRefreshRate, boolean inTraversal) {
- setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate, inTraversal);
+ float requestedRefreshRate, int requestedMode, boolean inTraversal) {
+ setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate,
+ requestedMode, inTraversal);
}
@Override
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index e87f265..cc7d848 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -35,7 +35,7 @@ import android.view.Surface;
import android.view.SurfaceControl;
import java.io.PrintWriter;
-import java.util.Arrays;
+import java.util.ArrayList;
/**
* A display adapter for the local displays managed by Surface Flinger.
@@ -56,6 +56,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private final SparseArray<LocalDisplayDevice> mDevices =
new SparseArray<LocalDisplayDevice>();
+ @SuppressWarnings("unused") // Becomes active at instantiation time.
private HotplugDisplayEventReceiver mHotplugReceiver;
// Called with SyncRoot lock held.
@@ -136,28 +137,22 @@ 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 final Light mBacklight;
+ private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>();
private DisplayDeviceInfo mInfo;
private boolean mHavePendingChanges;
private int mState = Display.STATE_UNKNOWN;
private int mBrightness = PowerManager.BRIGHTNESS_DEFAULT;
- private float[] mSupportedRefreshRates;
- private int[] mRefreshRateConfigIndices;
- private float mLastRequestedRefreshRate;
-
+ private int mDefaultModeId;
+ private int mActiveModeId;
+ private boolean mActiveModeInvalid;
public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId);
mBuiltInDisplayId = builtInDisplayId;
- mPhys = new SurfaceControl.PhysicalDisplayInfo(
- physicalDisplayInfos[activeDisplayInfo]);
- mDefaultPhysicalDisplayInfo = activeDisplayInfo;
- updateSupportedRefreshRatesLocked(physicalDisplayInfos, mPhys);
-
+ updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo);
if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
LightsManager lights = LocalServices.getService(LightsManager.class);
mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
@@ -168,14 +163,73 @@ final class LocalDisplayAdapter extends DisplayAdapter {
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;
+ // Build an updated list of all existing modes.
+ boolean modesAdded = false;
+ DisplayModeRecord activeRecord = null;
+ ArrayList<DisplayModeRecord> records = new ArrayList<DisplayModeRecord>();
+ for (int i = 0; i < physicalDisplayInfos.length; i++) {
+ SurfaceControl.PhysicalDisplayInfo info = physicalDisplayInfos[i];
+ DisplayModeRecord record = findDisplayModeRecord(info);
+ if (record != null) {
+ record.mPhysIndex = i;
+ } else {
+ record = new DisplayModeRecord(info, i);
+ modesAdded = true;
+ }
+ records.add(record);
+ if (i == activeDisplayInfo) {
+ activeRecord = record;
+ }
+ }
+ // Check whether surface flinger spontaneously changed modes out from under us. Schedule
+ // traversals to ensure that the correct state is reapplied if necessary.
+ if (mActiveModeId != 0
+ && mActiveModeId != activeRecord.mMode.getModeId()) {
+ mActiveModeInvalid = true;
+ sendTraversalRequestLocked();
+ }
+ // If no modes were added and we have the same number of modes as before, then nothing
+ // actually changed except possibly the physical index (which we only care about when
+ // setting the mode) so we're done.
+ if (records.size() == mSupportedModes.size() && !modesAdded) {
+ return false;
+ }
+ // Update the index of modes.
+ mHavePendingChanges = true;
+ mSupportedModes.clear();
+ for (DisplayModeRecord record : records) {
+ mSupportedModes.put(record.mMode.getModeId(), record);
+ }
+ // Update the default mode if needed.
+ if (mSupportedModes.indexOfKey(mDefaultModeId) < 0) {
+ if (mDefaultModeId != 0) {
+ Slog.w(TAG, "Default display mode no longer available, using currently active"
+ + " mode as default.");
+ }
+ mDefaultModeId = activeRecord.mMode.getModeId();
+ }
+ // Determine whether the active mode is still there.
+ if (mSupportedModes.indexOfKey(mActiveModeId) < 0) {
+ if (mActiveModeId != 0) {
+ Slog.w(TAG, "Active display mode no longer available, reverting to default"
+ + " mode.");
+ }
+ mActiveModeId = mDefaultModeId;
+ mActiveModeInvalid = true;
+ }
+ // Schedule traversals so that we apply pending changes.
+ sendTraversalRequestLocked();
+ return true;
+ }
+
+ private DisplayModeRecord findDisplayModeRecord(SurfaceControl.PhysicalDisplayInfo info) {
+ for (int i = 0; i < mSupportedModes.size(); i++) {
+ DisplayModeRecord record = mSupportedModes.valueAt(i);
+ if (record.mPhys.equals(info)) {
+ return record;
+ }
}
- return false;
+ return null;
}
@Override
@@ -189,19 +243,25 @@ final class LocalDisplayAdapter extends DisplayAdapter {
@Override
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
if (mInfo == null) {
+ SurfaceControl.PhysicalDisplayInfo phys = mSupportedModes.get(mActiveModeId).mPhys;
mInfo = new DisplayDeviceInfo();
- mInfo.width = mPhys.width;
- mInfo.height = mPhys.height;
- mInfo.refreshRate = mPhys.refreshRate;
- mInfo.supportedRefreshRates = mSupportedRefreshRates;
- mInfo.appVsyncOffsetNanos = mPhys.appVsyncOffsetNanos;
- mInfo.presentationDeadlineNanos = mPhys.presentationDeadlineNanos;
+ mInfo.width = phys.width;
+ mInfo.height = phys.height;
+ mInfo.modeId = mActiveModeId;
+ mInfo.defaultModeId = mDefaultModeId;
+ mInfo.supportedModes = new Display.Mode[mSupportedModes.size()];
+ for (int i = 0; i < mSupportedModes.size(); i++) {
+ DisplayModeRecord record = mSupportedModes.valueAt(i);
+ mInfo.supportedModes[i] = record.mMode;
+ }
+ mInfo.appVsyncOffsetNanos = phys.appVsyncOffsetNanos;
+ mInfo.presentationDeadlineNanos = phys.presentationDeadlineNanos;
mInfo.state = mState;
mInfo.uniqueId = getUniqueId();
// Assume that all built-in displays that have secure output (eg. HDCP) also
// support compositing from gralloc protected buffers.
- if (mPhys.secure) {
+ if (phys.secure) {
mInfo.flags = DisplayDeviceInfo.FLAG_SECURE
| DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS;
}
@@ -212,9 +272,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
| DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
mInfo.type = Display.TYPE_BUILT_IN;
- mInfo.densityDpi = (int)(mPhys.density * 160 + 0.5f);
- mInfo.xDpi = mPhys.xDpi;
- mInfo.yDpi = mPhys.yDpi;
+ mInfo.densityDpi = (int)(phys.density * 160 + 0.5f);
+ mInfo.xDpi = phys.xDpi;
+ mInfo.yDpi = phys.yDpi;
mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
} else {
mInfo.type = Display.TYPE_HDMI;
@@ -222,7 +282,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
mInfo.name = getContext().getResources().getString(
com.android.internal.R.string.display_manager_hdmi_display_name);
mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
- mInfo.setAssumedDensityForExternalDisplay(mPhys.width, mPhys.height);
+ mInfo.setAssumedDensityForExternalDisplay(phys.width, phys.height);
// For demonstration purposes, allow rotation of the external display.
// In the future we might allow the user to configure this directly.
@@ -332,30 +392,29 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
@Override
- public void requestRefreshRateLocked(float refreshRate) {
- if (mLastRequestedRefreshRate == refreshRate) {
- return;
+ public void requestModeInTransactionLocked(int modeId) {
+ if (modeId == 0) {
+ modeId = mDefaultModeId;
+ } else if (mSupportedModes.indexOfKey(modeId) < 0) {
+ Slog.w(TAG, "Requested mode " + modeId + " is not supported by this display,"
+ + " reverting to default display mode.");
+ modeId = mDefaultModeId;
}
- 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.");
+ if (mActiveModeId == modeId && !mActiveModeInvalid) {
+ return;
}
- SurfaceControl.setActiveConfig(getDisplayTokenLocked(), mDefaultPhysicalDisplayInfo);
+ DisplayModeRecord record = mSupportedModes.get(modeId);
+ SurfaceControl.setActiveConfig(getDisplayTokenLocked(), record.mPhysIndex);
+ mActiveModeId = modeId;
+ mActiveModeInvalid = false;
+ updateDeviceInfoLocked();
}
@Override
public void dumpLocked(PrintWriter pw) {
super.dumpLocked(pw);
pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
- pw.println("mPhys=" + mPhys);
+ pw.println("mActiveModeId=" + mActiveModeId);
pw.println("mState=" + Display.stateToString(mState));
pw.println("mBrightness=" + mBrightness);
pw.println("mBacklight=" + mBacklight);
@@ -365,29 +424,20 @@ 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);
- }
+ /**
+ * Keeps track of a display configuration.
+ */
+ private static final class DisplayModeRecord {
+ public final Display.Mode mMode;
+ public final SurfaceControl.PhysicalDisplayInfo mPhys;
+ public int mPhysIndex;
+
+ public DisplayModeRecord(SurfaceControl.PhysicalDisplayInfo phys, int physIndex) {
+ mMode = createMode(phys.width, phys.height, phys.refreshRate);
+ mPhys = phys;
+ mPhysIndex = physIndex;
}
}
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 65dc72f..7accbf2 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -73,8 +73,7 @@ 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;
+ private int mRequestedModeId;
// The display offsets to apply to the display projection.
private int mDisplayOffsetX;
@@ -219,9 +218,10 @@ final class LogicalDisplay {
mBaseDisplayInfo.logicalWidth = deviceInfo.width;
mBaseDisplayInfo.logicalHeight = deviceInfo.height;
mBaseDisplayInfo.rotation = Surface.ROTATION_0;
- mBaseDisplayInfo.refreshRate = deviceInfo.refreshRate;
- mBaseDisplayInfo.supportedRefreshRates = Arrays.copyOf(
- deviceInfo.supportedRefreshRates, deviceInfo.supportedRefreshRates.length);
+ mBaseDisplayInfo.modeId = deviceInfo.modeId;
+ mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
+ mBaseDisplayInfo.supportedModes = Arrays.copyOf(
+ deviceInfo.supportedModes, deviceInfo.supportedModes.length);
mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
@@ -259,14 +259,19 @@ final class LogicalDisplay {
*/
public void configureDisplayInTransactionLocked(DisplayDevice device,
boolean isBlanked) {
- final DisplayInfo displayInfo = getDisplayInfoLocked();
- final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked();
-
// Set the layer stack.
device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack);
- // Set the refresh rate
- device.requestRefreshRateLocked(mRequestedRefreshRate);
+ // Set the mode.
+ if (device == mPrimaryDisplayDevice) {
+ device.requestModeInTransactionLocked(mRequestedModeId);
+ } else {
+ device.requestModeInTransactionLocked(0); // Revert to default.
+ }
+
+ // Only grab the display info now as it may have been changed based on the requests above.
+ final DisplayInfo displayInfo = getDisplayInfoLocked();
+ final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked();
// Set the viewport.
// This is the area of the logical display that we intend to show on the
@@ -351,20 +356,17 @@ final class LogicalDisplay {
}
/**
- * Requests the given refresh rate.
- * @param requestedRefreshRate The desired refresh rate.
+ * Requests the given mode.
*/
- public void setRequestedRefreshRateLocked(float requestedRefreshRate) {
- mRequestedRefreshRate = requestedRefreshRate;
+ public void setRequestedModeIdLocked(int modeId) {
+ mRequestedModeId = modeId;
}
/**
- * Gets the pending requested refresh rate.
- *
- * @return The pending refresh rate requested
+ * Returns the pending requested mode.
*/
- public float getRequestedRefreshRateLocked() {
- return mRequestedRefreshRate;
+ public int getRequestedModeIdLocked() {
+ return mRequestedModeId;
}
/**
@@ -393,7 +395,7 @@ final class LogicalDisplay {
pw.println("mDisplayId=" + mDisplayId);
pw.println("mLayerStack=" + mLayerStack);
pw.println("mHasContent=" + mHasContent);
- pw.println("mRequestedRefreshRate=" + mRequestedRefreshRate);
+ pw.println("mRequestedMode=" + mRequestedModeId);
pw.println("mDisplayOffset=(" + mDisplayOffsetX + ", " + mDisplayOffsetY + ")");
pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null ?
mPrimaryDisplayDevice.getNameLocked() : "null"));
diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
index af9f456..080665a 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -197,6 +197,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
private final long mDisplayPresentationDeadlineNanos;
private final int mDensityDpi;
private final boolean mSecure;
+ private final Display.Mode mMode;
private int mState;
private SurfaceTexture mSurfaceTexture;
@@ -217,6 +218,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
mSecure = secure;
mState = state;
mSurfaceTexture = surfaceTexture;
+ mMode = createMode(width, height, refreshRate);
}
public void destroyLocked() {
@@ -251,8 +253,9 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
mInfo.uniqueId = getUniqueId();
mInfo.width = mWidth;
mInfo.height = mHeight;
- mInfo.refreshRate = mRefreshRate;
- mInfo.supportedRefreshRates = new float[] { mRefreshRate };
+ mInfo.modeId = mMode.getModeId();
+ mInfo.defaultModeId = mMode.getModeId();
+ mInfo.supportedModes = new Display.Mode[] { mMode };
mInfo.densityDpi = mDensityDpi;
mInfo.xDpi = mDensityDpi;
mInfo.yDpi = mDensityDpi;
diff --git a/services/core/java/com/android/server/display/OverlayDisplayWindow.java b/services/core/java/com/android/server/display/OverlayDisplayWindow.java
index 3f4eab9..786889a 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayWindow.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayWindow.java
@@ -302,7 +302,8 @@ final class OverlayDisplayWindow implements DumpUtils.Dump {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
int width, int height) {
- mListener.onWindowCreated(surfaceTexture, mDefaultDisplayInfo.refreshRate,
+ mListener.onWindowCreated(surfaceTexture,
+ mDefaultDisplayInfo.getMode().getRefreshRate(),
mDefaultDisplayInfo.presentationDeadlineNanos, mDefaultDisplayInfo.state);
}
@@ -377,4 +378,4 @@ final class OverlayDisplayWindow implements DumpUtils.Dump {
public void onWindowDestroyed();
public void onStateChanged(int state);
}
-} \ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 7f961ae..986efd6 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -165,6 +165,8 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
private static final int PENDING_SURFACE_CHANGE = 0x01;
private static final int PENDING_RESIZE = 0x02;
+ private static final float REFRESH_RATE = 60.0f;
+
private final IBinder mAppToken;
private final int mOwnerUid;
final String mOwnerPackageName;
@@ -181,6 +183,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
private boolean mStopped;
private int mPendingChanges;
private int mUniqueIndex;
+ private Display.Mode mMode;
public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
int ownerUid, String ownerPackageName,
@@ -193,6 +196,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
mName = name;
mWidth = width;
mHeight = height;
+ mMode = createMode(width, height, REFRESH_RATE);
mDensityDpi = densityDpi;
mSurface = surface;
mFlags = flags;
@@ -262,6 +266,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
sendTraversalRequestLocked();
mWidth = width;
mHeight = height;
+ mMode = createMode(width, height, REFRESH_RATE);
mDensityDpi = densityDpi;
mInfo = null;
mPendingChanges |= PENDING_RESIZE;
@@ -290,12 +295,13 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
mInfo.uniqueId = getUniqueId();
mInfo.width = mWidth;
mInfo.height = mHeight;
- mInfo.refreshRate = 60;
- mInfo.supportedRefreshRates = new float[] { 60.0f };
+ mInfo.modeId = mMode.getModeId();
+ mInfo.defaultModeId = mMode.getModeId();
+ mInfo.supportedModes = new Display.Mode[] { mMode };
mInfo.densityDpi = mDensityDpi;
mInfo.xDpi = mDensityDpi;
mInfo.yDpi = mDensityDpi;
- mInfo.presentationDeadlineNanos = 1000000000L / (int) mInfo.refreshRate; // 1 frame
+ mInfo.presentationDeadlineNanos = 1000000000L / (int) REFRESH_RATE; // 1 frame
mInfo.flags = 0;
if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) {
mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE
diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
index f163555..64bc729 100644
--- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@@ -583,6 +583,7 @@ final class WifiDisplayAdapter extends DisplayAdapter {
private final float mRefreshRate;
private final int mFlags;
private final String mAddress;
+ private final Display.Mode mMode;
private Surface mSurface;
private DisplayDeviceInfo mInfo;
@@ -598,6 +599,7 @@ final class WifiDisplayAdapter extends DisplayAdapter {
mFlags = flags;
mAddress = address;
mSurface = surface;
+ mMode = createMode(width, height, refreshRate);
}
public void destroyLocked() {
@@ -628,8 +630,9 @@ final class WifiDisplayAdapter extends DisplayAdapter {
mInfo.uniqueId = getUniqueId();
mInfo.width = mWidth;
mInfo.height = mHeight;
- mInfo.refreshRate = mRefreshRate;
- mInfo.supportedRefreshRates = new float[] { mRefreshRate };
+ mInfo.modeId = mMode.getModeId();
+ mInfo.defaultModeId = mMode.getModeId();
+ mInfo.supportedModes = new Display.Mode[] { mMode };
mInfo.presentationDeadlineNanos = 1000000000L / (int) mRefreshRate; // 1 frame
mInfo.flags = mFlags;
mInfo.type = Display.TYPE_WIFI;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6bf68e8..06d3b22 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -691,6 +691,8 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mObscureApplicationContentOnSecondaryDisplays = false;
float mPreferredRefreshRate = 0;
+
+ int mPreferredModeId = 0;
}
final LayoutFields mInnerFields = new LayoutFields();
@@ -9713,6 +9715,10 @@ public class WindowManagerService extends IWindowManager.Stub
&& w.mAttrs.preferredRefreshRate != 0) {
mInnerFields.mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
}
+ if (mInnerFields.mPreferredModeId == 0
+ && w.mAttrs.preferredDisplayModeId != 0) {
+ mInnerFields.mPreferredModeId = w.mAttrs.preferredDisplayModeId;
+ }
}
}
}
@@ -9846,6 +9852,7 @@ public class WindowManagerService extends IWindowManager.Stub
// Reset for each display.
mInnerFields.mDisplayHasContent = false;
mInnerFields.mPreferredRefreshRate = 0;
+ mInnerFields.mPreferredModeId = 0;
int repeats = 0;
do {
@@ -10066,6 +10073,7 @@ public class WindowManagerService extends IWindowManager.Stub
mDisplayManagerInternal.setDisplayProperties(displayId,
mInnerFields.mDisplayHasContent, mInnerFields.mPreferredRefreshRate,
+ mInnerFields.mPreferredModeId,
true /* inTraversal, must call performTraversalInTrans... below */);
getDisplayContentLocked(displayId).stopDimmingIfNeeded();