• 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.Log;
24 
25 /**
26  * Handle onto a raw buffer that is being managed by the screen compositor.
27  */
28 public class Surface implements Parcelable {
29     private static final String LOG_TAG = "Surface";
30     private static final boolean DEBUG_RELEASE = false;
31 
32     /* orientations for setOrientation() */
33     public static final int ROTATION_0       = 0;
34     public static final int ROTATION_90      = 1;
35     public static final int ROTATION_180     = 2;
36     public static final int ROTATION_270     = 3;
37 
38     /**
39      * Create Surface from a {@link SurfaceTexture}.
40      *
41      * Images drawn to the Surface will be made available to the {@link
42      * SurfaceTexture}, which can attach them an OpenGL ES texture via {@link
43      * SurfaceTexture#updateTexImage}.
44      *
45      * @param surfaceTexture The {@link SurfaceTexture} that is updated by this
46      * Surface.
47      */
Surface(SurfaceTexture surfaceTexture)48     public Surface(SurfaceTexture surfaceTexture) {
49         if (DEBUG_RELEASE) {
50             mCreationStack = new Exception();
51         }
52         mCanvas = new CompatibleCanvas();
53         initFromSurfaceTexture(surfaceTexture);
54     }
55 
56     /**
57      * Does this object hold a valid surface?  Returns true if it holds
58      * a physical surface, so lockCanvas() will succeed.  Otherwise
59      * returns false.
60      */
isValid()61     public native   boolean isValid();
62 
63     /** Release the local reference to the server-side surface.
64      * Always call release() when you're done with a Surface. This will
65      * make the surface invalid.
66      */
release()67     public native void release();
68 
69     /** draw into a surface */
lockCanvas(Rect dirty)70     public Canvas lockCanvas(Rect dirty) throws OutOfResourcesException, IllegalArgumentException {
71         /*
72          * the dirty rectangle may be expanded to the surface's size, if for
73          * instance it has been resized or if the bits were lost, since the last
74          * call.
75          */
76         return lockCanvasNative(dirty);
77     }
78 
79     /** unlock the surface and asks a page flip */
unlockCanvasAndPost(Canvas canvas)80     public native   void unlockCanvasAndPost(Canvas canvas);
81 
82     /**
83      * unlock the surface. the screen won't be updated until
84      * post() or postAll() is called
85      */
unlockCanvas(Canvas canvas)86     public native   void unlockCanvas(Canvas canvas);
87 
88     @Override
toString()89     public String toString() {
90         return "Surface(name=" + mName + ", identity=" + getIdentity() + ")";
91     }
92 
describeContents()93     public int describeContents() {
94         return 0;
95     }
96 
readFromParcel(Parcel source)97     public native   void readFromParcel(Parcel source);
writeToParcel(Parcel dest, int flags)98     public native   void writeToParcel(Parcel dest, int flags);
99 
100     /**
101      * Exception thrown when a surface couldn't be created or resized
102      */
103     public static class OutOfResourcesException extends Exception {
OutOfResourcesException()104         public OutOfResourcesException() {
105         }
OutOfResourcesException(String name)106         public OutOfResourcesException(String name) {
107             super(name);
108         }
109     }
110 
111     /*
112      * -----------------------------------------------------------------------
113      * No user serviceable parts beyond this point
114      * -----------------------------------------------------------------------
115      */
116 
117     /* flags used in constructor (keep in sync with ISurfaceComposer.h) */
118 
119     /** Surface is created hidden @hide */
120     public static final int HIDDEN              = 0x00000004;
121 
122     /** The surface contains secure content, special measures will
123      * be taken to disallow the surface's content to be copied from
124      * another process. In particular, screenshots and VNC servers will
125      * be disabled, but other measures can take place, for instance the
126      * surface might not be hardware accelerated.
127      * @hide*/
128     public static final int SECURE              = 0x00000080;
129 
130     /** Creates a surface where color components are interpreted as
131      *  "non pre-multiplied" by their alpha channel. Of course this flag is
132      *  meaningless for surfaces without an alpha channel. By default
133      *  surfaces are pre-multiplied, which means that each color component is
134      *  already multiplied by its alpha value. In this case the blending
135      *  equation used is:
136      *
137      *    DEST = SRC + DEST * (1-SRC_ALPHA)
138      *
139      *  By contrast, non pre-multiplied surfaces use the following equation:
140      *
141      *    DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)
142      *
143      *  pre-multiplied surfaces must always be used if transparent pixels are
144      *  composited on top of each-other into the surface. A pre-multiplied
145      *  surface can never lower the value of the alpha component of a given
146      *  pixel.
147      *
148      *  In some rare situations, a non pre-multiplied surface is preferable.
149      *
150      *  @hide
151      */
152     public static final int NON_PREMULTIPLIED   = 0x00000100;
153 
154     /**
155      * Indicates that the surface must be considered opaque, even if its
156      * pixel format is set to translucent. This can be useful if an
157      * application needs full RGBA 8888 support for instance but will
158      * still draw every pixel opaque.
159      *
160      * @hide
161      */
162     public static final int OPAQUE              = 0x00000400;
163 
164     /**
165      * Application requires a hardware-protected path to an
166      * external display sink. If a hardware-protected path is not available,
167      * then this surface will not be displayed on the external sink.
168      *
169      * @hide
170      */
171     public static final int PROTECTED_APP       = 0x00000800;
172 
173     // 0x1000 is reserved for an independent DRM protected flag in framework
174 
175     /** Creates a normal surface. This is the default. @hide */
176     public static final int FX_SURFACE_NORMAL   = 0x00000000;
177 
178     /** Creates a Blur surface. Everything behind this surface is blurred
179      * by some amount. The quality and refresh speed of the blur effect
180      * is not settable or guaranteed.
181      * It is an error to lock a Blur surface, since it doesn't have
182      * a backing store.
183      * @hide
184      * @deprecated
185      */
186     @Deprecated
187     public static final int FX_SURFACE_BLUR     = 0x00010000;
188 
189     /** Creates a Dim surface. Everything behind this surface is dimmed
190      * by the amount specified in {@link #setAlpha}.
191      * It is an error to lock a Dim surface, since it doesn't have
192      * a backing store.
193      * @hide
194      */
195     public static final int FX_SURFACE_DIM     = 0x00020000;
196 
197     /** @hide */
198     public static final int FX_SURFACE_SCREENSHOT   = 0x00030000;
199 
200     /** Mask used for FX values above @hide */
201     public static final int FX_SURFACE_MASK     = 0x000F0000;
202 
203     /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */
204 
205     /** Hide the surface. Equivalent to calling hide(). @hide */
206     public static final int SURFACE_HIDDEN    = 0x01;
207 
208     /** Freeze the surface. Equivalent to calling freeze(). @hide */
209     public static final int SURFACE_FROZEN     = 0x02;
210 
211     /** Enable dithering when compositing this surface @hide */
212     public static final int SURFACE_DITHER    = 0x04;
213 
214     // The mSurfaceControl will only be present for Surfaces used by the window
215     // server or system processes. When this class is parceled we defer to the
216     // mSurfaceControl to do the parceling. Otherwise we parcel the
217     // mNativeSurface.
218     private int mSurfaceControl;
219     private int mSaveCount;
220     private Canvas mCanvas;
221     private int mNativeSurface;
222     private int mSurfaceGenerationId;
223     private String mName;
224 
225     // The Translator for density compatibility mode.  This is used for scaling
226     // the canvas to perform the appropriate density transformation.
227     private Translator mCompatibilityTranslator;
228 
229     // A matrix to scale the matrix set by application. This is set to null for
230     // non compatibility mode.
231     private Matrix mCompatibleMatrix;
232 
233     private Exception mCreationStack;
234 
235 
236     /*
237      * We use a class initializer to allow the native code to cache some
238      * field offsets.
239      */
nativeClassInit()240     native private static void nativeClassInit();
nativeClassInit()241     static { nativeClassInit(); }
242 
243     /** create a surface @hide */
Surface(SurfaceSession s, int pid, int display, int w, int h, int format, int flags)244     public Surface(SurfaceSession s,
245             int pid, int display, int w, int h, int format, int flags)
246         throws OutOfResourcesException {
247         if (DEBUG_RELEASE) {
248             mCreationStack = new Exception();
249         }
250         mCanvas = new CompatibleCanvas();
251         init(s,pid,null,display,w,h,format,flags);
252     }
253 
254     /** create a surface with a name @hide */
Surface(SurfaceSession s, int pid, String name, int display, int w, int h, int format, int flags)255     public Surface(SurfaceSession s,
256             int pid, String name, int display, int w, int h, int format, int flags)
257         throws OutOfResourcesException {
258         if (DEBUG_RELEASE) {
259             mCreationStack = new Exception();
260         }
261         mCanvas = new CompatibleCanvas();
262         init(s,pid,name,display,w,h,format,flags);
263         mName = name;
264     }
265 
266     /**
267      * Create an empty surface, which will later be filled in by
268      * readFromParcel().
269      * @hide
270      */
Surface()271     public Surface() {
272         if (DEBUG_RELEASE) {
273             mCreationStack = new Exception();
274         }
275         mCanvas = new CompatibleCanvas();
276     }
277 
Surface(Parcel source)278     private Surface(Parcel source) throws OutOfResourcesException {
279         init(source);
280     }
281 
282     /**
283      * Copy another surface to this one.  This surface now holds a reference
284      * to the same data as the original surface, and is -not- the owner.
285      * @hide
286      */
copyFrom(Surface o)287     public native void copyFrom(Surface o);
288 
289     /** @hide */
getGenerationId()290     public int getGenerationId() {
291         return mSurfaceGenerationId;
292     }
293 
294     /**
295      * A Canvas class that can handle the compatibility mode. This does two
296      * things differently.
297      * <ul>
298      * <li>Returns the width and height of the target metrics, rather than
299      * native. For example, the canvas returns 320x480 even if an app is running
300      * in WVGA high density.
301      * <li>Scales the matrix in setMatrix by the application scale, except if
302      * the matrix looks like obtained from getMatrix. This is a hack to handle
303      * the case that an application uses getMatrix to keep the original matrix,
304      * set matrix of its own, then set the original matrix back. There is no
305      * perfect solution that works for all cases, and there are a lot of cases
306      * that this model does not work, but we hope this works for many apps.
307      * </ul>
308      */
309     private class CompatibleCanvas extends Canvas {
310         // A temp matrix to remember what an application obtained via {@link getMatrix}
311         private Matrix mOrigMatrix = null;
312 
313         @Override
getWidth()314         public int getWidth() {
315             int w = super.getWidth();
316             if (mCompatibilityTranslator != null) {
317                 w = (int)(w * mCompatibilityTranslator.applicationInvertedScale + .5f);
318             }
319             return w;
320         }
321 
322         @Override
getHeight()323         public int getHeight() {
324             int h = super.getHeight();
325             if (mCompatibilityTranslator != null) {
326                 h = (int)(h * mCompatibilityTranslator.applicationInvertedScale + .5f);
327             }
328             return h;
329         }
330 
331         @Override
setMatrix(Matrix matrix)332         public void setMatrix(Matrix matrix) {
333             if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) {
334                 // don't scale the matrix if it's not compatibility mode, or
335                 // the matrix was obtained from getMatrix.
336                 super.setMatrix(matrix);
337             } else {
338                 Matrix m = new Matrix(mCompatibleMatrix);
339                 m.preConcat(matrix);
340                 super.setMatrix(m);
341             }
342         }
343 
344         @Override
getMatrix(Matrix m)345         public void getMatrix(Matrix m) {
346             super.getMatrix(m);
347             if (mOrigMatrix == null) {
348                 mOrigMatrix = new Matrix();
349             }
350             mOrigMatrix.set(m);
351         }
352     }
353 
354     /**
355      * Sets the translator used to scale canvas's width/height in compatibility
356      * mode.
357      */
setCompatibilityTranslator(Translator translator)358     void setCompatibilityTranslator(Translator translator) {
359         if (translator != null) {
360             float appScale = translator.applicationScale;
361             mCompatibleMatrix = new Matrix();
362             mCompatibleMatrix.setScale(appScale, appScale);
363         }
364     }
365 
366     /** Free all server-side state associated with this surface and
367      * release this object's reference. @hide */
destroy()368     public native void destroy();
369 
lockCanvasNative(Rect dirty)370     private native Canvas lockCanvasNative(Rect dirty);
371 
372     /*
373      * set display parameters & screenshots
374      */
375 
376     /**
377      * Freezes the specified display, No updating of the screen will occur
378      * until unfreezeDisplay() is called. Everything else works as usual though,
379      * in particular transactions.
380      * @param display
381      * @hide
382      */
freezeDisplay(int display)383     public static native   void freezeDisplay(int display);
384 
385     /**
386      * resume updating the specified display.
387      * @param display
388      * @hide
389      */
unfreezeDisplay(int display)390     public static native   void unfreezeDisplay(int display);
391 
392     /**
393      * set the orientation of the given display.
394      * @param display
395      * @param orientation
396      * @param flags Currently unused, set to 0.
397      * @hide
398      */
setOrientation(int display, int orientation, int flags)399     public static native   void setOrientation(int display, int orientation, int flags);
400 
401     /**
402      * set the orientation of the given display.
403      * @param display
404      * @param orientation
405      * @hide
406      */
setOrientation(int display, int orientation)407     public static void setOrientation(int display, int orientation) {
408         setOrientation(display, orientation, 0);
409     }
410 
411     /**
412      * Like {@link #screenshot(int, int, int, int)} but includes all
413      * Surfaces in the screenshot.
414      *
415      * @hide
416      */
screenshot(int width, int height)417     public static native Bitmap screenshot(int width, int height);
418 
419     /**
420      * Copy the current screen contents into a bitmap and return it.
421      *
422      * @param width The desired width of the returned bitmap; the raw
423      * screen will be scaled down to this size.
424      * @param height The desired height of the returned bitmap; the raw
425      * screen will be scaled down to this size.
426      * @param minLayer The lowest (bottom-most Z order) surface layer to
427      * include in the screenshot.
428      * @param maxLayer The highest (top-most Z order) surface layer to
429      * include in the screenshot.
430      * @return Returns a Bitmap containing the screen contents.
431      *
432      * @hide
433      */
screenshot(int width, int height, int minLayer, int maxLayer)434     public static native Bitmap screenshot(int width, int height, int minLayer, int maxLayer);
435 
436 
437     /*
438      * set surface parameters.
439      * needs to be inside open/closeTransaction block
440      */
441 
442     /** start a transaction @hide */
openTransaction()443     public static native   void openTransaction();
444     /** end a transaction @hide */
closeTransaction()445     public static native   void closeTransaction();
446     /** @hide */
setLayer(int zorder)447     public native   void setLayer(int zorder);
448     /** @hide */
setPosition(int x, int y)449     public void setPosition(int x, int y) { setPosition((float)x, (float)y); }
450     /** @hide */
setPosition(float x, float y)451     public native   void setPosition(float x, float y);
452     /** @hide */
setSize(int w, int h)453     public native   void setSize(int w, int h);
454     /** @hide */
hide()455     public native   void hide();
456     /** @hide */
show()457     public native   void show();
458     /** @hide */
setTransparentRegionHint(Region region)459     public native   void setTransparentRegionHint(Region region);
460     /** @hide */
setAlpha(float alpha)461     public native   void setAlpha(float alpha);
462     /** @hide */
setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)463     public native   void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy);
464     /** @hide */
freeze()465     public native   void freeze();
466     /** @hide */
unfreeze()467     public native   void unfreeze();
468     /** @hide */
setFreezeTint(int tint)469     public native   void setFreezeTint(int tint);
470     /** @hide */
setFlags(int flags, int mask)471     public native   void setFlags(int flags, int mask);
472 
473 
474 
475     public static final Parcelable.Creator<Surface> CREATOR
476             = new Parcelable.Creator<Surface>()
477     {
478         public Surface createFromParcel(Parcel source) {
479             try {
480                 return new Surface(source);
481             } catch (Exception e) {
482                 Log.e(LOG_TAG, "Exception creating surface from parcel", e);
483             }
484             return null;
485         }
486 
487         public Surface[] newArray(int size) {
488             return new Surface[size];
489         }
490     };
491 
492     @Override
finalize()493     protected void finalize() throws Throwable {
494         try {
495             super.finalize();
496         } finally {
497             if (mNativeSurface != 0 || mSurfaceControl != 0) {
498                 if (DEBUG_RELEASE) {
499                     Log.w(LOG_TAG, "Surface.finalize() has work. You should have called release() ("
500                             + mNativeSurface + ", " + mSurfaceControl + ")", mCreationStack);
501                 } else {
502                     Log.w(LOG_TAG, "Surface.finalize() has work. You should have called release() ("
503                             + mNativeSurface + ", " + mSurfaceControl + ")");
504                 }
505             }
506             release();
507         }
508     }
509 
init(SurfaceSession s, int pid, String name, int display, int w, int h, int format, int flags)510     private native void init(SurfaceSession s,
511             int pid, String name, int display, int w, int h, int format, int flags)
512             throws OutOfResourcesException;
513 
init(Parcel source)514     private native void init(Parcel source);
515 
initFromSurfaceTexture(SurfaceTexture surfaceTexture)516     private native void initFromSurfaceTexture(SurfaceTexture surfaceTexture);
517 
getIdentity()518     private native int getIdentity();
519 }
520