FileDocCategorySizeDatePackage
Surface.javaAPI DocAndroid 5.1 API21250Thu Mar 12 22:22:10 GMT 2015android.view

Surface

public class Surface extends Object implements android.os.Parcelable
Handle onto a raw buffer that is being managed by the screen compositor.

Fields Summary
private static final String
TAG
public static final Parcelable.Creator
CREATOR
private final dalvik.system.CloseGuard
mCloseGuard
final Object
mLock
private String
mName
long
mNativeObject
private long
mLockedObject
private int
mGenerationId
private final android.graphics.Canvas
mCanvas
private android.graphics.Matrix
mCompatibleMatrix
private HwuiContext
mHwuiContext
public static final int
ROTATION_0
Rotation constant: 0 degree rotation (natural orientation)
public static final int
ROTATION_90
Rotation constant: 90 degree rotation.
public static final int
ROTATION_180
Rotation constant: 180 degree rotation.
public static final int
ROTATION_270
Rotation constant: 270 degree rotation.
Constructors Summary
public Surface()
Create an empty surface, which will later be filled in by readFromParcel().

hide


                      
      
    
public Surface(android.graphics.SurfaceTexture surfaceTexture)
Create Surface from a {@link SurfaceTexture}. Images drawn to the Surface will be made available to the {@link SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link SurfaceTexture#updateTexImage}.

param
surfaceTexture The {@link SurfaceTexture} that is updated by this Surface.
throws
OutOfResourcesException if the surface could not be created.

        if (surfaceTexture == null) {
            throw new IllegalArgumentException("surfaceTexture must not be null");
        }

        synchronized (mLock) {
            mName = surfaceTexture.toString();
            setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
        }
    
private Surface(long nativeObject)

        synchronized (mLock) {
            setNativeObjectLocked(nativeObject);
        }
    
Methods Summary
public voidallocateBuffers()
Allocate buffers ahead of time to avoid allocation delays during rendering

hide

        synchronized (mLock) {
            checkNotReleasedLocked();
            nativeAllocateBuffers(mNativeObject);
        }
    
private voidcheckNotReleasedLocked()

        if (mNativeObject == 0) {
            throw new IllegalStateException("Surface has already been released.");
        }
    
public voidcopyFrom(SurfaceControl other)
Copy another surface to this one. This surface now holds a reference to the same data as the original surface, and is -not- the owner. This is for use by the window manager when returning a window surface back from a client, converting it from the representation being managed by the window manager to the representation the client uses to draw in to it.

hide

        if (other == null) {
            throw new IllegalArgumentException("other must not be null");
        }

        long surfaceControlPtr = other.mNativeObject;
        if (surfaceControlPtr == 0) {
            throw new NullPointerException(
                    "SurfaceControl native object is null. Are you using a released SurfaceControl?");
        }
        long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);

        synchronized (mLock) {
            if (mNativeObject != 0) {
                nativeRelease(mNativeObject);
            }
            setNativeObjectLocked(newNativeObject);
        }
    
public intdescribeContents()

        return 0;
    
public voiddestroy()
Free all server-side state associated with this surface and release this object's reference. This method can only be called from the process that created the service.

hide

        release();
    
protected voidfinalize()

        try {
            if (mCloseGuard != null) {
                mCloseGuard.warnIfOpen();
            }
            release();
        } finally {
            super.finalize();
        }
    
public intgetGenerationId()
Gets the generation number of this surface, incremented each time the native surface contained within this object changes.

return
The current generation number.
hide

        synchronized (mLock) {
            return mGenerationId;
        }
    
public booleanisConsumerRunningBehind()
Returns true if the consumer of this Surface is running behind the producer.

return
True if the consumer is more than one buffer ahead of the producer.
hide

        synchronized (mLock) {
            checkNotReleasedLocked();
            return nativeIsConsumerRunningBehind(mNativeObject);
        }
    
public booleanisValid()
Returns true if this object holds a valid surface.

return
True if it holds a physical surface, so lockCanvas() will succeed. Otherwise returns false.

        synchronized (mLock) {
            if (mNativeObject == 0) return false;
            return nativeIsValid(mNativeObject);
        }
    
