WindowSurfaceController.java revision 086d2929f739ab217c38f99b76fd70f30dcfa478
1/* 2 * Copyright (C) 2015 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 17package com.android.server.wm; 18 19import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC; 20import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; 21import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; 22import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE; 23import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; 24import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 25import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 26import static android.view.Surface.SCALING_MODE_FREEZE; 27import static android.view.Surface.SCALING_MODE_SCALE_TO_WINDOW; 28 29import android.graphics.PixelFormat; 30import android.graphics.Point; 31import android.graphics.PointF; 32import android.graphics.Rect; 33import android.graphics.Region; 34import android.os.IBinder; 35import android.os.Debug; 36import android.view.Surface; 37import android.view.SurfaceControl; 38import android.view.SurfaceSession; 39import android.view.WindowContentFrameStats; 40import android.view.Surface.OutOfResourcesException; 41 42import android.util.Slog; 43 44import java.io.PrintWriter; 45import java.util.ArrayList; 46 47class WindowSurfaceController { 48 static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfaceController" : TAG_WM; 49 50 final WindowStateAnimator mAnimator; 51 52 private SurfaceControl mSurfaceControl; 53 54 private boolean mSurfaceShown = false; 55 private float mSurfaceX = 0; 56 private float mSurfaceY = 0; 57 private float mSurfaceW = 0; 58 private float mSurfaceH = 0; 59 60 private float mSurfaceAlpha = 0; 61 62 private int mSurfaceLayer = 0; 63 64 // Surface flinger doesn't support crop rectangles where width or height is non-positive. 65 // However, we need to somehow handle the situation where the cropping would completely hide 66 // the window. We achieve this by explicitly hiding the surface and not letting it be shown. 67 private boolean mHiddenForCrop = false; 68 69 // Initially a surface is hidden after just being created. 70 private boolean mHiddenForOtherReasons = true; 71 private final String title; 72 73 public WindowSurfaceController(SurfaceSession s, 74 String name, int w, int h, int format, int flags, WindowStateAnimator animator) { 75 mAnimator = animator; 76 77 mSurfaceW = w; 78 mSurfaceH = h; 79 80 title = name; 81 82 // For opaque child windows placed under parent windows, 83 // we use a special SurfaceControl which mirrors commands 84 // to a black-out layer placed one Z-layer below the surface. 85 // This prevents holes to whatever app/wallpaper is underneath. 86 if (animator.mWin.isChildWindow() && 87 animator.mWin.mSubLayer < 0) { 88 mSurfaceControl = new SurfaceControlWithBackground(s, 89 name, w, h, format, flags); 90 } else if (DEBUG_SURFACE_TRACE) { 91 mSurfaceControl = new SurfaceTrace( 92 s, name, w, h, format, flags); 93 } else { 94 mSurfaceControl = new SurfaceControl( 95 s, name, w, h, format, flags); 96 } 97 } 98 99 100 void logSurface(String msg, RuntimeException where) { 101 String str = " SURFACE " + msg + ": " + title; 102 if (where != null) { 103 Slog.i(TAG, str, where); 104 } else { 105 Slog.i(TAG, str); 106 } 107 } 108 109 void hideInTransaction(String reason) { 110 if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null); 111 mHiddenForOtherReasons = true; 112 113 mAnimator.destroyPreservedSurfaceLocked(); 114 updateVisibility(); 115 } 116 117 private void hideSurface() { 118 if (mSurfaceControl != null) { 119 mSurfaceShown = false; 120 try { 121 mSurfaceControl.hide(); 122 } catch (RuntimeException e) { 123 Slog.w(TAG, "Exception hiding surface in " + this); 124 } 125 } 126 } 127 128 void setPositionAndLayer(float left, float top, int layerStack, int layer) { 129 SurfaceControl.openTransaction(); 130 try { 131 mSurfaceX = left; 132 mSurfaceY = top; 133 134 try { 135 if (SHOW_TRANSACTIONS) logSurface( 136 "POS (setPositionAndLayer) @ (" + left + "," + top + ")", null); 137 mSurfaceControl.setPosition(left, top); 138 mSurfaceControl.setLayerStack(layerStack); 139 140 mSurfaceControl.setLayer(layer); 141 mSurfaceControl.setAlpha(0); 142 mSurfaceShown = false; 143 } catch (RuntimeException e) { 144 Slog.w(TAG, "Error creating surface in " + this, e); 145 mAnimator.reclaimSomeSurfaceMemory("create-init", true); 146 } 147 } finally { 148 SurfaceControl.closeTransaction(); 149 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 150 "<<< CLOSE TRANSACTION setPositionAndLayer"); 151 } 152 } 153 154 void destroyInTransaction() { 155 // if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { 156 Slog.i(TAG, "Destroying surface " + this + " called by " + Debug.getCallers(8)); 157 // } 158 try { 159 if (mSurfaceControl != null) { 160 mSurfaceControl.destroy(); 161 } 162 } catch (RuntimeException e) { 163 Slog.w(TAG, "Error destroying surface in: " + this, e); 164 } finally { 165 mSurfaceShown = false; 166 mSurfaceControl = null; 167 } 168 } 169 170 void disconnectInTransaction() { 171 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { 172 Slog.i(TAG, "Disconnecting client: " + this); 173 } 174 175 try { 176 if (mSurfaceControl != null) { 177 mSurfaceControl.disconnect(); 178 } 179 } catch (RuntimeException e) { 180 Slog.w(TAG, "Error disconnecting surface in: " + this, e); 181 } 182 } 183 184 void setCropInTransaction(Rect clipRect, boolean recoveringMemory) { 185 if (SHOW_TRANSACTIONS) logSurface( 186 "CROP " + clipRect.toShortString(), null); 187 try { 188 if (clipRect.width() != 0 && clipRect.height() != 0) { 189 mSurfaceControl.setWindowCrop(clipRect); 190 mHiddenForCrop = false; 191 updateVisibility(); 192 } else { 193 mHiddenForCrop = true; 194 mAnimator.destroyPreservedSurfaceLocked(); 195 updateVisibility(); 196 } 197 } catch (RuntimeException e) { 198 Slog.w(TAG, "Error setting crop surface of " + this 199 + " crop=" + clipRect.toShortString(), e); 200 if (!recoveringMemory) { 201 mAnimator.reclaimSomeSurfaceMemory("crop", true); 202 } 203 } 204 } 205 206 void setFinalCropInTransaction(Rect clipRect) { 207 if (SHOW_TRANSACTIONS) logSurface( 208 "FINAL CROP " + clipRect.toShortString(), null); 209 try { 210 mSurfaceControl.setFinalCrop(clipRect); 211 } catch (RuntimeException e) { 212 Slog.w(TAG, "Error disconnecting surface in: " + this, e); 213 } 214 } 215 216 void setLayer(int layer) { 217 if (mSurfaceControl != null) { 218 SurfaceControl.openTransaction(); 219 try { 220 mSurfaceControl.setLayer(layer); 221 } finally { 222 SurfaceControl.closeTransaction(); 223 } 224 } 225 } 226 227 void setPositionInTransaction(float left, float top, boolean recoveringMemory) { 228 final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top; 229 if (surfaceMoved) { 230 mSurfaceX = left; 231 mSurfaceY = top; 232 233 try { 234 if (SHOW_TRANSACTIONS) logSurface( 235 "POS (setPositionInTransaction) @ (" + left + "," + top + ")", null); 236 237 mSurfaceControl.setPosition(left, top); 238 } catch (RuntimeException e) { 239 Slog.w(TAG, "Error positioning surface of " + this 240 + " pos=(" + left + "," + top + ")", e); 241 if (!recoveringMemory) { 242 mAnimator.reclaimSomeSurfaceMemory("position", true); 243 } 244 } 245 } 246 } 247 248 void setPositionAppliesWithResizeInTransaction(boolean recoveringMemory) { 249 mSurfaceControl.setPositionAppliesWithResize(); 250 } 251 252 void setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy, 253 boolean recoveringMemory) { 254 try { 255 if (SHOW_TRANSACTIONS) logSurface( 256 "MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null); 257 mSurfaceControl.setMatrix( 258 dsdx, dtdx, dsdy, dtdy); 259 } catch (RuntimeException e) { 260 // If something goes wrong with the surface (such 261 // as running out of memory), don't take down the 262 // entire system. 263 Slog.e(TAG, "Error setting matrix on surface surface" + title 264 + " MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null); 265 if (!recoveringMemory) { 266 mAnimator.reclaimSomeSurfaceMemory("matrix", true); 267 } 268 } 269 return; 270 } 271 272 boolean setSizeInTransaction(int width, int height, boolean recoveringMemory) { 273 final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height; 274 if (surfaceResized) { 275 mSurfaceW = width; 276 mSurfaceH = height; 277 278 try { 279 if (SHOW_TRANSACTIONS) logSurface( 280 "SIZE " + width + "x" + height, null); 281 mSurfaceControl.setSize(width, height); 282 } catch (RuntimeException e) { 283 // If something goes wrong with the surface (such 284 // as running out of memory), don't take down the 285 // entire system. 286 Slog.e(TAG, "Error resizing surface of " + title 287 + " size=(" + width + "x" + height + ")", e); 288 if (!recoveringMemory) { 289 mAnimator.reclaimSomeSurfaceMemory("size", true); 290 } 291 return false; 292 } 293 return true; 294 } 295 return false; 296 } 297 298 boolean prepareToShowInTransaction(float alpha, int layer, float dsdx, float dtdx, float dsdy, 299 float dtdy, boolean recoveringMemory) { 300 if (mSurfaceControl != null) { 301 try { 302 mSurfaceAlpha = alpha; 303 mSurfaceControl.setAlpha(alpha); 304 mSurfaceLayer = layer; 305 mSurfaceControl.setLayer(layer); 306 mSurfaceControl.setMatrix( 307 dsdx, dtdx, dsdy, dtdy); 308 309 } catch (RuntimeException e) { 310 Slog.w(TAG, "Error updating surface in " + title, e); 311 if (!recoveringMemory) { 312 mAnimator.reclaimSomeSurfaceMemory("update", true); 313 } 314 return false; 315 } 316 } 317 return true; 318 } 319 320 void setTransparentRegionHint(final Region region) { 321 if (mSurfaceControl == null) { 322 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true"); 323 return; 324 } 325 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion"); 326 SurfaceControl.openTransaction(); 327 try { 328 mSurfaceControl.setTransparentRegionHint(region); 329 } finally { 330 SurfaceControl.closeTransaction(); 331 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 332 "<<< CLOSE TRANSACTION setTransparentRegion"); 333 } 334 } 335 336 void setOpaque(boolean isOpaque) { 337 if (SHOW_TRANSACTIONS) logSurface("isOpaque=" + isOpaque, 338 null); 339 340 if (mSurfaceControl == null) { 341 return; 342 } 343 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked"); 344 SurfaceControl.openTransaction(); 345 try { 346 mSurfaceControl.setOpaque(isOpaque); 347 } finally { 348 SurfaceControl.closeTransaction(); 349 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked"); 350 } 351 } 352 353 void setSecure(boolean isSecure) { 354 if (SHOW_TRANSACTIONS) logSurface("isSecure=" + isSecure, 355 null); 356 357 if (mSurfaceControl == null) { 358 return; 359 } 360 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked"); 361 SurfaceControl.openTransaction(); 362 try { 363 mSurfaceControl.setSecure(isSecure); 364 } finally { 365 SurfaceControl.closeTransaction(); 366 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked"); 367 } 368 } 369 370 boolean showRobustlyInTransaction() { 371 if (SHOW_TRANSACTIONS) logSurface( 372 "SHOW (performLayout)", null); 373 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this 374 + " during relayout"); 375 mHiddenForOtherReasons = false; 376 return updateVisibility(); 377 } 378 379 private boolean updateVisibility() { 380 if (mHiddenForCrop || mHiddenForOtherReasons) { 381 if (mSurfaceShown) { 382 hideSurface(); 383 } 384 return false; 385 } else { 386 if (!mSurfaceShown) { 387 return showSurface(); 388 } else { 389 return true; 390 } 391 } 392 } 393 394 private boolean showSurface() { 395 try { 396 mSurfaceShown = true; 397 mSurfaceControl.show(); 398 return true; 399 } catch (RuntimeException e) { 400 Slog.w(TAG, "Failure showing surface " + mSurfaceControl + " in " + this, e); 401 } 402 403 mAnimator.reclaimSomeSurfaceMemory("show", true); 404 405 return false; 406 } 407 408 void deferTransactionUntil(IBinder handle, long frame) { 409 // TODO: Logging 410 mSurfaceControl.deferTransactionUntil(handle, frame); 411 } 412 413 void forceScaleableInTransaction(boolean force) { 414 // -1 means we don't override the default or client specified 415 // scaling mode. 416 int scalingMode = force ? SCALING_MODE_SCALE_TO_WINDOW : -1; 417 mSurfaceControl.setOverrideScalingMode(scalingMode); 418 } 419 420 boolean clearWindowContentFrameStats() { 421 if (mSurfaceControl == null) { 422 return false; 423 } 424 return mSurfaceControl.clearContentFrameStats(); 425 } 426 427 boolean getWindowContentFrameStats(WindowContentFrameStats outStats) { 428 if (mSurfaceControl == null) { 429 return false; 430 } 431 return mSurfaceControl.getContentFrameStats(outStats); 432 } 433 434 435 boolean hasSurface() { 436 return mSurfaceControl != null; 437 } 438 439 IBinder getHandle() { 440 if (mSurfaceControl == null) { 441 return null; 442 } 443 return mSurfaceControl.getHandle(); 444 } 445 446 void getSurface(Surface outSurface) { 447 outSurface.copyFrom(mSurfaceControl); 448 } 449 450 int getLayer() { 451 return mSurfaceLayer; 452 } 453 454 boolean getShown() { 455 return mSurfaceShown; 456 } 457 458 void setShown(boolean surfaceShown) { 459 mSurfaceShown = surfaceShown; 460 } 461 462 float getX() { 463 return mSurfaceX; 464 } 465 466 float getY() { 467 return mSurfaceY; 468 } 469 470 float getWidth() { 471 return mSurfaceW; 472 } 473 474 float getHeight() { 475 return mSurfaceH; 476 } 477 478 479 public void dump(PrintWriter pw, String prefix, boolean dumpAll) { 480 if (dumpAll) { 481 pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl); 482 } 483 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown); 484 pw.print(" layer="); pw.print(mSurfaceLayer); 485 pw.print(" alpha="); pw.print(mSurfaceAlpha); 486 pw.print(" rect=("); pw.print(mSurfaceX); 487 pw.print(","); pw.print(mSurfaceY); 488 pw.print(") "); pw.print(mSurfaceW); 489 pw.print(" x "); pw.println(mSurfaceH); 490 } 491 492 @Override 493 public String toString() { 494 return mSurfaceControl.toString(); 495 } 496 497 static class SurfaceTrace extends SurfaceControl { 498 private final static String SURFACE_TAG = TAG_WITH_CLASS_NAME ? "SurfaceTrace" : TAG_WM; 499 private final static boolean LOG_SURFACE_TRACE = DEBUG_SURFACE_TRACE; 500 final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>(); 501 502 private float mSurfaceTraceAlpha = 0; 503 private int mLayer; 504 private final PointF mPosition = new PointF(); 505 private final Point mSize = new Point(); 506 private final Rect mWindowCrop = new Rect(); 507 private final Rect mFinalCrop = new Rect(); 508 private boolean mShown = false; 509 private int mLayerStack; 510 private boolean mIsOpaque; 511 private float mDsdx, mDtdx, mDsdy, mDtdy; 512 private final String mName; 513 514 public SurfaceTrace(SurfaceSession s, 515 String name, int w, int h, int format, int flags) 516 throws OutOfResourcesException { 517 super(s, name, w, h, format, flags); 518 mName = name != null ? name : "Not named"; 519 mSize.set(w, h); 520 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by " 521 + Debug.getCallers(3)); 522 synchronized (sSurfaces) { 523 sSurfaces.add(0, this); 524 } 525 } 526 527 @Override 528 public void setAlpha(float alpha) { 529 if (mSurfaceTraceAlpha != alpha) { 530 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this + 531 ". Called by " + Debug.getCallers(3)); 532 mSurfaceTraceAlpha = alpha; 533 } 534 super.setAlpha(alpha); 535 } 536 537 @Override 538 public void setLayer(int zorder) { 539 if (zorder != mLayer) { 540 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this 541 + ". Called by " + Debug.getCallers(3)); 542 mLayer = zorder; 543 } 544 super.setLayer(zorder); 545 546 synchronized (sSurfaces) { 547 sSurfaces.remove(this); 548 int i; 549 for (i = sSurfaces.size() - 1; i >= 0; i--) { 550 SurfaceTrace s = sSurfaces.get(i); 551 if (s.mLayer < zorder) { 552 break; 553 } 554 } 555 sSurfaces.add(i + 1, this); 556 } 557 } 558 559 @Override 560 public void setPosition(float x, float y) { 561 if (x != mPosition.x || y != mPosition.y) { 562 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:" 563 + this + ". Called by " + Debug.getCallers(3)); 564 mPosition.set(x, y); 565 } 566 super.setPosition(x, y); 567 } 568 569 @Override 570 public void setPositionAppliesWithResize() { 571 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPositionAppliesWithResize(): OLD: " 572 + this + ". Called by" + Debug.getCallers(9)); 573 super.setPositionAppliesWithResize(); 574 } 575 576 @Override 577 public void setSize(int w, int h) { 578 if (w != mSize.x || h != mSize.y) { 579 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:" 580 + this + ". Called by " + Debug.getCallers(3)); 581 mSize.set(w, h); 582 } 583 super.setSize(w, h); 584 } 585 586 @Override 587 public void setWindowCrop(Rect crop) { 588 if (crop != null) { 589 if (!crop.equals(mWindowCrop)) { 590 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setWindowCrop(" 591 + crop.toShortString() + "): OLD:" + this + ". Called by " 592 + Debug.getCallers(3)); 593 mWindowCrop.set(crop); 594 } 595 } 596 super.setWindowCrop(crop); 597 } 598 599 @Override 600 public void setFinalCrop(Rect crop) { 601 if (crop != null) { 602 if (!crop.equals(mFinalCrop)) { 603 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setFinalCrop(" 604 + crop.toShortString() + "): OLD:" + this + ". Called by " 605 + Debug.getCallers(3)); 606 mFinalCrop.set(crop); 607 } 608 } 609 super.setFinalCrop(crop); 610 } 611 612 @Override 613 public void setLayerStack(int layerStack) { 614 if (layerStack != mLayerStack) { 615 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:" 616 + this + ". Called by " + Debug.getCallers(3)); 617 mLayerStack = layerStack; 618 } 619 super.setLayerStack(layerStack); 620 } 621 622 @Override 623 public void setOpaque(boolean isOpaque) { 624 if (isOpaque != mIsOpaque) { 625 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:" 626 + this + ". Called by " + Debug.getCallers(3)); 627 mIsOpaque = isOpaque; 628 } 629 super.setOpaque(isOpaque); 630 } 631 632 @Override 633 public void setSecure(boolean isSecure) { 634 super.setSecure(isSecure); 635 } 636 637 @Override 638 public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 639 if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) { 640 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + "," 641 + dsdy + "," + dtdy + "): OLD:" + this + ". Called by " 642 + Debug.getCallers(3)); 643 mDsdx = dsdx; 644 mDtdx = dtdx; 645 mDsdy = dsdy; 646 mDtdy = dtdy; 647 } 648 super.setMatrix(dsdx, dtdx, dsdy, dtdy); 649 } 650 651 @Override 652 public void hide() { 653 if (mShown) { 654 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by " 655 + Debug.getCallers(3)); 656 mShown = false; 657 } 658 super.hide(); 659 } 660 661 @Override 662 public void show() { 663 if (!mShown) { 664 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by " 665 + Debug.getCallers(3)); 666 mShown = true; 667 } 668 super.show(); 669 } 670 671 @Override 672 public void destroy() { 673 super.destroy(); 674 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by " 675 + Debug.getCallers(3)); 676 synchronized (sSurfaces) { 677 sSurfaces.remove(this); 678 } 679 } 680 681 @Override 682 public void release() { 683 super.release(); 684 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "release: " + this + ". Called by " 685 + Debug.getCallers(3)); 686 synchronized (sSurfaces) { 687 sSurfaces.remove(this); 688 } 689 } 690 691 @Override 692 public void setTransparentRegionHint(Region region) { 693 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setTransparentRegionHint(" + region 694 + "): OLD: " + this + " . Called by " + Debug.getCallers(3)); 695 super.setTransparentRegionHint(region); 696 } 697 698 static void dumpAllSurfaces(PrintWriter pw, String header) { 699 synchronized (sSurfaces) { 700 final int N = sSurfaces.size(); 701 if (N <= 0) { 702 return; 703 } 704 if (header != null) { 705 pw.println(header); 706 } 707 pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)"); 708 for (int i = 0; i < N; i++) { 709 SurfaceTrace s = sSurfaces.get(i); 710 pw.print(" Surface #"); pw.print(i); pw.print(": #"); 711 pw.print(Integer.toHexString(System.identityHashCode(s))); 712 pw.print(" "); pw.println(s.mName); 713 pw.print(" mLayerStack="); pw.print(s.mLayerStack); 714 pw.print(" mLayer="); pw.println(s.mLayer); 715 pw.print(" mShown="); pw.print(s.mShown); pw.print(" mAlpha="); 716 pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque="); 717 pw.println(s.mIsOpaque); 718 pw.print(" mPosition="); pw.print(s.mPosition.x); pw.print(","); 719 pw.print(s.mPosition.y); 720 pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x"); 721 pw.println(s.mSize.y); 722 pw.print(" mCrop="); s.mWindowCrop.printShortString(pw); pw.println(); 723 pw.print(" mFinalCrop="); s.mFinalCrop.printShortString(pw); pw.println(); 724 pw.print(" Transform: ("); pw.print(s.mDsdx); pw.print(", "); 725 pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy); 726 pw.print(", "); pw.print(s.mDtdy); pw.println(")"); 727 } 728 } 729 } 730 731 @Override 732 public String toString() { 733 return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " " 734 + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer 735 + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y 736 + " " + mSize.x + "x" + mSize.y 737 + " crop=" + mWindowCrop.toShortString() 738 + " opaque=" + mIsOpaque 739 + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")"; 740 } 741 } 742 743 private static class SurfaceControlWithBackground extends SurfaceControl { 744 private SurfaceControl mBackgroundControl; 745 private boolean mOpaque = true; 746 private boolean mVisible = false; 747 748 public SurfaceControlWithBackground(SurfaceSession s, 749 String name, int w, int h, int format, int flags) 750 throws OutOfResourcesException { 751 super(s, name, w, h, format, flags); 752 mBackgroundControl = new SurfaceControl(s, name, w, h, 753 PixelFormat.OPAQUE, flags | SurfaceControl.FX_SURFACE_DIM); 754 mOpaque = (flags & SurfaceControl.OPAQUE) != 0; 755 } 756 757 @Override 758 public void setAlpha(float alpha) { 759 super.setAlpha(alpha); 760 mBackgroundControl.setAlpha(alpha); 761 } 762 763 @Override 764 public void setLayer(int zorder) { 765 super.setLayer(zorder); 766 mBackgroundControl.setLayer(zorder - 1); 767 } 768 769 @Override 770 public void setPosition(float x, float y) { 771 super.setPosition(x, y); 772 mBackgroundControl.setPosition(x, y); 773 } 774 775 @Override 776 public void setSize(int w, int h) { 777 super.setSize(w, h); 778 mBackgroundControl.setSize(w, h); 779 } 780 781 @Override 782 public void setWindowCrop(Rect crop) { 783 super.setWindowCrop(crop); 784 mBackgroundControl.setWindowCrop(crop); 785 } 786 787 @Override 788 public void setFinalCrop(Rect crop) { 789 super.setFinalCrop(crop); 790 mBackgroundControl.setFinalCrop(crop); 791 } 792 793 @Override 794 public void setLayerStack(int layerStack) { 795 super.setLayerStack(layerStack); 796 mBackgroundControl.setLayerStack(layerStack); 797 } 798 799 @Override 800 public void setOpaque(boolean isOpaque) { 801 super.setOpaque(isOpaque); 802 mOpaque = isOpaque; 803 updateBackgroundVisibility(); 804 } 805 806 @Override 807 public void setSecure(boolean isSecure) { 808 super.setSecure(isSecure); 809 } 810 811 @Override 812 public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 813 super.setMatrix(dsdx, dtdx, dsdy, dtdy); 814 mBackgroundControl.setMatrix(dsdx, dtdx, dsdy, dtdy); 815 } 816 817 @Override 818 public void hide() { 819 mVisible = false; 820 super.hide(); 821 updateBackgroundVisibility(); 822 } 823 824 @Override 825 public void show() { 826 mVisible = true; 827 super.show(); 828 updateBackgroundVisibility(); 829 } 830 831 @Override 832 public void destroy() { 833 super.destroy(); 834 mBackgroundControl.destroy(); 835 } 836 837 @Override 838 public void release() { 839 super.release(); 840 mBackgroundControl.release(); 841 } 842 843 @Override 844 public void setTransparentRegionHint(Region region) { 845 super.setTransparentRegionHint(region); 846 mBackgroundControl.setTransparentRegionHint(region); 847 } 848 849 @Override 850 public void deferTransactionUntil(IBinder handle, long frame) { 851 super.deferTransactionUntil(handle, frame); 852 mBackgroundControl.deferTransactionUntil(handle, frame); 853 } 854 855 private void updateBackgroundVisibility() { 856 if (mOpaque && mVisible) { 857 mBackgroundControl.show(); 858 } else { 859 mBackgroundControl.hide(); 860 } 861 } 862 } 863} 864