diff options
author | Mathias Agopian <mathias@google.com> | 2013-02-11 22:08:48 -0800 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2013-02-14 12:19:11 -0800 |
commit | 3866f0d581ceaa165710feeee9f37fe1b0d7067d (patch) | |
tree | b3469b8b6dc7fa4d92afa97297947d2fb5ec9e1b /core/java/android/view/Surface.java | |
parent | f9136fd9692158574d187af8d4031fa4b1e2b6e6 (diff) | |
download | frameworks_base-3866f0d581ceaa165710feeee9f37fe1b0d7067d.zip frameworks_base-3866f0d581ceaa165710feeee9f37fe1b0d7067d.tar.gz frameworks_base-3866f0d581ceaa165710feeee9f37fe1b0d7067d.tar.bz2 |
split Surface in two classes: SurfaceControl and Surface
SurfaceControl is the window manager side; it can
control the attributes of a surface but cannot push buffers
to it. Surface on the other hand is the application (producer)
side and is used to push buffers to the surface.
Change-Id: Ib6754c968924e87e8dd02a2073c7a447f729f4dd
Diffstat (limited to 'core/java/android/view/Surface.java')
-rw-r--r-- | core/java/android/view/Surface.java | 571 |
1 files changed, 65 insertions, 506 deletions
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 48b7180..5e96dad 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -16,20 +16,15 @@ package android.view; -import dalvik.system.CloseGuard; - import android.content.res.CompatibilityInfo.Translator; -import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; -import android.graphics.Region; import android.graphics.SurfaceTexture; -import android.os.IBinder; -import android.os.Parcelable; import android.os.Parcel; -import android.os.SystemProperties; +import android.os.Parcelable; import android.util.Log; +import dalvik.system.CloseGuard; /** * Handle onto a raw buffer that is being managed by the screen compositor. @@ -37,9 +32,6 @@ import android.util.Log; public class Surface implements Parcelable { private static final String TAG = "Surface"; - private static final boolean HEADLESS = "1".equals( - SystemProperties.get("ro.config.headless", "0")); - public static final Parcelable.Creator<Surface> CREATOR = new Parcelable.Creator<Surface>() { public Surface createFromParcel(Parcel source) { @@ -78,130 +70,6 @@ public class Surface implements Parcelable { */ public static final int ROTATION_270 = 3; - /* built-in physical display ids (keep in sync with ISurfaceComposer.h) - * these are different from the logical display ids used elsewhere in the framework */ - - /** - * Built-in physical display id: Main display. - * Use only with {@link #getBuiltInDisplay()}. - * @hide - */ - public static final int BUILT_IN_DISPLAY_ID_MAIN = 0; - - /** - * Built-in physical display id: Attached HDMI display. - * Use only with {@link #getBuiltInDisplay()}. - * @hide - */ - public static final int BUILT_IN_DISPLAY_ID_HDMI = 1; - - /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */ - - /** - * Surface creation flag: Surface is created hidden - * @hide */ - public static final int HIDDEN = 0x00000004; - - /** - * Surface creation flag: The surface contains secure content, special - * measures will be taken to disallow the surface's content to be copied - * from another process. In particular, screenshots and VNC servers will - * be disabled, but other measures can take place, for instance the - * surface might not be hardware accelerated. - * @hide - */ - public static final int SECURE = 0x00000080; - - /** - * Surface creation flag: Creates a surface where color components are interpreted - * as "non pre-multiplied" by their alpha channel. Of course this flag is - * meaningless for surfaces without an alpha channel. By default - * surfaces are pre-multiplied, which means that each color component is - * already multiplied by its alpha value. In this case the blending - * equation used is: - * - * DEST = SRC + DEST * (1-SRC_ALPHA) - * - * By contrast, non pre-multiplied surfaces use the following equation: - * - * DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA) - * - * pre-multiplied surfaces must always be used if transparent pixels are - * composited on top of each-other into the surface. A pre-multiplied - * surface can never lower the value of the alpha component of a given - * pixel. - * - * In some rare situations, a non pre-multiplied surface is preferable. - * @hide - */ - public static final int NON_PREMULTIPLIED = 0x00000100; - - /** - * Surface creation flag: Indicates that the surface must be considered opaque, - * even if its pixel format is set to translucent. This can be useful if an - * application needs full RGBA 8888 support for instance but will - * still draw every pixel opaque. - * @hide - */ - public static final int OPAQUE = 0x00000400; - - /** - * Surface creation flag: Application requires a hardware-protected path to an - * external display sink. If a hardware-protected path is not available, - * then this surface will not be displayed on the external sink. - * @hide - */ - public static final int PROTECTED_APP = 0x00000800; - - // 0x1000 is reserved for an independent DRM protected flag in framework - - /** - * Surface creation flag: Creates a normal surface. - * This is the default. - * @hide - */ - public static final int FX_SURFACE_NORMAL = 0x00000000; - - /** - * Surface creation flag: Creates a Blur surface. - * Everything behind this surface is blurred by some amount. - * The quality and refresh speed of the blur effect is not settable or guaranteed. - * It is an error to lock a Blur surface, since it doesn't have a backing store. - * @hide - * @deprecated - */ - @Deprecated - public static final int FX_SURFACE_BLUR = 0x00010000; - - /** - * Surface creation flag: Creates a Dim surface. - * Everything behind this surface is dimmed by the amount specified - * in {@link #setAlpha}. It is an error to lock a Dim surface, since it - * doesn't have a backing store. - * @hide - */ - public static final int FX_SURFACE_DIM = 0x00020000; - - /** - * @hide - */ - public static final int FX_SURFACE_SCREENSHOT = 0x00030000; - - /** - * Mask used for FX values above. - * @hide - */ - public static final int FX_SURFACE_MASK = 0x000F0000; - - /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */ - - /** - * Surface flag: Hide the surface. - * Equivalent to calling hide(). - * @hide - */ - public static final int SURFACE_HIDDEN = 0x01; - private final CloseGuard mCloseGuard = CloseGuard.get(); private String mName; @@ -211,8 +79,8 @@ public class Surface implements Parcelable { // server or system processes. When this class is parceled we defer to the // mSurfaceControl to do the parceling. Otherwise we parcel the // mNativeSurface. - private int mNativeSurface; // Surface* - private int mNativeSurfaceControl; // SurfaceControl* + int mNativeObject; // package scope only for SurfaceControl access + private int mGenerationId; // incremented each time mNativeSurface changes private final Canvas mCanvas = new CompatibleCanvas(); private int mCanvasSaveCount; // Canvas save count at time of lockCanvas() @@ -225,112 +93,12 @@ public class Surface implements Parcelable { // non compatibility mode. private Matrix mCompatibleMatrix; - private native void nativeCreate(SurfaceSession session, String name, - int w, int h, int format, int flags) - throws OutOfResourcesException; - private native void nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture) - throws OutOfResourcesException; - private native void nativeRelease(); - private native void nativeDestroy(); - - private native boolean nativeIsValid(); - private native boolean nativeIsConsumerRunningBehind(); - - private native Canvas nativeLockCanvas(Rect dirty); - private native void nativeUnlockCanvasAndPost(Canvas canvas); - - private static native Bitmap nativeScreenshot(IBinder displayToken, - int width, int height, int minLayer, int maxLayer, boolean allLayers); - - private static native void nativeOpenTransaction(); - private static native void nativeCloseTransaction(); - private static native void nativeSetAnimationTransaction(); - - private native void nativeSetLayer(int zorder); - private native void nativeSetPosition(float x, float y); - private native void nativeSetSize(int w, int h); - private native void nativeSetTransparentRegionHint(Region region); - private native void nativeSetAlpha(float alpha); - private native void nativeSetMatrix(float dsdx, float dtdx, float dsdy, float dtdy); - private native void nativeSetFlags(int flags, int mask); - private native void nativeSetWindowCrop(Rect crop); - private native void nativeSetLayerStack(int layerStack); - - private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId); - private static native IBinder nativeCreateDisplay(String name, boolean secure); - private static native void nativeSetDisplaySurface( - IBinder displayToken, Surface surface); - private static native void nativeSetDisplayLayerStack( - IBinder displayToken, int layerStack); - private static native void nativeSetDisplayProjection( - IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect); - private static native boolean nativeGetDisplayInfo( - IBinder displayToken, PhysicalDisplayInfo outInfo); - private static native void nativeBlankDisplay(IBinder displayToken); - private static native void nativeUnblankDisplay(IBinder displayToken); - - private native void nativeCopyFrom(Surface other); - private native void nativeTransferFrom(Surface other); - private native void nativeReadFromParcel(Parcel source); - private native void nativeWriteToParcel(Parcel dest); - /** * Create an empty surface, which will later be filled in by readFromParcel(). * @hide */ public Surface() { - checkHeadless(); - - mCloseGuard.open("release"); - } - - /** - * Create a surface with a name. - * - * The surface creation flags specify what kind of surface to create and - * certain options such as whether the surface can be assumed to be opaque - * and whether it should be initially hidden. Surfaces should always be - * created with the {@link #HIDDEN} flag set to ensure that they are not - * made visible prematurely before all of the surface's properties have been - * configured. - * - * Good practice is to first create the surface with the {@link #HIDDEN} flag - * specified, open a transaction, set the surface layer, layer stack, alpha, - * and position, call {@link #show} if appropriate, and close the transaction. - * - * @param session The surface session, must not be null. - * @param name The surface name, must not be null. - * @param w The surface initial width. - * @param h The surface initial height. - * @param flags The surface creation flags. Should always include {@link #HIDDEN} - * in the creation flags. - * @hide - */ - public Surface(SurfaceSession session, - String name, int w, int h, int format, int flags) - throws OutOfResourcesException { - if (session == null) { - throw new IllegalArgumentException("session must not be null"); - } - if (name == null) { - throw new IllegalArgumentException("name must not be null"); - } - - if ((flags & HIDDEN) == 0) { - Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set " - + "to ensure that they are not made visible prematurely before " - + "all of the surface's properties have been configured. " - + "Set the other properties and make the surface visible within " - + "a transaction. New surface name: " + name, - new Throwable()); - } - - checkHeadless(); - - mName = name; - nativeCreate(session, name, w, h, format, flags); - mCloseGuard.open("release"); } @@ -349,11 +117,9 @@ public class Surface implements Parcelable { throw new IllegalArgumentException("surfaceTexture must not be null"); } - checkHeadless(); - mName = surfaceTexture.toString(); try { - nativeCreateFromSurfaceTexture(surfaceTexture); + mNativeObject = nativeCreateFromSurfaceTexture(surfaceTexture); } catch (OutOfResourcesException ex) { // We can't throw OutOfResourcesException because it would be an API change. throw new RuntimeException(ex); @@ -362,13 +128,20 @@ public class Surface implements Parcelable { mCloseGuard.open("release"); } + private Surface(int nativeObject) { + mNativeObject = nativeObject; + mCloseGuard.open("release"); + } + @Override protected void finalize() throws Throwable { try { if (mCloseGuard != null) { mCloseGuard.warnIfOpen(); } - nativeRelease(); + if (mNativeObject != 0) { + nativeRelease(mNativeObject); + } } finally { super.finalize(); } @@ -380,7 +153,10 @@ public class Surface implements Parcelable { * This will make the surface invalid. */ public void release() { - nativeRelease(); + if (mNativeObject != 0) { + nativeRelease(mNativeObject); + mNativeObject = 0; + } mCloseGuard.close(); } @@ -391,7 +167,10 @@ public class Surface implements Parcelable { * @hide */ public void destroy() { - nativeDestroy(); + if (mNativeObject != 0) { + nativeDestroy(mNativeObject); + mNativeObject = 0; + } mCloseGuard.close(); } @@ -402,7 +181,8 @@ public class Surface implements Parcelable { * Otherwise returns false. */ public boolean isValid() { - return nativeIsValid(); + if (mNativeObject == 0) return false; + return nativeIsValid(mNativeObject); } /** @@ -423,7 +203,8 @@ public class Surface implements Parcelable { * @hide */ public boolean isConsumerRunningBehind() { - return nativeIsConsumerRunningBehind(); + checkNotReleased(); + return nativeIsConsumerRunningBehind(mNativeObject); } /** @@ -441,9 +222,10 @@ public class Surface implements Parcelable { * entire surface should be redrawn. * @return A canvas for drawing into the surface. */ - public Canvas lockCanvas(Rect dirty) + public Canvas lockCanvas(Rect inOutDirty) throws OutOfResourcesException, IllegalArgumentException { - return nativeLockCanvas(dirty); + checkNotReleased(); + return nativeLockCanvas(mNativeObject, inOutDirty); } /** @@ -453,7 +235,8 @@ public class Surface implements Parcelable { * @param canvas The canvas previously obtained from {@link #lockCanvas}. */ public void unlockCanvasAndPost(Canvas canvas) { - nativeUnlockCanvasAndPost(canvas); + checkNotReleased(); + nativeUnlockCanvasAndPost(mNativeObject, canvas); } /** @@ -476,190 +259,6 @@ public class Surface implements Parcelable { } } - /** - * Like {@link #screenshot(int, int, int, int)} but includes all - * Surfaces in the screenshot. - * - * @hide - */ - public static Bitmap screenshot(int width, int height) { - // TODO: should take the display as a parameter - IBinder displayToken = getBuiltInDisplay(BUILT_IN_DISPLAY_ID_MAIN); - return nativeScreenshot(displayToken, width, height, 0, 0, true); - } - - /** - * Copy the current screen contents into a bitmap and return it. - * - * @param width The desired width of the returned bitmap; the raw - * screen will be scaled down to this size. - * @param height The desired height of the returned bitmap; the raw - * screen will be scaled down to this size. - * @param minLayer The lowest (bottom-most Z order) surface layer to - * include in the screenshot. - * @param maxLayer The highest (top-most Z order) surface layer to - * include in the screenshot. - * @return Returns a Bitmap containing the screen contents, or null - * if an error occurs. - * - * @hide - */ - public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer) { - // TODO: should take the display as a parameter - IBinder displayToken = getBuiltInDisplay(BUILT_IN_DISPLAY_ID_MAIN); - return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false); - } - - /* - * set surface parameters. - * needs to be inside open/closeTransaction block - */ - - /** start a transaction @hide */ - public static void openTransaction() { - nativeOpenTransaction(); - } - - /** end a transaction @hide */ - public static void closeTransaction() { - nativeCloseTransaction(); - } - - /** flag the transaction as an animation @hide */ - public static void setAnimationTransaction() { - nativeSetAnimationTransaction(); - } - - /** @hide */ - public void setLayer(int zorder) { - nativeSetLayer(zorder); - } - - /** @hide */ - public void setPosition(int x, int y) { - nativeSetPosition((float)x, (float)y); - } - - /** @hide */ - public void setPosition(float x, float y) { - nativeSetPosition(x, y); - } - - /** @hide */ - public void setSize(int w, int h) { - nativeSetSize(w, h); - } - - /** @hide */ - public void hide() { - nativeSetFlags(SURFACE_HIDDEN, SURFACE_HIDDEN); - } - - /** @hide */ - public void show() { - nativeSetFlags(0, SURFACE_HIDDEN); - } - - /** @hide */ - public void setTransparentRegionHint(Region region) { - nativeSetTransparentRegionHint(region); - } - - /** @hide */ - public void setAlpha(float alpha) { - nativeSetAlpha(alpha); - } - - /** @hide */ - public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { - nativeSetMatrix(dsdx, dtdx, dsdy, dtdy); - } - - /** @hide */ - public void setFlags(int flags, int mask) { - nativeSetFlags(flags, mask); - } - - /** @hide */ - public void setWindowCrop(Rect crop) { - nativeSetWindowCrop(crop); - } - - /** @hide */ - public void setLayerStack(int layerStack) { - nativeSetLayerStack(layerStack); - } - - /** @hide */ - public static IBinder getBuiltInDisplay(int builtInDisplayId) { - return nativeGetBuiltInDisplay(builtInDisplayId); - } - - /** @hide */ - public static IBinder createDisplay(String name, boolean secure) { - if (name == null) { - throw new IllegalArgumentException("name must not be null"); - } - return nativeCreateDisplay(name, secure); - } - - /** @hide */ - public static void setDisplaySurface(IBinder displayToken, Surface surface) { - if (displayToken == null) { - throw new IllegalArgumentException("displayToken must not be null"); - } - nativeSetDisplaySurface(displayToken, surface); - } - - /** @hide */ - public static void setDisplayLayerStack(IBinder displayToken, int layerStack) { - if (displayToken == null) { - throw new IllegalArgumentException("displayToken must not be null"); - } - nativeSetDisplayLayerStack(displayToken, layerStack); - } - - /** @hide */ - public static void setDisplayProjection(IBinder displayToken, - int orientation, Rect layerStackRect, Rect displayRect) { - if (displayToken == null) { - throw new IllegalArgumentException("displayToken must not be null"); - } - if (layerStackRect == null) { - throw new IllegalArgumentException("layerStackRect must not be null"); - } - if (displayRect == null) { - throw new IllegalArgumentException("displayRect must not be null"); - } - nativeSetDisplayProjection(displayToken, orientation, layerStackRect, displayRect); - } - - /** @hide */ - public static boolean getDisplayInfo(IBinder displayToken, PhysicalDisplayInfo outInfo) { - if (displayToken == null) { - throw new IllegalArgumentException("displayToken must not be null"); - } - if (outInfo == null) { - throw new IllegalArgumentException("outInfo must not be null"); - } - return nativeGetDisplayInfo(displayToken, outInfo); - } - - /** @hide */ - public static void blankDisplay(IBinder displayToken) { - if (displayToken == null) { - throw new IllegalArgumentException("displayToken must not be null"); - } - nativeBlankDisplay(displayToken); - } - - /** @hide */ - public static void unblankDisplay(IBinder displayToken) { - if (displayToken == null) { - throw new IllegalArgumentException("displayToken must not be null"); - } - nativeUnblankDisplay(displayToken); - } /** * Copy another surface to this one. This surface now holds a reference @@ -670,13 +269,15 @@ public class Surface implements Parcelable { * in to it. * @hide */ - public void copyFrom(Surface other) { + public void copyFrom(SurfaceControl other) { if (other == null) { throw new IllegalArgumentException("other must not be null"); } - if (other != this) { - nativeCopyFrom(other); + if (other.mNativeObject == 0) { + throw new NullPointerException( + "SurfaceControl native object is null. Are you using a released SurfaceControl?"); } + mNativeObject = nativeCopyFrom(mNativeObject, other.mNativeObject); } /** @@ -692,7 +293,13 @@ public class Surface implements Parcelable { throw new IllegalArgumentException("other must not be null"); } if (other != this) { - nativeTransferFrom(other); + if (mNativeObject != 0) { + // release our reference to our native object + nativeRelease(mNativeObject); + } + // transfer the reference from other to us + mNativeObject = other.mNativeObject; + other.mNativeObject = 0; } } @@ -705,9 +312,8 @@ public class Surface implements Parcelable { if (source == null) { throw new IllegalArgumentException("source must not be null"); } - mName = source.readString(); - nativeReadFromParcel(source); + mNativeObject = nativeReadFromParcel(mNativeObject, source); } @Override @@ -715,9 +321,8 @@ public class Surface implements Parcelable { if (dest == null) { throw new IllegalArgumentException("dest must not be null"); } - dest.writeString(mName); - nativeWriteToParcel(dest); + nativeWriteToParcel(mNativeObject, dest); if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { release(); } @@ -728,85 +333,18 @@ public class Surface implements Parcelable { return "Surface(name=" + mName + ")"; } - private static void checkHeadless() { - if (HEADLESS) { - throw new UnsupportedOperationException("Device is headless"); - } - } - /** * Exception thrown when a surface couldn't be created or resized. */ public static class OutOfResourcesException extends Exception { public OutOfResourcesException() { } - public OutOfResourcesException(String name) { super(name); } } /** - * Describes the properties of a physical display known to surface flinger. - * @hide - */ - public static final class PhysicalDisplayInfo { - public int width; - public int height; - public float refreshRate; - public float density; - public float xDpi; - public float yDpi; - public boolean secure; - - public PhysicalDisplayInfo() { - } - - public PhysicalDisplayInfo(PhysicalDisplayInfo other) { - copyFrom(other); - } - - @Override - public boolean equals(Object o) { - return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o); - } - - public boolean equals(PhysicalDisplayInfo other) { - return other != null - && width == other.width - && height == other.height - && refreshRate == other.refreshRate - && density == other.density - && xDpi == other.xDpi - && yDpi == other.yDpi - && secure == other.secure; - } - - @Override - public int hashCode() { - return 0; // don't care - } - - public void copyFrom(PhysicalDisplayInfo other) { - width = other.width; - height = other.height; - refreshRate = other.refreshRate; - density = other.density; - xDpi = other.xDpi; - yDpi = other.yDpi; - secure = other.secure; - } - - // For debugging purposes - @Override - public String toString() { - return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, " - + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure - + "}"; - } - } - - /** * Returns a human readable representation of a rotation. * * @param rotation The rotation. @@ -893,4 +431,25 @@ public class Surface implements Parcelable { mOrigMatrix.set(m); } } + + private void checkNotReleased() { + if (mNativeObject == 0) throw new NullPointerException( + "mNativeObject is null. Have you called release() already?"); + } + + private native int nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture) + throws OutOfResourcesException; + + private native void nativeRelease(int nativeObject); + private native void nativeDestroy(int nativeObject); + private native boolean nativeIsValid(int nativeObject); + + private native boolean nativeIsConsumerRunningBehind(int nativeObject); + + private native Canvas nativeLockCanvas(int nativeObject, Rect dirty); + private native void nativeUnlockCanvasAndPost(int nativeObject, Canvas canvas); + + private native int nativeCopyFrom(int nativeObject, int surfaceControlNativeObject); + private native int nativeReadFromParcel(int nativeObject, Parcel source); + private native void nativeWriteToParcel(int nativeObject, Parcel dest); } |