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