public android.graphics.CanvaslockCanvas(android.graphics.Rect inOutDirty)
Gets a {@link Canvas} for drawing into this surface. After drawing into the provided {@link Canvas}, the caller must invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.

param
inOutDirty A rectangle that represents the dirty region that the caller wants to redraw. This function may choose to expand the dirty rectangle if for example the surface has been resized or if the previous contents of the surface were not available. The caller must redraw the entire dirty region as represented by the contents of the inOutDirty rectangle upon return from this function. The caller may also pass null instead, in the case where the entire surface should be redrawn.
return
A canvas for drawing into the surface.
throws
IllegalArgumentException If the inOutDirty rectangle is not valid.
throws
OutOfResourcesException If the canvas cannot be locked.

        synchronized (mLock) {
            checkNotReleasedLocked();
            if (mLockedObject != 0) {
                // Ideally, nativeLockCanvas() would throw in this situation and prevent the
                // double-lock, but that won't happen if mNativeObject was updated.  We can't
                // abandon the old mLockedObject because it might still be in use, so instead
                // we just refuse to re-lock the Surface.
                throw new IllegalArgumentException("Surface was already locked");
            }
            mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
            return mCanvas;
        }
    
public android.graphics.CanvaslockHardwareCanvas()
Gets a {@link Canvas} for drawing into this surface. After drawing into the provided {@link Canvas}, the caller must invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. Unlike {@link #lockCanvas(Rect)} this will return a hardware-accelerated canvas. See the unsupported drawing operations for a list of what is and isn't supported in a hardware-accelerated canvas. It is also required to fully cover the surface every time {@link #lockHardwareCanvas()} is called as the buffer is not preserved between frames. Partial updates are not supported.

return
A canvas for drawing into the surface.
throws
IllegalStateException If the canvas cannot be locked.
hide

        synchronized (mLock) {
            checkNotReleasedLocked();
            if (mHwuiContext == null) {
                mHwuiContext = new HwuiContext();
            }
            return mHwuiContext.lockCanvas(
                    nativeGetWidth(mNativeObject),
                    nativeGetHeight(mNativeObject));
        }
    
private static native longnHwuiCreate(long rootNode, long surface)

private static native voidnHwuiDestroy(long renderer)

private static native voidnHwuiDraw(long renderer)

private static native voidnHwuiSetSurface(long renderer, long surface)

private static native voidnativeAllocateBuffers(long nativeObject)

private static native longnativeCreateFromSurfaceControl(long surfaceControlNativeObject)

private static native longnativeCreateFromSurfaceTexture(android.graphics.SurfaceTexture surfaceTexture)

private static native intnativeGetHeight(long nativeObject)

private static native intnativeGetWidth(long nativeObject)

private static native booleannativeIsConsumerRunningBehind(long nativeObject)

private static native booleannativeIsValid(long nativeObject)

private static native longnativeLockCanvas(long nativeObject, android.graphics.Canvas canvas, android.graphics.Rect dirty)

private static native longnativeReadFromParcel(long nativeObject, android.os.Parcel source)

private static native voidnativeRelease(long nativeObject)

private static native voidnativeUnlockCanvasAndPost(long nativeObject, android.graphics.Canvas canvas)

private static native voidnativeWriteToParcel(long nativeObject, android.os.Parcel dest)

public voidreadFromParcel(android.os.Parcel source)

        if (source == null) {
            throw new IllegalArgumentException("source must not be null");
        }

        synchronized (mLock) {
            // nativeReadFromParcel() will either return mNativeObject, or
            // create a new native Surface and return it after reducing
            // the reference count on mNativeObject.  Either way, it is
            // not necessary to call nativeRelease() here.
            mName = source.readString();
            setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
        }
    
public voidrelease()
Release the local reference to the server-side surface. Always call release() when you're done with a Surface. This will make the surface invalid.

        synchronized (mLock) {
            if (mNativeObject != 0) {
                nativeRelease(mNativeObject);
                setNativeObjectLocked(0);
            }
            if (mHwuiContext != null) {
                mHwuiContext.destroy();
                mHwuiContext = null;
            }
        }
    
public static java.lang.StringrotationToString(int rotation)
Returns a human readable representation of a rotation.

param
rotation The rotation.
return
The rotation symbolic name.
hide

        switch (rotation) {
            case Surface.ROTATION_0: {
                return "ROTATION_0";
            }
            case Surface.ROTATION_90: {
                return "ROATATION_90";
            }
            case Surface.ROTATION_180: {
                return "ROATATION_180";
            }
            case Surface.ROTATION_270: {
                return "ROATATION_270";
            }
            default: {
                throw new IllegalArgumentException("Invalid rotation: " + rotation);
            }
        }
    
voidsetCompatibilityTranslator(android.content.res.CompatibilityInfo.Translator translator)
Sets the translator used to scale canvas's width/height in compatibility mode.

        if (translator != null) {
            float appScale = translator.applicationScale;
            mCompatibleMatrix = new Matrix();
            mCompatibleMatrix.setScale(appScale, appScale);
        }
    
private voidsetNativeObjectLocked(long ptr)

        if (mNativeObject != ptr) {
            if (mNativeObject == 0 && ptr != 0) {
                mCloseGuard.open("release");
            } else if (mNativeObject != 0 && ptr == 0) {
                mCloseGuard.close();
            }
            mNativeObject = ptr;
            mGenerationId += 1;
            if (mHwuiContext != null) {
                mHwuiContext.updateSurface();
            }
        }
    
public java.lang.StringtoString()

        synchronized (mLock) {
            return "Surface(name=" + mName + ")/@0x" +
                    Integer.toHexString(System.identityHashCode(this));
        }
    
public voidtransferFrom(android.view.Surface other)
This is intended to be used by {@link SurfaceView#updateWindow} only.

param
other access is not thread safe
hide
deprecated

        if (other == null) {
            throw new IllegalArgumentException("other must not be null");
        }
        if (other != this) {
            final long newPtr;
            synchronized (other.mLock) {
                newPtr = other.mNativeObject;
                other.setNativeObjectLocked(0);
            }

            synchronized (mLock) {
                if (mNativeObject != 0) {
                    nativeRelease(mNativeObject);
                }
                setNativeObjectLocked(newPtr);
            }
        }
    
public voidunlockCanvas(android.graphics.Canvas canvas)

deprecated
This API has been removed and is not supported. Do not use.

        throw new UnsupportedOperationException();
    
public voidunlockCanvasAndPost(android.graphics.Canvas canvas)
Posts the new contents of the {@link Canvas} to the surface and releases the {@link Canvas}.

param
canvas The canvas previously obtained from {@link #lockCanvas}.

        synchronized (mLock) {
            checkNotReleasedLocked();

            if (mHwuiContext != null) {
                mHwuiContext.unlockAndPost(canvas);
            } else {
                unlockSwCanvasAndPost(canvas);
            }
        }
    
private voidunlockSwCanvasAndPost(android.graphics.Canvas canvas)

        if (canvas != mCanvas) {
            throw new IllegalArgumentException("canvas object must be the same instance that "
                    + "was previously returned by lockCanvas");
        }
        if (mNativeObject != mLockedObject) {
            Log.w(TAG, "WARNING: Surface's mNativeObject (0x" +
                    Long.toHexString(mNativeObject) + ") != mLockedObject (0x" +
                    Long.toHexString(mLockedObject) +")");
        }
        if (mLockedObject == 0) {
            throw new IllegalStateException("Surface was not locked");
        }
        try {
            nativeUnlockCanvasAndPost(mLockedObject, canvas);
        } finally {
            nativeRelease(mLockedObject);
            mLockedObject = 0;
        }
    
public voidwriteToParcel(android.os.Parcel dest, int flags)

        if (dest == null) {
            throw new IllegalArgumentException("dest must not be null");
        }
        synchronized (mLock) {
            dest.writeString(mName);
            nativeWriteToParcel(mNativeObject, dest);
        }
        if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
            release();
        }