1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.display;
18 
19 import android.graphics.Point;
20 import android.graphics.Rect;
21 import android.hardware.display.DisplayManagerInternal;
22 import android.view.Display;
23 import android.view.DisplayInfo;
24 import android.view.Surface;
25 import android.view.SurfaceControl;
26 
27 import com.android.server.wm.utils.InsetUtils;
28 
29 import java.io.PrintWriter;
30 import java.util.Arrays;
31 import java.util.List;
32 import java.util.Objects;
33 
34 /**
35  * Describes how a logical display is configured.
36  * <p>
37  * At this time, we only support logical displays that are coupled to a particular
38  * primary display device from which the logical display derives its basic properties
39  * such as its size, density and refresh rate.
40  * </p><p>
41  * A logical display may be mirrored onto multiple display devices in addition to its
42  * primary display device.  Note that the contents of a logical display may not
43  * always be visible, even on its primary display device, such as in the case where
44  * the primary display device is currently mirroring content from a different
45  * logical display.
46  * </p><p>
47  * This object is designed to encapsulate as much of the policy of logical
48  * displays as possible.  The idea is to make it easy to implement new kinds of
49  * logical displays mostly by making local changes to this class.
50  * </p><p>
51  * Note: The display manager architecture does not actually require logical displays
52  * to be associated with any individual display device.  Logical displays and
53  * display devices are orthogonal concepts.  Some mapping will exist between
54  * logical displays and display devices but it can be many-to-many and
55  * and some might have no relation at all.
56  * </p><p>
57  * Logical displays are guarded by the {@link DisplayManagerService.SyncRoot} lock.
58  * </p>
59  */
60 final class LogicalDisplay {
61     private final DisplayInfo mBaseDisplayInfo = new DisplayInfo();
62 
63     // The layer stack we use when the display has been blanked to prevent any
64     // of its content from appearing.
65     private static final int BLANK_LAYER_STACK = -1;
66 
67     private final int mDisplayId;
68     private final int mLayerStack;
69     /**
70      * Override information set by the window manager. Will be reported instead of {@link #mInfo}
71      * if not null.
72      * @see #setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo)
73      * @see #getDisplayInfoLocked()
74      */
75     private DisplayInfo mOverrideDisplayInfo;
76     /**
77      * Current display info. Initialized with {@link #mBaseDisplayInfo}. Set to {@code null} if
78      * needs to be updated.
79      * @see #getDisplayInfoLocked()
80      */
81     private final DisplayInfoProxy mInfo = new DisplayInfoProxy(null);
82 
83     // The display device that this logical display is based on and which
84     // determines the base metrics that it uses.
85     private DisplayDevice mPrimaryDisplayDevice;
86     private DisplayDeviceInfo mPrimaryDisplayDeviceInfo;
87 
88     // True if the logical display has unique content.
89     private boolean mHasContent;
90 
91     private int mRequestedColorMode;
92     private boolean mRequestedMinimalPostProcessing;
93 
94     private DisplayModeDirector.DesiredDisplayModeSpecs mDesiredDisplayModeSpecs =
95             new DisplayModeDirector.DesiredDisplayModeSpecs();
96 
97     // The display offsets to apply to the display projection.
98     private int mDisplayOffsetX;
99     private int mDisplayOffsetY;
100 
101     /**
102      * The position of the display projection sent to SurfaceFlinger
103      */
104     private final Point mDisplayPosition = new Point();
105 
106     /**
107      * {@code true} if display scaling is disabled, or {@code false} if the default scaling mode
108      * is used.
109      * @see #isDisplayScalingDisabled()
110      * @see #setDisplayScalingDisabledLocked(boolean)
111      */
112     private boolean mDisplayScalingDisabled;
113 
114     // Temporary rectangle used when needed.
115     private final Rect mTempLayerStackRect = new Rect();
116     private final Rect mTempDisplayRect = new Rect();
117 
LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice)118     public LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) {
119         mDisplayId = displayId;
120         mLayerStack = layerStack;
121         mPrimaryDisplayDevice = primaryDisplayDevice;
122     }
123 
124     /**
125      * Gets the logical display id of this logical display.
126      *
127      * @return The logical display id.
128      */
getDisplayIdLocked()129     public int getDisplayIdLocked() {
130         return mDisplayId;
131     }
132 
133     /**
134      * Gets the primary display device associated with this logical display.
135      *
136      * @return The primary display device.
137      */
getPrimaryDisplayDeviceLocked()138     public DisplayDevice getPrimaryDisplayDeviceLocked() {
139         return mPrimaryDisplayDevice;
140     }
141 
142     /**
143      * Gets information about the logical display.
144      *
145      * @return The device info, which should be treated as immutable by the caller.
146      * The logical display should allocate a new display info object whenever
147      * the data changes.
148      */
getDisplayInfoLocked()149     public DisplayInfo getDisplayInfoLocked() {
150         if (mInfo.get() == null) {
151             DisplayInfo info = new DisplayInfo();
152             info.copyFrom(mBaseDisplayInfo);
153             if (mOverrideDisplayInfo != null) {
154                 info.appWidth = mOverrideDisplayInfo.appWidth;
155                 info.appHeight = mOverrideDisplayInfo.appHeight;
156                 info.smallestNominalAppWidth = mOverrideDisplayInfo.smallestNominalAppWidth;
157                 info.smallestNominalAppHeight = mOverrideDisplayInfo.smallestNominalAppHeight;
158                 info.largestNominalAppWidth = mOverrideDisplayInfo.largestNominalAppWidth;
159                 info.largestNominalAppHeight = mOverrideDisplayInfo.largestNominalAppHeight;
160                 info.logicalWidth = mOverrideDisplayInfo.logicalWidth;
161                 info.logicalHeight = mOverrideDisplayInfo.logicalHeight;
162                 info.rotation = mOverrideDisplayInfo.rotation;
163                 info.displayCutout = mOverrideDisplayInfo.displayCutout;
164                 info.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi;
165                 info.physicalXDpi = mOverrideDisplayInfo.physicalXDpi;
166                 info.physicalYDpi = mOverrideDisplayInfo.physicalYDpi;
167             }
168             mInfo.set(info);
169         }
170         return mInfo.get();
171     }
172 
173     /**
174      * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo)
175      */
getNonOverrideDisplayInfoLocked(DisplayInfo outInfo)176     void getNonOverrideDisplayInfoLocked(DisplayInfo outInfo) {
177         outInfo.copyFrom(mBaseDisplayInfo);
178     }
179 
180     /**
181      * Sets overridden logical display information from the window manager.
182      * This method can be used to adjust application insets, rotation, and other
183      * properties that the window manager takes care of.
184      *
185      * @param info The logical display information, may be null.
186      */
setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo info)187     public boolean setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo info) {
188         if (info != null) {
189             if (mOverrideDisplayInfo == null) {
190                 mOverrideDisplayInfo = new DisplayInfo(info);
191                 mInfo.set(null);
192                 return true;
193             } else if (!mOverrideDisplayInfo.equals(info)) {
194                 mOverrideDisplayInfo.copyFrom(info);
195                 mInfo.set(null);
196                 return true;
197             }
198         } else if (mOverrideDisplayInfo != null) {
199             mOverrideDisplayInfo = null;
200             mInfo.set(null);
201             return true;
202         }
203         return false;
204     }
205 
206     /**
207      * Returns true if the logical display is in a valid state.
208      * This method should be checked after calling {@link #updateLocked} to handle the
209      * case where a logical display should be removed because all of its associated
210      * display devices are gone or if it is otherwise no longer needed.
211      *
212      * @return True if the logical display is still valid.
213      */
isValidLocked()214     public boolean isValidLocked() {
215         return mPrimaryDisplayDevice != null;
216     }
217 
218     /**
219      * Updates the state of the logical display based on the available display devices.
220      * The logical display might become invalid if it is attached to a display device
221      * that no longer exists.
222      *
223      * @param devices The list of all connected display devices.
224      */
updateLocked(List<DisplayDevice> devices)225     public void updateLocked(List<DisplayDevice> devices) {
226         // Nothing to update if already invalid.
227         if (mPrimaryDisplayDevice == null) {
228             return;
229         }
230 
231         // Check whether logical display has become invalid.
232         if (!devices.contains(mPrimaryDisplayDevice)) {
233             mPrimaryDisplayDevice = null;
234             return;
235         }
236 
237         // Bootstrap the logical display using its associated primary physical display.
238         // We might use more elaborate configurations later.  It's possible that the
239         // configuration of several physical displays might be used to determine the
240         // logical display that they are sharing.  (eg. Adjust size for pixel-perfect
241         // mirroring over HDMI.)
242         DisplayDeviceInfo deviceInfo = mPrimaryDisplayDevice.getDisplayDeviceInfoLocked();
243         if (!Objects.equals(mPrimaryDisplayDeviceInfo, deviceInfo)) {
244             mBaseDisplayInfo.layerStack = mLayerStack;
245             mBaseDisplayInfo.flags = 0;
246             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
247                 mBaseDisplayInfo.flags |= Display.FLAG_SUPPORTS_PROTECTED_BUFFERS;
248             }
249             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SECURE) != 0) {
250                 mBaseDisplayInfo.flags |= Display.FLAG_SECURE;
251             }
252             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0) {
253                 mBaseDisplayInfo.flags |= Display.FLAG_PRIVATE;
254                 // For private displays by default content is destroyed on removal.
255                 mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_DESTROY_CONTENT;
256             }
257             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_DESTROY_CONTENT_ON_REMOVAL) != 0) {
258                 mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_DESTROY_CONTENT;
259             }
260             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRESENTATION) != 0) {
261                 mBaseDisplayInfo.flags |= Display.FLAG_PRESENTATION;
262             }
263             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ROUND) != 0) {
264                 mBaseDisplayInfo.flags |= Display.FLAG_ROUND;
265             }
266             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
267                 mBaseDisplayInfo.flags |= Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
268             }
269             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
270                 mBaseDisplayInfo.flags |= Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
271             }
272             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TRUSTED) != 0) {
273                 mBaseDisplayInfo.flags |= Display.FLAG_TRUSTED;
274             }
275             Rect maskingInsets = getMaskingInsets(deviceInfo);
276             int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right;
277             int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom;
278 
279             mBaseDisplayInfo.type = deviceInfo.type;
280             mBaseDisplayInfo.address = deviceInfo.address;
281             mBaseDisplayInfo.deviceProductInfo = deviceInfo.deviceProductInfo;
282             mBaseDisplayInfo.name = deviceInfo.name;
283             mBaseDisplayInfo.uniqueId = deviceInfo.uniqueId;
284             mBaseDisplayInfo.appWidth = maskedWidth;
285             mBaseDisplayInfo.appHeight = maskedHeight;
286             mBaseDisplayInfo.logicalWidth = maskedWidth;
287             mBaseDisplayInfo.logicalHeight = maskedHeight;
288             mBaseDisplayInfo.rotation = Surface.ROTATION_0;
289             mBaseDisplayInfo.modeId = deviceInfo.modeId;
290             mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
291             mBaseDisplayInfo.supportedModes = Arrays.copyOf(
292                     deviceInfo.supportedModes, deviceInfo.supportedModes.length);
293             mBaseDisplayInfo.colorMode = deviceInfo.colorMode;
294             mBaseDisplayInfo.supportedColorModes = Arrays.copyOf(
295                     deviceInfo.supportedColorModes,
296                     deviceInfo.supportedColorModes.length);
297             mBaseDisplayInfo.hdrCapabilities = deviceInfo.hdrCapabilities;
298             mBaseDisplayInfo.minimalPostProcessingSupported =
299                     deviceInfo.allmSupported || deviceInfo.gameContentTypeSupported;
300             mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
301             mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
302             mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
303             mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos;
304             mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos;
305             mBaseDisplayInfo.state = deviceInfo.state;
306             mBaseDisplayInfo.smallestNominalAppWidth = maskedWidth;
307             mBaseDisplayInfo.smallestNominalAppHeight = maskedHeight;
308             mBaseDisplayInfo.largestNominalAppWidth = maskedWidth;
309             mBaseDisplayInfo.largestNominalAppHeight = maskedHeight;
310             mBaseDisplayInfo.ownerUid = deviceInfo.ownerUid;
311             mBaseDisplayInfo.ownerPackageName = deviceInfo.ownerPackageName;
312             boolean maskCutout =
313                     (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0;
314             mBaseDisplayInfo.displayCutout = maskCutout ? null : deviceInfo.displayCutout;
315             mBaseDisplayInfo.displayId = mDisplayId;
316 
317             mPrimaryDisplayDeviceInfo = deviceInfo;
318             mInfo.set(null);
319         }
320     }
321 
322     /**
323      * Return the insets currently applied to the display.
324      *
325      * Note that the base DisplayInfo already takes these insets into account, so if you want to
326      * find out the <b>true</b> size of the display, you need to add them back to the logical
327      * dimensions.
328      */
getInsets()329     public Rect getInsets() {
330         return getMaskingInsets(mPrimaryDisplayDeviceInfo);
331     }
332 
333     /**
334      * Returns insets in ROTATION_0 for areas that are masked.
335      */
getMaskingInsets(DisplayDeviceInfo deviceInfo)336     private static Rect getMaskingInsets(DisplayDeviceInfo deviceInfo) {
337         boolean maskCutout = (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0;
338         if (maskCutout && deviceInfo.displayCutout != null) {
339             // getSafeInsets is fixed at creation time and cannot change
340             return deviceInfo.displayCutout.getSafeInsets();
341         } else {
342             return new Rect();
343         }
344     }
345 
346     /**
347      * Returns the position of the display's projection.
348      *
349      * @return The x, y coordinates of the display. The return object must be treated as immutable.
350      */
getDisplayPosition()351     Point getDisplayPosition() {
352         // Allocate a new object to avoid a data race.
353         return new Point(mDisplayPosition);
354     }
355 
356     /**
357      * Applies the layer stack and transformation to the given display device
358      * so that it shows the contents of this logical display.
359      *
360      * We know that the given display device is only ever showing the contents of
361      * a single logical display, so this method is expected to blow away all of its
362      * transformation properties to make it happen regardless of what the
363      * display device was previously showing.
364      *
365      * The caller must have an open Surface transaction.
366      *
367      * The display device may not be the primary display device, in the case
368      * where the display is being mirrored.
369      *
370      * @param device The display device to modify.
371      * @param isBlanked True if the device is being blanked.
372      */
configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device, boolean isBlanked)373     public void configureDisplayLocked(SurfaceControl.Transaction t,
374             DisplayDevice device,
375             boolean isBlanked) {
376         // Set the layer stack.
377         device.setLayerStackLocked(t, isBlanked ? BLANK_LAYER_STACK : mLayerStack);
378 
379         // Set the color mode and allowed display mode.
380         if (device == mPrimaryDisplayDevice) {
381             device.setDesiredDisplayModeSpecsLocked(mDesiredDisplayModeSpecs);
382             device.setRequestedColorModeLocked(mRequestedColorMode);
383         } else {
384             // Reset to default for non primary displays
385             device.setDesiredDisplayModeSpecsLocked(
386                     new DisplayModeDirector.DesiredDisplayModeSpecs());
387             device.setRequestedColorModeLocked(0);
388         }
389 
390         device.setAutoLowLatencyModeLocked(mRequestedMinimalPostProcessing);
391         device.setGameContentTypeLocked(mRequestedMinimalPostProcessing);
392 
393         // Only grab the display info now as it may have been changed based on the requests above.
394         final DisplayInfo displayInfo = getDisplayInfoLocked();
395         final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked();
396 
397         // Set the viewport.
398         // This is the area of the logical display that we intend to show on the
399         // display device.  For now, it is always the full size of the logical display.
400         mTempLayerStackRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
401 
402         // Set the orientation.
403         // The orientation specifies how the physical coordinate system of the display
404         // is rotated when the contents of the logical display are rendered.
405         int orientation = Surface.ROTATION_0;
406         if ((displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) {
407             orientation = displayInfo.rotation;
408         }
409 
410         // Apply the physical rotation of the display device itself.
411         orientation = (orientation + displayDeviceInfo.rotation) % 4;
412 
413         // Set the frame.
414         // The frame specifies the rotated physical coordinates into which the viewport
415         // is mapped.  We need to take care to preserve the aspect ratio of the viewport.
416         // Currently we maximize the area to fill the display, but we could try to be
417         // more clever and match resolutions.
418         boolean rotated = (orientation == Surface.ROTATION_90
419                 || orientation == Surface.ROTATION_270);
420         int physWidth = rotated ? displayDeviceInfo.height : displayDeviceInfo.width;
421         int physHeight = rotated ? displayDeviceInfo.width : displayDeviceInfo.height;
422 
423         Rect maskingInsets = getMaskingInsets(displayDeviceInfo);
424         InsetUtils.rotateInsets(maskingInsets, orientation);
425         // Don't consider the masked area as available when calculating the scaling below.
426         physWidth -= maskingInsets.left + maskingInsets.right;
427         physHeight -= maskingInsets.top + maskingInsets.bottom;
428 
429         // Determine whether the width or height is more constrained to be scaled.
430         //    physWidth / displayInfo.logicalWidth    => letter box
431         // or physHeight / displayInfo.logicalHeight  => pillar box
432         //
433         // We avoid a division (and possible floating point imprecision) here by
434         // multiplying the fractions by the product of their denominators before
435         // comparing them.
436         int displayRectWidth, displayRectHeight;
437         if ((displayInfo.flags & Display.FLAG_SCALING_DISABLED) != 0 || mDisplayScalingDisabled) {
438             displayRectWidth = displayInfo.logicalWidth;
439             displayRectHeight = displayInfo.logicalHeight;
440         } else if (physWidth * displayInfo.logicalHeight
441                 < physHeight * displayInfo.logicalWidth) {
442             // Letter box.
443             displayRectWidth = physWidth;
444             displayRectHeight = displayInfo.logicalHeight * physWidth / displayInfo.logicalWidth;
445         } else {
446             // Pillar box.
447             displayRectWidth = displayInfo.logicalWidth * physHeight / displayInfo.logicalHeight;
448             displayRectHeight = physHeight;
449         }
450         int displayRectTop = (physHeight - displayRectHeight) / 2;
451         int displayRectLeft = (physWidth - displayRectWidth) / 2;
452         mTempDisplayRect.set(displayRectLeft, displayRectTop,
453                 displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight);
454 
455         // Now add back the offset for the masked area.
456         mTempDisplayRect.offset(maskingInsets.left, maskingInsets.top);
457 
458         if (orientation == Surface.ROTATION_0) {
459             mTempDisplayRect.offset(mDisplayOffsetX, mDisplayOffsetY);
460         } else if (orientation == Surface.ROTATION_90) {
461             mTempDisplayRect.offset(mDisplayOffsetY, -mDisplayOffsetX);
462         } else if (orientation == Surface.ROTATION_180) {
463             mTempDisplayRect.offset(-mDisplayOffsetX, -mDisplayOffsetY);
464         } else {  // Surface.ROTATION_270
465             mTempDisplayRect.offset(-mDisplayOffsetY, mDisplayOffsetX);
466         }
467 
468         mDisplayPosition.set(mTempDisplayRect.left, mTempDisplayRect.top);
469         device.setProjectionLocked(t, orientation, mTempLayerStackRect, mTempDisplayRect);
470     }
471 
472     /**
473      * Returns true if the logical display has unique content.
474      * <p>
475      * If the display has unique content then we will try to ensure that it is
476      * visible on at least its primary display device.  Otherwise we will ignore the
477      * logical display and perhaps show mirrored content on the primary display device.
478      * </p>
479      *
480      * @return True if the display has unique content.
481      */
hasContentLocked()482     public boolean hasContentLocked() {
483         return mHasContent;
484     }
485 
486     /**
487      * Sets whether the logical display has unique content.
488      *
489      * @param hasContent True if the display has unique content.
490      */
setHasContentLocked(boolean hasContent)491     public void setHasContentLocked(boolean hasContent) {
492         mHasContent = hasContent;
493     }
494 
495     /**
496      * Sets the display configs the system can use.
497      */
setDesiredDisplayModeSpecsLocked( DisplayModeDirector.DesiredDisplayModeSpecs specs)498     public void setDesiredDisplayModeSpecsLocked(
499             DisplayModeDirector.DesiredDisplayModeSpecs specs) {
500         mDesiredDisplayModeSpecs = specs;
501     }
502 
503     /**
504      * Returns the display configs the system can choose.
505      */
getDesiredDisplayModeSpecsLocked()506     public DisplayModeDirector.DesiredDisplayModeSpecs getDesiredDisplayModeSpecsLocked() {
507         return mDesiredDisplayModeSpecs;
508     }
509 
510     /**
511      * Requests the given color mode.
512      */
setRequestedColorModeLocked(int colorMode)513     public void setRequestedColorModeLocked(int colorMode) {
514         mRequestedColorMode = colorMode;
515     }
516 
517     /**
518      * Returns the last requested minimal post processing setting.
519      */
getRequestedMinimalPostProcessingLocked()520     public boolean getRequestedMinimalPostProcessingLocked() {
521         return mRequestedMinimalPostProcessing;
522     }
523 
524     /**
525      * Instructs the connected display to do minimal post processing. This is implemented either
526      * via HDMI 2.1 ALLM or HDMI 1.4 ContentType=Game.
527      *
528      * @param on Whether to set minimal post processing on/off on the connected display.
529      */
setRequestedMinimalPostProcessingLocked(boolean on)530     public void setRequestedMinimalPostProcessingLocked(boolean on) {
531         mRequestedMinimalPostProcessing = on;
532     }
533 
534     /** Returns the pending requested color mode. */
getRequestedColorModeLocked()535     public int getRequestedColorModeLocked() {
536         return mRequestedColorMode;
537     }
538 
539     /**
540      * Gets the burn-in offset in X.
541      */
getDisplayOffsetXLocked()542     public int getDisplayOffsetXLocked() {
543         return mDisplayOffsetX;
544     }
545 
546     /**
547      * Gets the burn-in offset in Y.
548      */
getDisplayOffsetYLocked()549     public int getDisplayOffsetYLocked() {
550         return mDisplayOffsetY;
551     }
552 
553     /**
554      * Sets the burn-in offsets.
555      */
setDisplayOffsetsLocked(int x, int y)556     public void setDisplayOffsetsLocked(int x, int y) {
557         mDisplayOffsetX = x;
558         mDisplayOffsetY = y;
559     }
560 
561     /**
562      * @return {@code true} if display scaling is disabled, or {@code false} if the default scaling
563      * mode is used.
564      */
isDisplayScalingDisabled()565     public boolean isDisplayScalingDisabled() {
566         return mDisplayScalingDisabled;
567     }
568 
569     /**
570      * Disables scaling for a display.
571      *
572      * @param disableScaling {@code true} to disable scaling,
573      * {@code false} to use the default scaling behavior of the logical display.
574      */
setDisplayScalingDisabledLocked(boolean disableScaling)575     public void setDisplayScalingDisabledLocked(boolean disableScaling) {
576         mDisplayScalingDisabled = disableScaling;
577     }
578 
dumpLocked(PrintWriter pw)579     public void dumpLocked(PrintWriter pw) {
580         pw.println("mDisplayId=" + mDisplayId);
581         pw.println("mLayerStack=" + mLayerStack);
582         pw.println("mHasContent=" + mHasContent);
583         pw.println("mDesiredDisplayModeSpecs={" + mDesiredDisplayModeSpecs + "}");
584         pw.println("mRequestedColorMode=" + mRequestedColorMode);
585         pw.println("mDisplayOffset=(" + mDisplayOffsetX + ", " + mDisplayOffsetY + ")");
586         pw.println("mDisplayScalingDisabled=" + mDisplayScalingDisabled);
587         pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null ?
588                 mPrimaryDisplayDevice.getNameLocked() : "null"));
589         pw.println("mBaseDisplayInfo=" + mBaseDisplayInfo);
590         pw.println("mOverrideDisplayInfo=" + mOverrideDisplayInfo);
591         pw.println("mRequestedMinimalPostProcessing=" + mRequestedMinimalPostProcessing);
592     }
593 }
594