Advertisement
Guest User

Untitled

a guest
Jan 21st, 2017
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.23 KB | None | 0 0
  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.content.res.Resources;
  20. import android.graphics.Rect;
  21. import android.view.Display;
  22. import android.view.DisplayInfo;
  23. import android.view.Surface;
  24.  
  25. import java.io.PrintWriter;
  26. import java.util.Arrays;
  27. import java.util.List;
  28.  
  29. import libcore.util.Objects;
  30.  
  31. /**
  32. * Describes how a logical display is configured.
  33. * <p>
  34. * At this time, we only support logical displays that are coupled to a particular
  35. * primary display device from which the logical display derives its basic properties
  36. * such as its size, density and refresh rate.
  37. * </p><p>
  38. * A logical display may be mirrored onto multiple display devices in addition to its
  39. * primary display device. Note that the contents of a logical display may not
  40. * always be visible, even on its primary display device, such as in the case where
  41. * the primary display device is currently mirroring content from a different
  42. * logical display.
  43. * </p><p>
  44. * This object is designed to encapsulate as much of the policy of logical
  45. * displays as possible. The idea is to make it easy to implement new kinds of
  46. * logical displays mostly by making local changes to this class.
  47. * </p><p>
  48. * Note: The display manager architecture does not actually require logical displays
  49. * to be associated with any individual display device. Logical displays and
  50. * display devices are orthogonal concepts. Some mapping will exist between
  51. * logical displays and display devices but it can be many-to-many and
  52. * and some might have no relation at all.
  53. * </p><p>
  54. * Logical displays are guarded by the {@link DisplayManagerService.SyncRoot} lock.
  55. * </p>
  56. */
  57. final class LogicalDisplay {
  58. private final DisplayInfo mBaseDisplayInfo = new DisplayInfo();
  59.  
  60. // The layer stack we use when the display has been blanked to prevent any
  61. // of its content from appearing.
  62. private static final int BLANK_LAYER_STACK = -1;
  63.  
  64. private final int mDisplayId;
  65. private final int mLayerStack;
  66. private DisplayInfo mOverrideDisplayInfo; // set by the window manager
  67. private DisplayInfo mInfo;
  68.  
  69. // The display device that this logical display is based on and which
  70. // determines the base metrics that it uses.
  71. private DisplayDevice mPrimaryDisplayDevice;
  72. private DisplayDeviceInfo mPrimaryDisplayDeviceInfo;
  73.  
  74. // True if the logical display has unique content.
  75. private boolean mHasContent;
  76.  
  77. private int mRequestedModeId;
  78. private int mRequestedColorMode;
  79.  
  80. // The display offsets to apply to the display projection.
  81. private int mDisplayOffsetX = mOffsetCenterX;
  82. private int mDisplayOffsetY = mOffsetCenterY;
  83.  
  84. // Temporary rectangle used when needed.
  85. private final Rect mTempLayerStackRect = new Rect();
  86. private final Rect mTempDisplayRect = new Rect();
  87.  
  88. // Offset the "center" of the screen
  89. private int mOffsetCenterX = Resources.getSystem().getInteger(
  90. com.android.internal.R.integer.config_offsetCenterX);
  91. private int mOffsetCenterY = Resources.getSystem().getInteger(
  92. com.android.internal.R.integer.config_offsetCenterY);
  93. public LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) {
  94. mDisplayId = displayId;
  95. mLayerStack = layerStack;
  96. mPrimaryDisplayDevice = primaryDisplayDevice;
  97. }
  98.  
  99. /**
  100. * Gets the logical display id of this logical display.
  101. *
  102. * @return The logical display id.
  103. */
  104. public int getDisplayIdLocked() {
  105. return mDisplayId;
  106. }
  107.  
  108. /**
  109. * Gets the primary display device associated with this logical display.
  110. *
  111. * @return The primary display device.
  112. */
  113. public DisplayDevice getPrimaryDisplayDeviceLocked() {
  114. return mPrimaryDisplayDevice;
  115. }
  116.  
  117. /**
  118. * Gets information about the logical display.
  119. *
  120. * @return The device info, which should be treated as immutable by the caller.
  121. * The logical display should allocate a new display info object whenever
  122. * the data changes.
  123. */
  124. public DisplayInfo getDisplayInfoLocked() {
  125. if (mInfo == null) {
  126. mInfo = new DisplayInfo();
  127. mInfo.copyFrom(mBaseDisplayInfo);
  128. if (mOverrideDisplayInfo != null) {
  129. mInfo.appWidth = mOverrideDisplayInfo.appWidth;
  130. mInfo.appHeight = mOverrideDisplayInfo.appHeight;
  131. mInfo.smallestNominalAppWidth = mOverrideDisplayInfo.smallestNominalAppWidth;
  132. mInfo.smallestNominalAppHeight = mOverrideDisplayInfo.smallestNominalAppHeight;
  133. mInfo.largestNominalAppWidth = mOverrideDisplayInfo.largestNominalAppWidth;
  134. mInfo.largestNominalAppHeight = mOverrideDisplayInfo.largestNominalAppHeight;
  135. mInfo.logicalWidth = mOverrideDisplayInfo.logicalWidth;
  136. mInfo.logicalHeight = mOverrideDisplayInfo.logicalHeight;
  137. mInfo.overscanLeft = mOverrideDisplayInfo.overscanLeft;
  138. mInfo.overscanTop = mOverrideDisplayInfo.overscanTop;
  139. mInfo.overscanRight = mOverrideDisplayInfo.overscanRight;
  140. mInfo.overscanBottom = mOverrideDisplayInfo.overscanBottom;
  141. mInfo.rotation = mOverrideDisplayInfo.rotation;
  142. mInfo.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi;
  143. mInfo.physicalXDpi = mOverrideDisplayInfo.physicalXDpi;
  144. mInfo.physicalYDpi = mOverrideDisplayInfo.physicalYDpi;
  145. }
  146. }
  147. return mInfo;
  148. }
  149.  
  150. /**
  151. * Sets overridden logical display information from the window manager.
  152. * This method can be used to adjust application insets, rotation, and other
  153. * properties that the window manager takes care of.
  154. *
  155. * @param info The logical display information, may be null.
  156. */
  157. public boolean setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo info) {
  158. if (info != null) {
  159. if (mOverrideDisplayInfo == null) {
  160. mOverrideDisplayInfo = new DisplayInfo(info);
  161. mInfo = null;
  162. return true;
  163. }
  164. if (!mOverrideDisplayInfo.equals(info)) {
  165. mOverrideDisplayInfo.copyFrom(info);
  166. mInfo = null;
  167. return true;
  168. }
  169. } else if (mOverrideDisplayInfo != null) {
  170. mOverrideDisplayInfo = null;
  171. mInfo = null;
  172. return true;
  173. }
  174. return false;
  175. }
  176.  
  177. /**
  178. * Returns true if the logical display is in a valid state.
  179. * This method should be checked after calling {@link #updateLocked} to handle the
  180. * case where a logical display should be removed because all of its associated
  181. * display devices are gone or if it is otherwise no longer needed.
  182. *
  183. * @return True if the logical display is still valid.
  184. */
  185. public boolean isValidLocked() {
  186. return mPrimaryDisplayDevice != null;
  187. }
  188.  
  189. /**
  190. * Updates the state of the logical display based on the available display devices.
  191. * The logical display might become invalid if it is attached to a display device
  192. * that no longer exists.
  193. *
  194. * @param devices The list of all connected display devices.
  195. */
  196. public void updateLocked(List<DisplayDevice> devices) {
  197. // Nothing to update if already invalid.
  198. if (mPrimaryDisplayDevice == null) {
  199. return;
  200. }
  201.  
  202. // Check whether logical display has become invalid.
  203. if (!devices.contains(mPrimaryDisplayDevice)) {
  204. mPrimaryDisplayDevice = null;
  205. return;
  206. }
  207.  
  208. // Bootstrap the logical display using its associated primary physical display.
  209. // We might use more elaborate configurations later. It's possible that the
  210. // configuration of several physical displays might be used to determine the
  211. // logical display that they are sharing. (eg. Adjust size for pixel-perfect
  212. // mirroring over HDMI.)
  213. DisplayDeviceInfo deviceInfo = mPrimaryDisplayDevice.getDisplayDeviceInfoLocked();
  214. if (!Objects.equal(mPrimaryDisplayDeviceInfo, deviceInfo)) {
  215. mBaseDisplayInfo.layerStack = mLayerStack;
  216. mBaseDisplayInfo.flags = 0;
  217. if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
  218. mBaseDisplayInfo.flags |= Display.FLAG_SUPPORTS_PROTECTED_BUFFERS;
  219. }
  220. if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SECURE) != 0) {
  221. mBaseDisplayInfo.flags |= Display.FLAG_SECURE;
  222. }
  223. if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0) {
  224. mBaseDisplayInfo.flags |= Display.FLAG_PRIVATE;
  225. }
  226. if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRESENTATION) != 0) {
  227. mBaseDisplayInfo.flags |= Display.FLAG_PRESENTATION;
  228. }
  229. if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ROUND) != 0) {
  230. mBaseDisplayInfo.flags |= Display.FLAG_ROUND;
  231. }
  232. mBaseDisplayInfo.type = deviceInfo.type;
  233. mBaseDisplayInfo.address = deviceInfo.address;
  234. mBaseDisplayInfo.name = deviceInfo.name;
  235. mBaseDisplayInfo.uniqueId = deviceInfo.uniqueId;
  236. mBaseDisplayInfo.appWidth = deviceInfo.width;
  237. mBaseDisplayInfo.appHeight = deviceInfo.height;
  238. mBaseDisplayInfo.logicalWidth = deviceInfo.width;
  239. mBaseDisplayInfo.logicalHeight = deviceInfo.height;
  240. mBaseDisplayInfo.rotation = Surface.ROTATION_0;
  241. mBaseDisplayInfo.modeId = deviceInfo.modeId;
  242. mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
  243. mBaseDisplayInfo.supportedModes = Arrays.copyOf(
  244. deviceInfo.supportedModes, deviceInfo.supportedModes.length);
  245. mBaseDisplayInfo.colorMode = deviceInfo.colorMode;
  246. mBaseDisplayInfo.supportedColorModes = Arrays.copyOf(
  247. deviceInfo.supportedColorModes,
  248. deviceInfo.supportedColorModes.length);
  249. mBaseDisplayInfo.hdrCapabilities = deviceInfo.hdrCapabilities;
  250. mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
  251. mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
  252. mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
  253. mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos;
  254. mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos;
  255. mBaseDisplayInfo.state = deviceInfo.state;
  256. mBaseDisplayInfo.smallestNominalAppWidth = deviceInfo.width;
  257. mBaseDisplayInfo.smallestNominalAppHeight = deviceInfo.height;
  258. mBaseDisplayInfo.largestNominalAppWidth = deviceInfo.width;
  259. mBaseDisplayInfo.largestNominalAppHeight = deviceInfo.height;
  260. mBaseDisplayInfo.ownerUid = deviceInfo.ownerUid;
  261. mBaseDisplayInfo.ownerPackageName = deviceInfo.ownerPackageName;
  262.  
  263. mPrimaryDisplayDeviceInfo = deviceInfo;
  264. mInfo = null;
  265. }
  266. }
  267.  
  268. /**
  269. * Applies the layer stack and transformation to the given display device
  270. * so that it shows the contents of this logical display.
  271. *
  272. * We know that the given display device is only ever showing the contents of
  273. * a single logical display, so this method is expected to blow away all of its
  274. * transformation properties to make it happen regardless of what the
  275. * display device was previously showing.
  276. *
  277. * The caller must have an open Surface transaction.
  278. *
  279. * The display device may not be the primary display device, in the case
  280. * where the display is being mirrored.
  281. *
  282. * @param device The display device to modify.
  283. * @param isBlanked True if the device is being blanked.
  284. */
  285. public void configureDisplayInTransactionLocked(DisplayDevice device,
  286. boolean isBlanked) {
  287. // Set the layer stack.
  288. device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack);
  289.  
  290. // Set the color mode and mode.
  291. if (device == mPrimaryDisplayDevice) {
  292. device.requestDisplayModesInTransactionLocked(
  293. mRequestedColorMode, mRequestedModeId);
  294. } else {
  295. device.requestDisplayModesInTransactionLocked(0, 0); // Revert to default.
  296. }
  297.  
  298. // Only grab the display info now as it may have been changed based on the requests above.
  299. final DisplayInfo displayInfo = getDisplayInfoLocked();
  300. final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked();
  301.  
  302. // Set the viewport.
  303. // This is the area of the logical display that we intend to show on the
  304. // display device. For now, it is always the full size of the logical display.
  305. mTempLayerStackRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
  306.  
  307. // Set the orientation.
  308. // The orientation specifies how the physical coordinate system of the display
  309. // is rotated when the contents of the logical display are rendered.
  310. int orientation = Surface.ROTATION_0;
  311. if ((displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) {
  312. orientation = displayInfo.rotation;
  313. }
  314.  
  315. // Apply the physical rotation of the display device itself.
  316. orientation = (orientation + displayDeviceInfo.rotation) % 4;
  317.  
  318. // Set the frame.
  319. // The frame specifies the rotated physical coordinates into which the viewport
  320. // is mapped. We need to take care to preserve the aspect ratio of the viewport.
  321. // Currently we maximize the area to fill the display, but we could try to be
  322. // more clever and match resolutions.
  323. boolean rotated = (orientation == Surface.ROTATION_90
  324. || orientation == Surface.ROTATION_270);
  325. int physWidth = rotated ? displayDeviceInfo.height : displayDeviceInfo.width;
  326. int physHeight = rotated ? displayDeviceInfo.width : displayDeviceInfo.height;
  327.  
  328. // Determine whether the width or height is more constrained to be scaled.
  329. // physWidth / displayInfo.logicalWidth => letter box
  330. // or physHeight / displayInfo.logicalHeight => pillar box
  331. //
  332. // We avoid a division (and possible floating point imprecision) here by
  333. // multiplying the fractions by the product of their denominators before
  334. // comparing them.
  335. int displayRectWidth, displayRectHeight;
  336. if ((displayInfo.flags & Display.FLAG_SCALING_DISABLED) != 0) {
  337. displayRectWidth = displayInfo.logicalWidth;
  338. displayRectHeight = displayInfo.logicalHeight;
  339. } else if (physWidth * displayInfo.logicalHeight
  340. < physHeight * displayInfo.logicalWidth) {
  341. // Letter box.
  342. displayRectWidth = physWidth;
  343. displayRectHeight = displayInfo.logicalHeight * physWidth / displayInfo.logicalWidth;
  344. } else {
  345. // Pillar box.
  346. displayRectWidth = displayInfo.logicalWidth * physHeight / displayInfo.logicalHeight;
  347. displayRectHeight = physHeight;
  348. }
  349. int displayRectTop = (physHeight - displayRectHeight) / 2;
  350. int displayRectLeft = (physWidth - displayRectWidth) / 2;
  351. mTempDisplayRect.set(displayRectLeft, displayRectTop,
  352. displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight);
  353.  
  354. mTempDisplayRect.left += rotated ? (mDisplayOffsetY + mOffsetCenterY) : (mDisplayOffsetX + mOffsetCenterX);
  355. mTempDisplayRect.right += rotated ? (mDisplayOffsetY + mOffsetCenterY) : (mDisplayOffsetX + mOffsetCenterX);
  356. mTempDisplayRect.top += rotated ? (mDisplayOffsetX + mOffsetCenterX) : (mDisplayOffsetY + mOffsetCenterY);
  357. mTempDisplayRect.bottom += rotated ? (mDisplayOffsetX + mOffsetCenterX) : (mDisplayOffsetY + mOffsetCenterY);
  358. device.setProjectionInTransactionLocked(orientation, mTempLayerStackRect, mTempDisplayRect);
  359. }
  360.  
  361. /**
  362. * Returns true if the logical display has unique content.
  363. * <p>
  364. * If the display has unique content then we will try to ensure that it is
  365. * visible on at least its primary display device. Otherwise we will ignore the
  366. * logical display and perhaps show mirrored content on the primary display device.
  367. * </p>
  368. *
  369. * @return True if the display has unique content.
  370. */
  371. public boolean hasContentLocked() {
  372. return mHasContent;
  373. }
  374.  
  375. /**
  376. * Sets whether the logical display has unique content.
  377. *
  378. * @param hasContent True if the display has unique content.
  379. */
  380. public void setHasContentLocked(boolean hasContent) {
  381. mHasContent = hasContent;
  382. }
  383.  
  384. /**
  385. * Requests the given mode.
  386. */
  387. public void setRequestedModeIdLocked(int modeId) {
  388. mRequestedModeId = modeId;
  389. }
  390.  
  391. /**
  392. * Returns the pending requested mode.
  393. */
  394. public int getRequestedModeIdLocked() {
  395. return mRequestedModeId;
  396. }
  397.  
  398. /**
  399. * Requests the given color mode.
  400. */
  401. public void setRequestedColorModeLocked(int colorMode) {
  402. mRequestedColorMode = colorMode;
  403. }
  404.  
  405. /** Returns the pending requested color mode. */
  406. public int getRequestedColorModeLocked() {
  407. return mRequestedColorMode;
  408. }
  409.  
  410. /**
  411. * Gets the burn-in offset in X.
  412. */
  413. public int getDisplayOffsetXLocked() {
  414. return mDisplayOffsetX;
  415. }
  416.  
  417. /**
  418. * Gets the burn-in offset in Y.
  419. */
  420. public int getDisplayOffsetYLocked() {
  421. return mDisplayOffsetY;
  422. }
  423.  
  424. /**
  425. * Sets the burn-in offsets.
  426. */
  427. public void setDisplayOffsetsLocked(int x, int y) {
  428. mDisplayOffsetX = x;
  429. mDisplayOffsetY = y;
  430. }
  431.  
  432. public void dumpLocked(PrintWriter pw) {
  433. pw.println("mDisplayId=" + mDisplayId);
  434. pw.println("mLayerStack=" + mLayerStack);
  435. pw.println("mHasContent=" + mHasContent);
  436. pw.println("mRequestedMode=" + mRequestedModeId);
  437. pw.println("mRequestedColorMode=" + mRequestedColorMode);
  438. pw.println("mDisplayOffset=(" + mDisplayOffsetX + ", " + mDisplayOffsetY + ")");
  439. pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null ?
  440. mPrimaryDisplayDevice.getNameLocked() : "null"));
  441. pw.println("mBaseDisplayInfo=" + mBaseDisplayInfo);
  442. pw.println("mOverrideDisplayInfo=" + mOverrideDisplayInfo);
  443. }
  444. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement