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