Surface.java revision 5c1207be90fdf296c1b83034b7c68915e1749284
1/*
2 * Copyright (C) 2007 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 android.view;
18
19import android.content.res.CompatibilityInfo.Translator;
20import android.graphics.*;
21import android.os.Parcelable;
22import android.os.Parcel;
23import android.util.DisplayMetrics;
24import android.util.Log;
25
26/**
27 * Handle on to a raw buffer that is being managed by the screen compositor.
28 */
29public class Surface implements Parcelable {
30    private static final String LOG_TAG = "Surface";
31
32    /* flags used in constructor (keep in sync with ISurfaceComposer.h) */
33
34    /** Surface is created hidden */
35    public static final int HIDDEN              = 0x00000004;
36
37    /** The surface is to be used by hardware accelerators or DMA engines */
38    public static final int HARDWARE            = 0x00000010;
39
40    /** Implies "HARDWARE", the surface is to be used by the GPU
41     * additionally the backbuffer is never preserved for these
42     * surfaces. */
43    public static final int GPU                 = 0x00000028;
44
45    /** The surface contains secure content, special measures will
46     * be taken to disallow the surface's content to be copied from
47     * another process. In particular, screenshots and VNC servers will
48     * be disabled, but other measures can take place, for instance the
49     * surface might not be hardware accelerated. */
50    public static final int SECURE              = 0x00000080;
51
52    /** Creates a surface where color components are interpreted as
53     *  "non pre-multiplied" by their alpha channel. Of course this flag is
54     *  meaningless for surfaces without an alpha channel. By default
55     *  surfaces are pre-multiplied, which means that each color component is
56     *  already multiplied by its alpha value. In this case the blending
57     *  equation used is:
58     *
59     *    DEST = SRC + DEST * (1-SRC_ALPHA)
60     *
61     *  By contrast, non pre-multiplied surfaces use the following equation:
62     *
63     *    DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)
64     *
65     *  pre-multiplied surfaces must always be used if transparent pixels are
66     *  composited on top of each-other into the surface. A pre-multiplied
67     *  surface can never lower the value of the alpha component of a given
68     *  pixel.
69     *
70     *  In some rare situations, a non pre-multiplied surface is preferable.
71     *
72     */
73    public static final int NON_PREMULTIPLIED   = 0x00000100;
74
75    /**
76     * Creates a surface without a rendering buffer. Instead, the content
77     * of the surface must be pushed by an external entity. This is type
78     * of surface can be used for efficient camera preview or movie
79     * play back.
80     */
81    public static final int PUSH_BUFFERS        = 0x00000200;
82
83    /** Creates a normal surface. This is the default */
84    public static final int FX_SURFACE_NORMAL   = 0x00000000;
85
86    /** Creates a Blur surface. Everything behind this surface is blurred
87     * by some amount. The quality and refresh speed of the blur effect
88     * is not settable or guaranteed.
89     * It is an error to lock a Blur surface, since it doesn't have
90     * a backing store.
91     */
92    public static final int FX_SURFACE_BLUR     = 0x00010000;
93
94    /** Creates a Dim surface. Everything behind this surface is dimmed
95     * by the amount specified in setAlpha().
96     * It is an error to lock a Dim surface, since it doesn't have
97     * a backing store.
98     */
99    public static final int FX_SURFACE_DIM     = 0x00020000;
100
101    /** Mask used for FX values above */
102    public static final int FX_SURFACE_MASK     = 0x000F0000;
103
104    /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */
105
106    /** Hide the surface. Equivalent to calling hide() */
107    public static final int SURFACE_HIDDEN    = 0x01;
108
109    /** Freeze the surface. Equivalent to calling freeze() */
110    public static final int SURFACE_FROZEN     = 0x02;
111
112    /**
113     * @deprecated use {@link #SURFACE_FROZEN} instead.
114     */
115    @Deprecated
116    public static final int SURACE_FROZEN     = 0x02;
117
118    /** Enable dithering when compositing this surface */
119    public static final int SURFACE_DITHER    = 0x04;
120
121    public static final int SURFACE_BLUR_FREEZE= 0x10;
122
123    /* orientations for setOrientation() */
124    public static final int ROTATION_0       = 0;
125    public static final int ROTATION_90      = 1;
126    public static final int ROTATION_180     = 2;
127    public static final int ROTATION_270     = 3;
128
129    /**
130     * Disable the orientation animation
131     * {@hide}
132     */
133    public static final int FLAGS_ORIENTATION_ANIMATION_DISABLE = 0x000000001;
134
135    @SuppressWarnings("unused")
136    private int mSurface;
137    @SuppressWarnings("unused")
138    private int mSaveCount;
139    @SuppressWarnings("unused")
140    private Canvas mCanvas;
141
142    // The display metrics used to provide the pseudo canvas size for applications
143    // running in compatibility mode. This is set to null for non compatibility mode.
144    private DisplayMetrics mCompatibleDisplayMetrics;
145
146    // A matrix to scale the matrix set by application. This is set to null for
147    // non compatibility mode.
148    private Matrix mCompatibleMatrix;
149
150    /**
151     * Exception thrown when a surface couldn't be created or resized
152     */
153    public static class OutOfResourcesException extends Exception {
154        public OutOfResourcesException() {
155        }
156        public OutOfResourcesException(String name) {
157            super(name);
158        }
159    }
160
161    /*
162     * We use a class initializer to allow the native code to cache some
163     * field offsets.
164     */
165    native private static void nativeClassInit();
166    static { nativeClassInit(); }
167
168
169    /**
170     * create a surface
171     * {@hide}
172     */
173    public Surface(SurfaceSession s,
174            int pid, int display, int w, int h, int format, int flags)
175        throws OutOfResourcesException {
176        mCanvas = new Canvas();
177        init(s,pid,display,w,h,format,flags);
178    }
179
180    /**
181     * Create an empty surface, which will later be filled in by
182     * readFromParcel().
183     * {@hide}
184     */
185    public Surface() {
186        mCanvas = new CompatibleCanvas();
187    }
188
189    /**
190     * A Canvas class that can handle the compatibility mode. This does two things differently.
191     * <ul>
192     *  <li> Returns the width and height of the target metrics, rather than native.
193     *  For example, the canvas returns 320x480 even if an app is running in WVGA high density.
194     *  <li> Scales the matrix in setMatrix by the application scale, except if the matrix looks
195     *  like obtained from getMatrix. This is a hack to handle the case that an application
196     *  uses getMatrix to keep the original matrix, set matrix of its own, then set the original
197     *  matrix back. There is no perfect solution that works for all cases, and there are a lot of
198     *  cases that this model dose not work, but we hope this works for many apps.
199     * </ul>
200     */
201    private class CompatibleCanvas extends Canvas {
202        // A temp matrix to remember what an application obtained via {@link getMatrix}
203        private Matrix mOrigMatrix = null;
204
205        @Override
206        public int getWidth() {
207            return mCompatibleDisplayMetrics == null ?
208                    super.getWidth() : mCompatibleDisplayMetrics.widthPixels;
209        }
210
211        @Override
212        public int getHeight() {
213            return mCompatibleDisplayMetrics == null ?
214                    super.getHeight() : mCompatibleDisplayMetrics.heightPixels;
215        }
216
217        @Override
218        public void setMatrix(Matrix matrix) {
219            if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) {
220                // don't scale the matrix if it's not compatibility mode, or
221                // the matrix was obtained from getMatrix.
222                super.setMatrix(matrix);
223            } else {
224                Matrix m = new Matrix(mCompatibleMatrix);
225                m.preConcat(matrix);
226                super.setMatrix(m);
227            }
228        }
229
230        @Override
231        public void getMatrix(Matrix m) {
232            super.getMatrix(m);
233            if (mOrigMatrix == null) {
234                mOrigMatrix = new Matrix();
235            }
236            mOrigMatrix.set(m);
237        }
238    };
239
240    /**
241     * Sets the display metrics used to provide canva's width/height in comaptibility mode.
242     */
243    void setCompatibleDisplayMetrics(DisplayMetrics metrics, Translator translator) {
244        mCompatibleDisplayMetrics = metrics;
245        if (translator != null) {
246            float appScale = translator.applicationScale;
247            mCompatibleMatrix = new Matrix();
248            mCompatibleMatrix.setScale(appScale, appScale);
249        }
250    }
251
252    /**
253     * Copy another surface to this one.  This surface now holds a reference
254     * to the same data as the original surface, and is -not- the owner.
255     * {@hide}
256     */
257    public native   void copyFrom(Surface o);
258
259    /**
260     * Does this object hold a valid surface?  Returns true if it holds
261     * a physical surface, so lockCanvas() will succeed.  Otherwise
262     * returns false.
263     */
264    public native   boolean isValid();
265
266    /** Call this free the surface up. {@hide} */
267    public native   void clear();
268
269    /** draw into a surface */
270    public Canvas lockCanvas(Rect dirty) throws OutOfResourcesException {
271        /* the dirty rectangle may be expanded to the surface's size, if
272         * for instance it has been resized or if the bits were lost, since
273         * the last call.
274         */
275        return lockCanvasNative(dirty);
276    }
277
278    private native Canvas lockCanvasNative(Rect dirty);
279
280    /** unlock the surface and asks a page flip */
281    public native   void unlockCanvasAndPost(Canvas canvas);
282
283    /**
284     * unlock the surface. the screen won't be updated until
285     * post() or postAll() is called
286     */
287    public native   void unlockCanvas(Canvas canvas);
288
289    /** start/end a transaction {@hide} */
290    public static native   void openTransaction();
291    /** {@hide} */
292    public static native   void closeTransaction();
293
294    /**
295     * Freezes the specified display, No updating of the screen will occur
296     * until unfreezeDisplay() is called. Everything else works as usual though,
297     * in particular transactions.
298     * @param display
299     * {@hide}
300     */
301    public static native   void freezeDisplay(int display);
302
303    /**
304     * resume updating the specified display.
305     * @param display
306     * {@hide}
307     */
308    public static native   void unfreezeDisplay(int display);
309
310    /**
311     * set the orientation of the given display.
312     * @param display
313     * @param orientation
314     * @param flags
315     * {@hide}
316     */
317    public static native   void setOrientation(int display, int orientation, int flags);
318
319    /**
320     * set the orientation of the given display.
321     * @param display
322     * @param orientation
323     */
324    public static void setOrientation(int display, int orientation) {
325        setOrientation(display, orientation, 0);
326    }
327
328    /**
329     * set surface parameters.
330     * needs to be inside open/closeTransaction block
331     */
332    public native   void setLayer(int zorder);
333    public native   void setPosition(int x, int y);
334    public native   void setSize(int w, int h);
335
336    public native   void hide();
337    public native   void show();
338    public native   void setTransparentRegionHint(Region region);
339    public native   void setAlpha(float alpha);
340    public native   void setMatrix(float dsdx, float dtdx,
341                                   float dsdy, float dtdy);
342
343    public native   void freeze();
344    public native   void unfreeze();
345
346    public native   void setFreezeTint(int tint);
347
348    public native   void setFlags(int flags, int mask);
349
350    @Override
351    public String toString() {
352        return "Surface(native-token=" + mSurface + ")";
353    }
354
355    private Surface(Parcel source) throws OutOfResourcesException {
356        init(source);
357    }
358
359    public int describeContents() {
360        return 0;
361    }
362
363    public native   void readFromParcel(Parcel source);
364    public native   void writeToParcel(Parcel dest, int flags);
365
366    public static final Parcelable.Creator<Surface> CREATOR
367            = new Parcelable.Creator<Surface>()
368    {
369        public Surface createFromParcel(Parcel source) {
370            try {
371                return new Surface(source);
372            } catch (Exception e) {
373                Log.e(LOG_TAG, "Exception creating surface from parcel", e);
374            }
375            return null;
376        }
377
378        public Surface[] newArray(int size) {
379            return new Surface[size];
380        }
381    };
382
383    /* no user serviceable parts here ... */
384    @Override
385    protected void finalize() throws Throwable {
386        clear();
387    }
388
389    private native void init(SurfaceSession s,
390            int pid, int display, int w, int h, int format, int flags)
391            throws OutOfResourcesException;
392
393    private native void init(Parcel source);
394}
395