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