diff options
author | P.Y. Laligand <pylaligand@google.com> | 2015-05-11 15:02:07 -0700 |
---|---|---|
committer | P.Y. Laligand <pylaligand@google.com> | 2015-05-11 15:02:07 -0700 |
commit | b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9 (patch) | |
tree | 9d1d777fceb08094b7accab63c4f1b135e687a2e /services | |
parent | ed1ef7d4eb8934f6940a2e828ebd0e6878e1af89 (diff) | |
download | frameworks_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')
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(); |