am 91f2123b: Merge "Add support for setting color transforms" into mnc-dr-dev
* commit '91f2123b2a6d534372ab9b7c8e6ac0c62cf33ae6': Add support for setting color transforms
This commit is contained in:
@@ -359,6 +359,14 @@ public final class DisplayManagerGlobal {
|
||||
}
|
||||
}
|
||||
|
||||
public void requestColorTransform(int displayId, int colorTransformId) {
|
||||
try {
|
||||
mDm.requestColorTransform(displayId, colorTransformId);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Failed to request color transform.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public VirtualDisplay createVirtualDisplay(Context context, MediaProjection projection,
|
||||
String name, int width, int height, int densityDpi, Surface surface, int flags,
|
||||
VirtualDisplay.Callback callback, Handler handler) {
|
||||
|
||||
@@ -59,6 +59,9 @@ interface IDisplayManager {
|
||||
// No permissions required.
|
||||
WifiDisplayStatus getWifiDisplayStatus();
|
||||
|
||||
// Requires CONFIGURE_DISPLAY_COLOR_TRANSFORM
|
||||
void requestColorTransform(int displayId, int colorTransformId);
|
||||
|
||||
// Requires CAPTURE_VIDEO_OUTPUT, CAPTURE_SECURE_VIDEO_OUTPUT, or an appropriate
|
||||
// MediaProjection token for certain combinations of flags.
|
||||
int createVirtualDisplay(in IVirtualDisplayCallback callback,
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.content.Context;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
@@ -30,6 +33,8 @@ import android.util.Log;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM;
|
||||
|
||||
/**
|
||||
* Provides information about the size and density of a logical display.
|
||||
* <p>
|
||||
@@ -678,6 +683,49 @@ public final class Display {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the display applies a color transform.
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(CONFIGURE_DISPLAY_COLOR_TRANSFORM)
|
||||
public void requestColorTransform(ColorTransform colorTransform) {
|
||||
mGlobal.requestColorTransform(mDisplayId, colorTransform.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the active color transform of this display
|
||||
* @hide
|
||||
*/
|
||||
public ColorTransform getColorTransform() {
|
||||
synchronized (this) {
|
||||
updateDisplayInfoLocked();
|
||||
return mDisplayInfo.getColorTransform();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default color transform of this display
|
||||
* @hide
|
||||
*/
|
||||
public ColorTransform getDefaultColorTransform() {
|
||||
synchronized (this) {
|
||||
updateDisplayInfoLocked();
|
||||
return mDisplayInfo.getDefaultColorTransform();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the supported color transforms of this device.
|
||||
* @hide
|
||||
*/
|
||||
public ColorTransform[] getSupportedColorTransforms() {
|
||||
synchronized (this) {
|
||||
updateDisplayInfoLocked();
|
||||
ColorTransform[] transforms = mDisplayInfo.supportedColorTransforms;
|
||||
return Arrays.copyOf(transforms, transforms.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
|
||||
@@ -1054,4 +1102,89 @@ public final class Display {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A color transform supported by a given display.
|
||||
*
|
||||
* @see Display#getSupportedColorTransforms()
|
||||
* @hide
|
||||
*/
|
||||
public static final class ColorTransform implements Parcelable {
|
||||
public static final ColorTransform[] EMPTY_ARRAY = new ColorTransform[0];
|
||||
|
||||
private final int mId;
|
||||
private final int mColorTransform;
|
||||
|
||||
public ColorTransform(int id, int colorTransform) {
|
||||
mId = id;
|
||||
mColorTransform = colorTransform;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
public int getColorTransform() {
|
||||
return mColorTransform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof ColorTransform)) {
|
||||
return false;
|
||||
}
|
||||
ColorTransform that = (ColorTransform) other;
|
||||
return mId == that.mId
|
||||
&& mColorTransform == that.mColorTransform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 1;
|
||||
hash = hash * 17 + mId;
|
||||
hash = hash * 17 + mColorTransform;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("{")
|
||||
.append("id=").append(mId)
|
||||
.append(", colorTransform=").append(mColorTransform)
|
||||
.append("}")
|
||||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private ColorTransform(Parcel in) {
|
||||
this(in.readInt(), in.readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int parcelableFlags) {
|
||||
out.writeInt(mId);
|
||||
out.writeInt(mColorTransform);
|
||||
}
|
||||
|
||||
@SuppressWarnings("hiding")
|
||||
public static final Parcelable.Creator<ColorTransform> CREATOR
|
||||
= new Parcelable.Creator<ColorTransform>() {
|
||||
@Override
|
||||
public ColorTransform createFromParcel(Parcel in) {
|
||||
return new ColorTransform(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorTransform[] newArray(int size) {
|
||||
return new ColorTransform[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +169,15 @@ public final class DisplayInfo implements Parcelable {
|
||||
*/
|
||||
public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
|
||||
|
||||
/** The active color transform. */
|
||||
public int colorTransformId;
|
||||
|
||||
/** The default color transform. */
|
||||
public int defaultColorTransformId;
|
||||
|
||||
/** The list of supported color transforms */
|
||||
public Display.ColorTransform[] supportedColorTransforms = Display.ColorTransform.EMPTY_ARRAY;
|
||||
|
||||
/**
|
||||
* The logical display density which is the basis for density-independent
|
||||
* pixels.
|
||||
@@ -279,6 +288,8 @@ public final class DisplayInfo implements Parcelable {
|
||||
&& rotation == other.rotation
|
||||
&& modeId == other.modeId
|
||||
&& defaultModeId == other.defaultModeId
|
||||
&& colorTransformId == other.colorTransformId
|
||||
&& defaultColorTransformId == other.defaultColorTransformId
|
||||
&& logicalDensityDpi == other.logicalDensityDpi
|
||||
&& physicalXDpi == other.physicalXDpi
|
||||
&& physicalYDpi == other.physicalYDpi
|
||||
@@ -317,6 +328,10 @@ public final class DisplayInfo implements Parcelable {
|
||||
modeId = other.modeId;
|
||||
defaultModeId = other.defaultModeId;
|
||||
supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
|
||||
colorTransformId = other.colorTransformId;
|
||||
defaultColorTransformId = other.defaultColorTransformId;
|
||||
supportedColorTransforms = Arrays.copyOf(
|
||||
other.supportedColorTransforms, other.supportedColorTransforms.length);
|
||||
logicalDensityDpi = other.logicalDensityDpi;
|
||||
physicalXDpi = other.physicalXDpi;
|
||||
physicalYDpi = other.physicalYDpi;
|
||||
@@ -353,6 +368,13 @@ public final class DisplayInfo implements Parcelable {
|
||||
for (int i = 0; i < nModes; i++) {
|
||||
supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source);
|
||||
}
|
||||
colorTransformId = source.readInt();
|
||||
defaultColorTransformId = source.readInt();
|
||||
int nColorTransforms = source.readInt();
|
||||
supportedColorTransforms = new Display.ColorTransform[nColorTransforms];
|
||||
for (int i = 0; i < nColorTransforms; i++) {
|
||||
supportedColorTransforms[i] = Display.ColorTransform.CREATOR.createFromParcel(source);
|
||||
}
|
||||
logicalDensityDpi = source.readInt();
|
||||
physicalXDpi = source.readFloat();
|
||||
physicalYDpi = source.readFloat();
|
||||
@@ -390,6 +412,12 @@ public final class DisplayInfo implements Parcelable {
|
||||
for (int i = 0; i < supportedModes.length; i++) {
|
||||
supportedModes[i].writeToParcel(dest, flags);
|
||||
}
|
||||
dest.writeInt(colorTransformId);
|
||||
dest.writeInt(defaultColorTransformId);
|
||||
dest.writeInt(supportedColorTransforms.length);
|
||||
for (int i = 0; i < supportedColorTransforms.length; i++) {
|
||||
supportedColorTransforms[i].writeToParcel(dest, flags);
|
||||
}
|
||||
dest.writeInt(logicalDensityDpi);
|
||||
dest.writeFloat(physicalXDpi);
|
||||
dest.writeFloat(physicalYDpi);
|
||||
@@ -461,6 +489,24 @@ public final class DisplayInfo implements Parcelable {
|
||||
return result;
|
||||
}
|
||||
|
||||
public Display.ColorTransform getColorTransform() {
|
||||
return findColorTransform(colorTransformId);
|
||||
}
|
||||
|
||||
public Display.ColorTransform getDefaultColorTransform() {
|
||||
return findColorTransform(defaultColorTransformId);
|
||||
}
|
||||
|
||||
private Display.ColorTransform findColorTransform(int colorTransformId) {
|
||||
for (int i = 0; i < supportedColorTransforms.length; i++) {
|
||||
Display.ColorTransform colorTransform = supportedColorTransforms[i];
|
||||
if (colorTransform.getId() == colorTransformId) {
|
||||
return colorTransform;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Unable to locate color transform: " + colorTransformId);
|
||||
}
|
||||
|
||||
public void getAppMetrics(DisplayMetrics outMetrics) {
|
||||
getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
|
||||
}
|
||||
@@ -562,6 +608,12 @@ public final class DisplayInfo implements Parcelable {
|
||||
sb.append(defaultModeId);
|
||||
sb.append(", modes ");
|
||||
sb.append(Arrays.toString(supportedModes));
|
||||
sb.append(", colorTransformId ");
|
||||
sb.append(colorTransformId);
|
||||
sb.append(", defaultColorTransformId ");
|
||||
sb.append(defaultColorTransformId);
|
||||
sb.append(", supportedColorTransforms ");
|
||||
sb.append(Arrays.toString(supportedColorTransforms));
|
||||
sb.append(", rotation ");
|
||||
sb.append(rotation);
|
||||
sb.append(", density ");
|
||||
|
||||
@@ -2167,6 +2167,13 @@
|
||||
<permission android:name="android.permission.CONTROL_WIFI_DISPLAY"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<!-- Allows an application to control the color transforms applied to
|
||||
displays system-wide.
|
||||
<p>Not for use by third-party applications.</p>
|
||||
@hide -->
|
||||
<permission android:name="android.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<!-- @SystemApi Allows an application to control VPN.
|
||||
<p>Not for use by third-party applications.</p>
|
||||
@hide -->
|
||||
|
||||
@@ -1758,6 +1758,28 @@
|
||||
-->
|
||||
<bool name="config_enableWifiDisplay">false</bool>
|
||||
|
||||
<!-- The color transform values that correspond to each respective configuration mode for the
|
||||
built-in display, or -1 if the mode is unsupported by the device. The possible
|
||||
configuration modes are:
|
||||
1. Wide-gamut ("Vibrant")
|
||||
2. Adobe RGB ("Natural")
|
||||
3. sRGB ("Standard")
|
||||
|
||||
For example, if a device had Wide-gamut as color transform mode 1, sRGB mode as color
|
||||
transform mode 7, and did not support Adobe RGB at all this would look like:
|
||||
|
||||
<integer-array name="config_colorTransforms">
|
||||
<item>1</item>
|
||||
<item>-1</item>
|
||||
<item>7</item>
|
||||
</integer-array>
|
||||
-->
|
||||
<integer-array name="config_colorTransforms">
|
||||
<item>-1</item>
|
||||
<item>-1</item>
|
||||
<item>-1</item>
|
||||
</integer-array>
|
||||
|
||||
<!-- When true use the linux /dev/input/event subsystem to detect the switch changes
|
||||
on the headphone/microphone jack. When false use the older uevent framework. -->
|
||||
<bool name="config_useDevInputEventForAudioJack">false</bool>
|
||||
|
||||
@@ -1134,6 +1134,7 @@
|
||||
<java-symbol type="array" name="config_telephonyHardware" />
|
||||
<java-symbol type="array" name="config_keySystemUuidMapping" />
|
||||
<java-symbol type="array" name="config_gpsParameters" />
|
||||
<java-symbol type="array" name="config_colorTransforms" />
|
||||
|
||||
<java-symbol type="drawable" name="default_wallpaper" />
|
||||
<java-symbol type="drawable" name="indicator_input_error" />
|
||||
|
||||
@@ -49,6 +49,13 @@ abstract class DisplayAdapter {
|
||||
*/
|
||||
private static final AtomicInteger NEXT_DISPLAY_MODE_ID = new AtomicInteger(1); // 0 = no mode.
|
||||
|
||||
/**
|
||||
* Used to generate globally unique color transform ids.
|
||||
*
|
||||
* Valid IDs start at 1 with 0 as the sentinel value for the default mode.
|
||||
*/
|
||||
private static final AtomicInteger NEXT_COLOR_TRANSFORM_ID = new AtomicInteger(1);
|
||||
|
||||
// Called with SyncRoot lock held.
|
||||
public DisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
|
||||
Context context, Handler handler, Listener listener, String name) {
|
||||
@@ -134,6 +141,11 @@ abstract class DisplayAdapter {
|
||||
NEXT_DISPLAY_MODE_ID.getAndIncrement(), width, height, refreshRate);
|
||||
}
|
||||
|
||||
public static Display.ColorTransform createColorTransform(int colorTransform) {
|
||||
return new Display.ColorTransform(
|
||||
NEXT_COLOR_TRANSFORM_ID.getAndIncrement(), colorTransform);
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
public void onDisplayDeviceEvent(DisplayDevice device, int event);
|
||||
public void onTraversalRequested();
|
||||
|
||||
@@ -135,7 +135,7 @@ abstract class DisplayDevice {
|
||||
/**
|
||||
* Sets the mode, if supported.
|
||||
*/
|
||||
public void requestModeInTransactionLocked(int id) {
|
||||
public void requestColorTransformAndModeInTransactionLocked(int colorTransformId, int modeId) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -155,6 +155,15 @@ final class DisplayDeviceInfo {
|
||||
*/
|
||||
public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
|
||||
|
||||
/** The active color transform of the display */
|
||||
public int colorTransformId;
|
||||
|
||||
/** The default color transform of the display */
|
||||
public int defaultColorTransformId;
|
||||
|
||||
/** The supported color transforms of the display */
|
||||
public Display.ColorTransform[] supportedColorTransforms = Display.ColorTransform.EMPTY_ARRAY;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -276,6 +285,9 @@ final class DisplayDeviceInfo {
|
||||
|| modeId != other.modeId
|
||||
|| defaultModeId != other.defaultModeId
|
||||
|| !Arrays.equals(supportedModes, other.supportedModes)
|
||||
|| colorTransformId != other.colorTransformId
|
||||
|| defaultColorTransformId != other.defaultColorTransformId
|
||||
|| !Arrays.equals(supportedColorTransforms, other.supportedColorTransforms)
|
||||
|| densityDpi != other.densityDpi
|
||||
|| xDpi != other.xDpi
|
||||
|| yDpi != other.yDpi
|
||||
@@ -306,6 +318,9 @@ final class DisplayDeviceInfo {
|
||||
modeId = other.modeId;
|
||||
defaultModeId = other.defaultModeId;
|
||||
supportedModes = other.supportedModes;
|
||||
colorTransformId = other.colorTransformId;
|
||||
defaultColorTransformId = other.defaultColorTransformId;
|
||||
supportedColorTransforms = other.supportedColorTransforms;
|
||||
densityDpi = other.densityDpi;
|
||||
xDpi = other.xDpi;
|
||||
yDpi = other.yDpi;
|
||||
@@ -331,6 +346,9 @@ final class DisplayDeviceInfo {
|
||||
sb.append(", modeId ").append(modeId);
|
||||
sb.append(", defaultModeId ").append(defaultModeId);
|
||||
sb.append(", supportedModes ").append(Arrays.toString(supportedModes));
|
||||
sb.append(", colorTransformId ").append(colorTransformId);
|
||||
sb.append(", defaultColorTransformId ").append(defaultColorTransformId);
|
||||
sb.append(", supportedColorTransforms ").append(Arrays.toString(supportedColorTransforms));
|
||||
sb.append(", density ").append(densityDpi);
|
||||
sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
|
||||
sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
|
||||
|
||||
@@ -540,6 +540,17 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void requestColorTransformInternal(int displayId, int colorTransformId) {
|
||||
synchronized (mSyncRoot) {
|
||||
LogicalDisplay display = mLogicalDisplays.get(displayId);
|
||||
if (display != null &&
|
||||
display.getRequestedColorTransformIdLocked() != colorTransformId) {
|
||||
display.setRequestedColorTransformIdLocked(colorTransformId);
|
||||
scheduleTraversalLocked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
|
||||
IMediaProjection projection, int callingUid, String packageName,
|
||||
String name, int width, int height, int densityDpi, Surface surface, int flags) {
|
||||
@@ -1339,6 +1350,19 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void requestColorTransform(int displayId, int colorTransformId) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
Manifest.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM,
|
||||
"Permission required to change the display color transform");
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
requestColorTransformInternal(displayId, colorTransformId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public int createVirtualDisplay(IVirtualDisplayCallback callback,
|
||||
IMediaProjection projection, String packageName, String name,
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.os.SystemProperties;
|
||||
import android.os.Trace;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayEventReceiver;
|
||||
import android.view.Surface;
|
||||
@@ -38,6 +39,7 @@ import android.view.SurfaceControl;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A display adapter for the local displays managed by Surface Flinger.
|
||||
@@ -143,14 +145,22 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
private final int mBuiltInDisplayId;
|
||||
private final Light mBacklight;
|
||||
private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>();
|
||||
private final SparseArray<Display.ColorTransform> mSupportedColorTransforms =
|
||||
new SparseArray<>();
|
||||
|
||||
private DisplayDeviceInfo mInfo;
|
||||
private boolean mHavePendingChanges;
|
||||
private int mState = Display.STATE_UNKNOWN;
|
||||
private int mBrightness = PowerManager.BRIGHTNESS_DEFAULT;
|
||||
private int mActivePhysIndex;
|
||||
private int mDefaultModeId;
|
||||
private int mActiveModeId;
|
||||
private boolean mActiveModeInvalid;
|
||||
private int mDefaultColorTransformId;
|
||||
private int mActiveColorTransformId;
|
||||
private boolean mActiveColorTransformInvalid;
|
||||
|
||||
private SurfaceControl.PhysicalDisplayInfo mDisplayInfos[];
|
||||
|
||||
public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
|
||||
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
|
||||
@@ -167,22 +177,73 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
|
||||
public boolean updatePhysicalDisplayInfoLocked(
|
||||
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
|
||||
// Build an updated list of all existing modes.
|
||||
boolean modesAdded = false;
|
||||
DisplayModeRecord activeRecord = null;
|
||||
ArrayList<DisplayModeRecord> records = new ArrayList<DisplayModeRecord>();
|
||||
mDisplayInfos = Arrays.copyOf(physicalDisplayInfos, physicalDisplayInfos.length);
|
||||
mActivePhysIndex = activeDisplayInfo;
|
||||
ArrayList<Display.ColorTransform> colorTransforms = new ArrayList<>();
|
||||
|
||||
// Build an updated list of all existing color transforms.
|
||||
boolean colorTransformsAdded = false;
|
||||
Display.ColorTransform activeColorTransform = null;
|
||||
for (int i = 0; i < physicalDisplayInfos.length; i++) {
|
||||
SurfaceControl.PhysicalDisplayInfo info = physicalDisplayInfos[i];
|
||||
// First check to see if we've already added this color transform
|
||||
boolean existingMode = false;
|
||||
for (int j = 0; j < colorTransforms.size(); j++) {
|
||||
if (colorTransforms.get(j).getColorTransform() == info.colorTransform) {
|
||||
existingMode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (existingMode) {
|
||||
continue;
|
||||
}
|
||||
Display.ColorTransform colorTransform = findColorTransform(info);
|
||||
if (colorTransform == null) {
|
||||
colorTransform = createColorTransform(info.colorTransform);
|
||||
colorTransformsAdded = true;
|
||||
}
|
||||
colorTransforms.add(colorTransform);
|
||||
if (i == activeDisplayInfo) {
|
||||
activeColorTransform = colorTransform;
|
||||
}
|
||||
}
|
||||
|
||||
// Build an updated list of all existing modes.
|
||||
ArrayList<DisplayModeRecord> records = new ArrayList<DisplayModeRecord>();
|
||||
boolean modesAdded = false;
|
||||
for (int i = 0; i < physicalDisplayInfos.length; i++) {
|
||||
SurfaceControl.PhysicalDisplayInfo info = physicalDisplayInfos[i];
|
||||
// First, check to see if we've already added a matching mode. Since not all
|
||||
// configuration options are exposed via Display.Mode, it's possible that we have
|
||||
// multiple PhysicalDisplayInfos that would generate the same Display.Mode.
|
||||
boolean existingMode = false;
|
||||
for (int j = 0; j < records.size(); j++) {
|
||||
if (records.get(j).hasMatchingMode(info)) {
|
||||
existingMode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (existingMode) {
|
||||
continue;
|
||||
}
|
||||
// If we haven't already added a mode for this configuration to the new set of
|
||||
// supported modes then check to see if we have one in the prior set of supported
|
||||
// modes to reuse.
|
||||
DisplayModeRecord record = findDisplayModeRecord(info);
|
||||
if (record != null) {
|
||||
record.mPhysIndex = i;
|
||||
} else {
|
||||
record = new DisplayModeRecord(info, i);
|
||||
if (record == null) {
|
||||
record = new DisplayModeRecord(info);
|
||||
modesAdded = true;
|
||||
}
|
||||
records.add(record);
|
||||
if (i == activeDisplayInfo) {
|
||||
}
|
||||
|
||||
// Get the currently active mode
|
||||
DisplayModeRecord activeRecord = null;
|
||||
for (int i = 0; i < records.size(); i++) {
|
||||
DisplayModeRecord record = records.get(i);
|
||||
if (record.hasMatchingMode(physicalDisplayInfos[activeDisplayInfo])){
|
||||
activeRecord = record;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Check whether surface flinger spontaneously changed modes out from under us. Schedule
|
||||
@@ -192,25 +253,48 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
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) {
|
||||
// Check whether surface flinger spontaneously changed color transforms out from under
|
||||
// us.
|
||||
if (mActiveColorTransformId != 0
|
||||
&& mActiveColorTransformId != activeColorTransform.getId()) {
|
||||
mActiveColorTransformInvalid = true;
|
||||
sendTraversalRequestLocked();
|
||||
}
|
||||
|
||||
boolean colorTransformsChanged =
|
||||
colorTransforms.size() != mSupportedColorTransforms.size()
|
||||
|| colorTransformsAdded;
|
||||
boolean recordsChanged = records.size() != mSupportedModes.size() || modesAdded;
|
||||
// If neither the records nor the supported color transforms have changed then we're
|
||||
// done here.
|
||||
if (!recordsChanged && !colorTransformsChanged) {
|
||||
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) {
|
||||
mSupportedColorTransforms.clear();
|
||||
for (Display.ColorTransform colorTransform : colorTransforms) {
|
||||
mSupportedColorTransforms.put(colorTransform.getId(), colorTransform);
|
||||
}
|
||||
|
||||
// Update the default mode and color transform if needed. This needs to be done in
|
||||
// tandem so we always have a default state to fall back to.
|
||||
if (findDisplayInfoIndexLocked(mDefaultColorTransformId, mDefaultModeId) < 0) {
|
||||
if (mDefaultModeId != 0) {
|
||||
Slog.w(TAG, "Default display mode no longer available, using currently active"
|
||||
+ " mode as default.");
|
||||
Slog.w(TAG, "Default display mode no longer available, using currently"
|
||||
+ " active mode as default.");
|
||||
}
|
||||
mDefaultModeId = activeRecord.mMode.getModeId();
|
||||
if (mDefaultColorTransformId != 0) {
|
||||
Slog.w(TAG, "Default color transform no longer available, using currently"
|
||||
+ " active color transform as default");
|
||||
}
|
||||
mDefaultColorTransformId = activeColorTransform.getId();
|
||||
}
|
||||
// Determine whether the active mode is still there.
|
||||
if (mSupportedModes.indexOfKey(mActiveModeId) < 0) {
|
||||
@@ -221,6 +305,16 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
mActiveModeId = mDefaultModeId;
|
||||
mActiveModeInvalid = true;
|
||||
}
|
||||
|
||||
// Determine whether the active color transform is still there.
|
||||
if (mSupportedColorTransforms.indexOfKey(mActiveColorTransformId) < 0) {
|
||||
if (mActiveColorTransformId != 0) {
|
||||
Slog.w(TAG, "Active color transform no longer available, reverting"
|
||||
+ " to default transform.");
|
||||
}
|
||||
mActiveColorTransformId = mDefaultColorTransformId;
|
||||
mActiveColorTransformInvalid = true;
|
||||
}
|
||||
// Schedule traversals so that we apply pending changes.
|
||||
sendTraversalRequestLocked();
|
||||
return true;
|
||||
@@ -229,13 +323,23 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
private DisplayModeRecord findDisplayModeRecord(SurfaceControl.PhysicalDisplayInfo info) {
|
||||
for (int i = 0; i < mSupportedModes.size(); i++) {
|
||||
DisplayModeRecord record = mSupportedModes.valueAt(i);
|
||||
if (record.mPhys.equals(info)) {
|
||||
if (record.hasMatchingMode(info)) {
|
||||
return record;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Display.ColorTransform findColorTransform(SurfaceControl.PhysicalDisplayInfo info) {
|
||||
for (int i = 0; i < mSupportedColorTransforms.size(); i++) {
|
||||
Display.ColorTransform transform = mSupportedColorTransforms.valueAt(i);
|
||||
if (transform.getColorTransform() == info.colorTransform) {
|
||||
return transform;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyPendingDisplayDeviceInfoChangesLocked() {
|
||||
if (mHavePendingChanges) {
|
||||
@@ -247,7 +351,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
@Override
|
||||
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
|
||||
if (mInfo == null) {
|
||||
SurfaceControl.PhysicalDisplayInfo phys = mSupportedModes.get(mActiveModeId).mPhys;
|
||||
SurfaceControl.PhysicalDisplayInfo phys = mDisplayInfos[mActivePhysIndex];
|
||||
mInfo = new DisplayDeviceInfo();
|
||||
mInfo.width = phys.width;
|
||||
mInfo.height = phys.height;
|
||||
@@ -258,6 +362,13 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
DisplayModeRecord record = mSupportedModes.valueAt(i);
|
||||
mInfo.supportedModes[i] = record.mMode;
|
||||
}
|
||||
mInfo.colorTransformId = mActiveColorTransformId;
|
||||
mInfo.defaultColorTransformId = mDefaultColorTransformId;
|
||||
mInfo.supportedColorTransforms =
|
||||
new Display.ColorTransform[mSupportedColorTransforms.size()];
|
||||
for (int i = 0; i < mSupportedColorTransforms.size(); i++) {
|
||||
mInfo.supportedColorTransforms[i] = mSupportedColorTransforms.valueAt(i);
|
||||
}
|
||||
mInfo.appVsyncOffsetNanos = phys.appVsyncOffsetNanos;
|
||||
mInfo.presentationDeadlineNanos = phys.presentationDeadlineNanos;
|
||||
mInfo.state = mState;
|
||||
@@ -402,7 +513,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestModeInTransactionLocked(int modeId) {
|
||||
public void requestColorTransformAndModeInTransactionLocked(
|
||||
int colorTransformId, int modeId) {
|
||||
if (modeId == 0) {
|
||||
modeId = mDefaultModeId;
|
||||
} else if (mSupportedModes.indexOfKey(modeId) < 0) {
|
||||
@@ -410,13 +522,37 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
+ " reverting to default display mode.");
|
||||
modeId = mDefaultModeId;
|
||||
}
|
||||
if (mActiveModeId == modeId && !mActiveModeInvalid) {
|
||||
|
||||
if (colorTransformId == 0) {
|
||||
colorTransformId = mDefaultColorTransformId;
|
||||
} else if (mSupportedColorTransforms.indexOfKey(colorTransformId) < 0) {
|
||||
Slog.w(TAG, "Requested color transform " + colorTransformId + " is not supported"
|
||||
+ " by this display, reverting to the default color transform");
|
||||
colorTransformId = mDefaultColorTransformId;
|
||||
}
|
||||
int physIndex = findDisplayInfoIndexLocked(colorTransformId, modeId);
|
||||
if (physIndex < 0) {
|
||||
Slog.w(TAG, "Requested color transform, mode ID pair (" + colorTransformId + ", "
|
||||
+ modeId + ") not available, trying color transform with default mode ID");
|
||||
modeId = mDefaultModeId;
|
||||
physIndex = findDisplayInfoIndexLocked(colorTransformId, modeId);
|
||||
if (physIndex < 0) {
|
||||
Slog.w(TAG, "Requested color transform with default mode ID still not"
|
||||
+ " available, falling back to default color transform with default"
|
||||
+ " mode.");
|
||||
colorTransformId = mDefaultColorTransformId;
|
||||
physIndex = findDisplayInfoIndexLocked(colorTransformId, modeId);
|
||||
}
|
||||
}
|
||||
if (physIndex > 0 && mActivePhysIndex == physIndex) {
|
||||
return;
|
||||
}
|
||||
DisplayModeRecord record = mSupportedModes.get(modeId);
|
||||
SurfaceControl.setActiveConfig(getDisplayTokenLocked(), record.mPhysIndex);
|
||||
SurfaceControl.setActiveConfig(getDisplayTokenLocked(), physIndex);
|
||||
mActivePhysIndex = physIndex;
|
||||
mActiveModeId = modeId;
|
||||
mActiveModeInvalid = false;
|
||||
mActiveColorTransformId = colorTransformId;
|
||||
mActiveColorTransformInvalid = false;
|
||||
updateDeviceInfoLocked();
|
||||
}
|
||||
|
||||
@@ -424,10 +560,43 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
public void dumpLocked(PrintWriter pw) {
|
||||
super.dumpLocked(pw);
|
||||
pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
|
||||
pw.println("mActivePhysIndex=" + mActivePhysIndex);
|
||||
pw.println("mActiveModeId=" + mActiveModeId);
|
||||
pw.println("mActiveColorTransformId=" + mActiveColorTransformId);
|
||||
pw.println("mState=" + Display.stateToString(mState));
|
||||
pw.println("mBrightness=" + mBrightness);
|
||||
pw.println("mBacklight=" + mBacklight);
|
||||
pw.println("mDisplayInfos=");
|
||||
for (int i = 0; i < mDisplayInfos.length; i++) {
|
||||
pw.println(" " + mDisplayInfos[i]);
|
||||
}
|
||||
pw.println("mSupportedModes=");
|
||||
for (int i = 0; i < mSupportedModes.size(); i++) {
|
||||
pw.println(" " + mSupportedModes.valueAt(i));
|
||||
}
|
||||
pw.println("mSupportedColorTransforms=[");
|
||||
for (int i = 0; i < mSupportedColorTransforms.size(); i++) {
|
||||
if (i != 0) {
|
||||
pw.print(", ");
|
||||
}
|
||||
pw.print(mSupportedColorTransforms.valueAt(i));
|
||||
}
|
||||
pw.println("]");
|
||||
}
|
||||
|
||||
private int findDisplayInfoIndexLocked(int colorTransformId, int modeId) {
|
||||
DisplayModeRecord record = mSupportedModes.get(modeId);
|
||||
Display.ColorTransform transform = mSupportedColorTransforms.get(colorTransformId);
|
||||
if (record != null && transform != null) {
|
||||
for (int i = 0; i < mDisplayInfos.length; i++) {
|
||||
SurfaceControl.PhysicalDisplayInfo info = mDisplayInfos[i];
|
||||
if (info.colorTransform == transform.getColorTransform()
|
||||
&& record.hasMatchingMode(info)){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void updateDeviceInfoLocked() {
|
||||
@@ -441,13 +610,28 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
*/
|
||||
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) {
|
||||
public DisplayModeRecord(SurfaceControl.PhysicalDisplayInfo phys) {
|
||||
mMode = createMode(phys.width, phys.height, phys.refreshRate);
|
||||
mPhys = phys;
|
||||
mPhysIndex = physIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the mode generated by the given PhysicalDisplayInfo matches the mode
|
||||
* contained by the record modulo mode ID.
|
||||
*
|
||||
* Note that this doesn't necessarily mean the the PhysicalDisplayInfos are identical, just
|
||||
* that they generate identical modes.
|
||||
*/
|
||||
public boolean hasMatchingMode(SurfaceControl.PhysicalDisplayInfo info) {
|
||||
int modeRefreshRate = Float.floatToIntBits(mMode.getRefreshRate());
|
||||
int displayInfoRefreshRate = Float.floatToIntBits(info.refreshRate);
|
||||
return mMode.getPhysicalWidth() == info.width
|
||||
&& mMode.getPhysicalHeight() == info.height
|
||||
&& modeRefreshRate == displayInfoRefreshRate;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "DisplayModeRecord{mMode=" + mMode + "}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ final class LogicalDisplay {
|
||||
private boolean mHasContent;
|
||||
|
||||
private int mRequestedModeId;
|
||||
private int mRequestedColorTransformId;
|
||||
|
||||
// The display offsets to apply to the display projection.
|
||||
private int mDisplayOffsetX;
|
||||
@@ -235,6 +236,11 @@ final class LogicalDisplay {
|
||||
mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
|
||||
mBaseDisplayInfo.supportedModes = Arrays.copyOf(
|
||||
deviceInfo.supportedModes, deviceInfo.supportedModes.length);
|
||||
mBaseDisplayInfo.colorTransformId = deviceInfo.colorTransformId;
|
||||
mBaseDisplayInfo.defaultColorTransformId = deviceInfo.defaultColorTransformId;
|
||||
mBaseDisplayInfo.supportedColorTransforms = Arrays.copyOf(
|
||||
deviceInfo.supportedColorTransforms,
|
||||
deviceInfo.supportedColorTransforms.length);
|
||||
mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
|
||||
mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
|
||||
mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
|
||||
@@ -275,11 +281,12 @@ final class LogicalDisplay {
|
||||
// Set the layer stack.
|
||||
device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack);
|
||||
|
||||
// Set the mode.
|
||||
// Set the color transform and mode.
|
||||
if (device == mPrimaryDisplayDevice) {
|
||||
device.requestModeInTransactionLocked(mRequestedModeId);
|
||||
device.requestColorTransformAndModeInTransactionLocked(
|
||||
mRequestedColorTransformId, mRequestedModeId);
|
||||
} else {
|
||||
device.requestModeInTransactionLocked(0); // Revert to default.
|
||||
device.requestColorTransformAndModeInTransactionLocked(0, 0); // Revert to default.
|
||||
}
|
||||
|
||||
// Only grab the display info now as it may have been changed based on the requests above.
|
||||
@@ -382,6 +389,18 @@ final class LogicalDisplay {
|
||||
return mRequestedModeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the given color transform.
|
||||
*/
|
||||
public void setRequestedColorTransformIdLocked(int colorTransformId) {
|
||||
mRequestedColorTransformId = colorTransformId;
|
||||
}
|
||||
|
||||
/** Returns the pending requested color transform. */
|
||||
public int getRequestedColorTransformIdLocked() {
|
||||
return mRequestedColorTransformId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the burn-in offset in X.
|
||||
*/
|
||||
@@ -409,6 +428,7 @@ final class LogicalDisplay {
|
||||
pw.println("mLayerStack=" + mLayerStack);
|
||||
pw.println("mHasContent=" + mHasContent);
|
||||
pw.println("mRequestedMode=" + mRequestedModeId);
|
||||
pw.println("mRequestedColorTransformId=" + mRequestedColorTransformId);
|
||||
pw.println("mDisplayOffset=(" + mDisplayOffsetX + ", " + mDisplayOffsetY + ")");
|
||||
pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null ?
|
||||
mPrimaryDisplayDevice.getNameLocked() : "null"));
|
||||
|
||||
@@ -310,7 +310,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestModeInTransactionLocked(int id) {
|
||||
public void requestColorTransformAndModeInTransactionLocked(int color, int id) {
|
||||
int index = -1;
|
||||
if (id == 0) {
|
||||
// Use the default.
|
||||
|
||||
Reference in New Issue
Block a user