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