1/*
2 * Copyright (C) 2011 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 android.graphics.Matrix;
20import android.graphics.PixelFormat;
21import android.graphics.Rect;
22import android.util.Slog;
23import android.view.Surface;
24import android.view.SurfaceSession;
25
26/**
27 * Four black surfaces put together to make a black frame.
28 */
29public class BlackFrame {
30    class BlackSurface {
31        final int left;
32        final int top;
33        final Surface surface;
34
35        BlackSurface(SurfaceSession session, int layer, int l, int t, int r, int b)
36                throws Surface.OutOfResourcesException {
37            left = l;
38            top = t;
39            int w = r-l;
40            int h = b-t;
41            surface = new Surface(session, 0, "BlackSurface",
42                    -1, w, h, PixelFormat.OPAQUE, Surface.FX_SURFACE_DIM);
43            if (WindowManagerService.SHOW_TRANSACTIONS ||
44                    WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
45                            "  BLACK " + surface + ": CREATE layer=" + layer);
46            surface.setAlpha(1.0f);
47            surface.setLayer(layer);
48        }
49
50        void setMatrix(Matrix matrix) {
51            mTmpMatrix.setTranslate(left, top);
52            mTmpMatrix.postConcat(matrix);
53            mTmpMatrix.getValues(mTmpFloats);
54            surface.setPosition(mTmpFloats[Matrix.MTRANS_X],
55                    mTmpFloats[Matrix.MTRANS_Y]);
56            surface.setMatrix(
57                    mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
58                    mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
59            if (false) {
60                Slog.i(WindowManagerService.TAG, "Black Surface @ (" + left + "," + top + "): ("
61                        + mTmpFloats[Matrix.MTRANS_X] + ","
62                        + mTmpFloats[Matrix.MTRANS_Y] + ") matrix=["
63                        + mTmpFloats[Matrix.MSCALE_X] + ","
64                        + mTmpFloats[Matrix.MSCALE_Y] + "]["
65                        + mTmpFloats[Matrix.MSKEW_X] + ","
66                        + mTmpFloats[Matrix.MSKEW_Y] + "]");
67            }
68        }
69
70        void clearMatrix() {
71            surface.setMatrix(1, 0, 0, 1);
72        }
73    }
74
75    final Matrix mTmpMatrix = new Matrix();
76    final float[] mTmpFloats = new float[9];
77    final BlackSurface[] mBlackSurfaces = new BlackSurface[4];
78
79    public BlackFrame(SurfaceSession session, Rect outer, Rect inner,
80            int layer) throws Surface.OutOfResourcesException {
81        boolean success = false;
82
83        try {
84            if (outer.top < inner.top) {
85                mBlackSurfaces[0] = new BlackSurface(session, layer,
86                        outer.left, outer.top, inner.right, inner.top);
87            }
88            if (outer.left < inner.left) {
89                mBlackSurfaces[1] = new BlackSurface(session, layer,
90                        outer.left, inner.top, inner.left, outer.bottom);
91            }
92            if (outer.bottom > inner.bottom) {
93                mBlackSurfaces[2] = new BlackSurface(session, layer,
94                        inner.left, inner.bottom, outer.right, outer.bottom);
95            }
96            if (outer.right > inner.right) {
97                mBlackSurfaces[3] = new BlackSurface(session, layer,
98                        inner.right, outer.top, outer.right, inner.bottom);
99            }
100            success = true;
101        } finally {
102            if (!success) {
103                kill();
104            }
105        }
106    }
107
108    public void kill() {
109        if (mBlackSurfaces != null) {
110            for (int i=0; i<mBlackSurfaces.length; i++) {
111                if (mBlackSurfaces[i] != null) {
112                    if (WindowManagerService.SHOW_TRANSACTIONS ||
113                            WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(
114                                    WindowManagerService.TAG,
115                                    "  BLACK " + mBlackSurfaces[i].surface + ": DESTROY");
116                    mBlackSurfaces[i].surface.destroy();
117                    mBlackSurfaces[i] = null;
118                }
119            }
120        }
121    }
122
123    public void hide() {
124        if (mBlackSurfaces != null) {
125            for (int i=0; i<mBlackSurfaces.length; i++) {
126                if (mBlackSurfaces[i] != null) {
127                    mBlackSurfaces[i].surface.hide();
128                }
129            }
130        }
131    }
132
133    public void setMatrix(Matrix matrix) {
134        for (int i=0; i<mBlackSurfaces.length; i++) {
135            if (mBlackSurfaces[i] != null) {
136                mBlackSurfaces[i].setMatrix(matrix);
137            }
138        }
139    }
140
141    public void clearMatrix() {
142        for (int i=0; i<mBlackSurfaces.length; i++) {
143            if (mBlackSurfaces[i] != null) {
144                mBlackSurfaces[i].clearMatrix();
145            }
146        }
147    }
148}
149