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