Surface.java revision 7c1ad0cac642dc9a2e84499d7503b7804e0552fe
1a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar/*
2a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * Copyright (C) 2007 The Android Open Source Project
3a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar *
4a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * Licensed under the Apache License, Version 2.0 (the "License");
5a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * you may not use this file except in compliance with the License.
6a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * You may obtain a copy of the License at
7a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar *
8a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar *      http://www.apache.org/licenses/LICENSE-2.0
9a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar *
10a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * Unless required by applicable law or agreed to in writing, software
11d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth * distributed under the License is distributed on an "AS IS" BASIS,
12dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth * See the License for the specific language governing permissions and
14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth * limitations under the License.
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth */
168c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar
174a0abd80f18f9c2a10bf5b14cd6731d51972a426Daniel Dunbarpackage android.view;
18a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar
198c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbarimport android.annotation.IntDef;
202761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarimport android.content.res.CompatibilityInfo.Translator;
21abde2982e3c660398ff5a8e5f7ac3d1467b83062Daniel Dunbarimport android.graphics.Canvas;
2290edac0e8b35f766599362b6301863229f0ddcdbChris Lattnerimport android.graphics.Matrix;
23bfe3686aee881cb7599c42fc96afc44ff9bcf356Evan Chengimport android.graphics.Rect;
240e6a052331f674dd70e28af41f654a7874405eabEvan Chengimport android.graphics.SurfaceTexture;
25e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Chengimport android.os.Parcel;
26f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattnerimport android.os.Parcelable;
27a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbarimport android.util.Log;
285e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola
29c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwinimport java.lang.annotation.Retention;
304a0abd80f18f9c2a10bf5b14cd6731d51972a426Daniel Dunbarimport java.lang.annotation.RetentionPolicy;
3186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner
32d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruthimport dalvik.system.CloseGuard;
33a11c3e25015a62c817e60ec4f955a7f3f3bb6c67Rafael Espindola
34476b242fe7a61e5f9ac6214b0bc5c680d24f152eNick Lewycky/**
35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines * Handle onto a raw buffer that is being managed by the screen compositor.
36a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar */
37a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbarpublic class Surface implements Parcelable {
38a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar    private static final String TAG = "Surface";
39a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar
4046a947d8c191e5c218e736330c9d4d59ac4bcab3Chris Lattner    private static native long nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture)
41916a94b870042772568fca7995cf45aef7a6e333Bill Wendling            throws OutOfResourcesException;
4286e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    private static native long nativeCreateFromSurfaceControl(long surfaceControlNativeObject);
4399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling
44916a94b870042772568fca7995cf45aef7a6e333Bill Wendling    private static native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty)
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            throws OutOfResourcesException;
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    private static native void nativeUnlockCanvasAndPost(long nativeObject, Canvas canvas);
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4800545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach    private static native void nativeRelease(long nativeObject);
4986e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    private static native boolean nativeIsValid(long nativeObject);
50d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner    private static native boolean nativeIsConsumerRunningBehind(long nativeObject);
519dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar    private static native long nativeReadFromParcel(long nativeObject, Parcel source);
529dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar    private static native void nativeWriteToParcel(long nativeObject, Parcel dest);
539dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar
5444d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky    private static native void nativeAllocateBuffers(long nativeObject);
559dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar
566e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola    public static final Parcelable.Creator<Surface> CREATOR =
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            new Parcelable.Creator<Surface>() {
5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        @Override
596e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola        public Surface createFromParcel(Parcel source) {
6046a947d8c191e5c218e736330c9d4d59ac4bcab3Chris Lattner            try {
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                Surface s = new Surface();
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                s.readFromParcel(source);
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                return s;
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            } catch (Exception e) {
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                Log.e(TAG, "Exception creating surface from parcel", e);
66320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola                return null;
67320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola            }
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        }
695d672cfab096390690a1a5f33b0057c4cf252c55Chris Lattner
705d672cfab096390690a1a5f33b0057c4cf252c55Chris Lattner        @Override
715d672cfab096390690a1a5f33b0057c4cf252c55Chris Lattner        public Surface[] newArray(int size) {
72a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar            return new Surface[size];
7386e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner        }
74d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner    };
75d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner
7686e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    private final CloseGuard mCloseGuard = CloseGuard.get();
7786e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner
7886e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    // Guarded state.
7986e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    final Object mLock = new Object(); // protects the native state
8086e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    private String mName;
8186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    long mNativeObject; // package scope only for SurfaceControl access
8256591ab218639d8a6e4c756ca37adaf20215c3b6Chris Lattner    private long mLockedObject;
8356591ab218639d8a6e4c756ca37adaf20215c3b6Chris Lattner    private int mGenerationId; // incremented each time mNativeObject changes
8456591ab218639d8a6e4c756ca37adaf20215c3b6Chris Lattner    private final Canvas mCanvas = new CompatibleCanvas();
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8600545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach    // A matrix to scale the matrix set by application. This is set to null for
8791bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner    // non compatibility mode.
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    private Matrix mCompatibleMatrix;
896b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar
90d32c7cfa248f685e6e3064c0958dc2f0c31a4df6Chris Lattner    private HwuiContext mHwuiContext;
9186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner
9286e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    /** @hide */
9386e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    @Retention(RetentionPolicy.SOURCE)
956b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar    public @interface Rotation {}
966b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /**
986b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar     * Rotation constant: 0 degree rotation (natural orientation)
99d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner     */
100d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner    public static final int ROTATION_0 = 0;
101d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /**
103d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner     * Rotation constant: 90 degree rotation.
104d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner     */
105d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner    public static final int ROTATION_90 = 1;
106d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner
1076b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar    /**
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * Rotation constant: 180 degree rotation.
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     */
1100fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner    public static final int ROTATION_180 = 2;
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1120fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner    /**
1130fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner     * Rotation constant: 270 degree rotation.
1146b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar     */
11546a947d8c191e5c218e736330c9d4d59ac4bcab3Chris Lattner    public static final int ROTATION_270 = 3;
11646a947d8c191e5c218e736330c9d4d59ac4bcab3Chris Lattner
117a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar    /**
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * Create an empty surface, which will later be filled in by readFromParcel().
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * @hide
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     */
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    public Surface() {
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /**
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * Create Surface from a {@link SurfaceTexture}.
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     *
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * Images drawn to the Surface will be made available to the {@link
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * SurfaceTexture#updateTexImage}.
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     *
13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * @param surfaceTexture The {@link SurfaceTexture} that is updated by this
13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * Surface.
13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * @throws OutOfResourcesException if the surface could not be created.
13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     */
13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    public Surface(SurfaceTexture surfaceTexture) {
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (surfaceTexture == null) {
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            throw new IllegalArgumentException("surfaceTexture must not be null");
13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        synchronized (mLock) {
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            mName = surfaceTexture.toString();
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
14595cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby
1469eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner    /* called from android_view_Surface_createFromIGraphicBufferProducer() */
1479eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner    private Surface(long nativeObject) {
1489eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner        synchronized (mLock) {
1499eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner            setNativeObjectLocked(nativeObject);
150a00b80b04c5edb08639c1c6b32e9231fd8b066f7Dmitri Gribenko        }
15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    @Override
154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    protected void finalize() throws Throwable {
15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        try {
15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            if (mCloseGuard != null) {
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                mCloseGuard.warnIfOpen();
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            }
15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            release();
16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        } finally {
16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            super.finalize();
162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        }
163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /**
16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * Release the local reference to the server-side surface.
16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * Always call release() when you're done with a Surface.
16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * This will make the surface invalid.
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     */
17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    public void release() {
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        synchronized (mLock) {
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            if (mNativeObject != 0) {
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                nativeRelease(mNativeObject);
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                setNativeObjectLocked(0);
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            }
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            if (mHwuiContext != null) {
17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                mHwuiContext.destroy();
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                mHwuiContext = null;
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            }
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /**
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * Free all server-side state associated with this surface and
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * release this object's reference.  This method can only be
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * called from the process that created the service.
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * @hide
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     */
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    public void destroy() {
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        release();
19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /**
19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * Returns true if this object holds a valid surface.
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     *
19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * @return True if it holds a physical surface, so lockCanvas() will succeed.
19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * Otherwise returns false.
19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     */
19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    public boolean isValid() {
20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        synchronized (mLock) {
20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            if (mNativeObject == 0) return false;
20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            return nativeIsValid(mNativeObject);
20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /**
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * Gets the generation number of this surface, incremented each time
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * the native surface contained within this object changes.
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     *
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * @return The current generation number.
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * @hide
21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     */
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    public int getGenerationId() {
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        synchronized (mLock) {
215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            return mGenerationId;
216cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        }
217cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    /**
220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines     * Returns true if the consumer of this Surface is running behind the producer.
221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines     *
222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines     * @return True if the consumer is more than one buffer ahead of the producer.
223cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines     * @hide
224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines     */
225cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    public boolean isConsumerRunningBehind() {
226cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        synchronized (mLock) {
227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            checkNotReleasedLocked();
228cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            return nativeIsConsumerRunningBehind(mNativeObject);
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /**
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * Gets a {@link Canvas} for drawing into this surface.
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     *
2354766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky     * After drawing into the provided {@link Canvas}, the caller must
236bd4ec84d154bdd3f19b07de1076a06c16f7ebce8Jim Grosbach     * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
23791bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner     *
23891bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner     * @param inOutDirty A rectangle that represents the dirty region that the caller wants
23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * to redraw.  This function may choose to expand the dirty rectangle if for example
24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * the surface has been resized or if the previous contents of the surface were
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * not available.  The caller must redraw the entire dirty region as represented
24246a947d8c191e5c218e736330c9d4d59ac4bcab3Chris Lattner     * by the contents of the inOutDirty rectangle upon return from this function.
24384a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar     * The caller may also pass <code>null</code> instead, in the case where the
24446a947d8c191e5c218e736330c9d4d59ac4bcab3Chris Lattner     * entire surface should be redrawn.
245a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar     * @return A canvas for drawing into the surface.
246d32c7cfa248f685e6e3064c0958dc2f0c31a4df6Chris Lattner     *
24786e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner     * @throws IllegalArgumentException If the inOutDirty rectangle is not valid.
24886e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner     * @throws OutOfResourcesException If the canvas cannot be locked.
24986e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner     */
250d32c7cfa248f685e6e3064c0958dc2f0c31a4df6Chris Lattner    public Canvas lockCanvas(Rect inOutDirty)
25186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner            throws Surface.OutOfResourcesException, IllegalArgumentException {
25200545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach        synchronized (mLock) {
253d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner            checkNotReleasedLocked();
254d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner            if (mLockedObject != 0) {
25500545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach                // Ideally, nativeLockCanvas() would throw in this situation and prevent the
25686e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner                // double-lock, but that won't happen if mNativeObject was updated.  We can't
257d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner                // abandon the old mLockedObject because it might still be in use, so instead
258d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner                // we just refuse to re-lock the Surface.
25900545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach                throw new IllegalArgumentException("Surface was already locked");
26014ca177beba15e86ca410c9f6fc7f48ba245dba6Chris Lattner            }
26114ca177beba15e86ca410c9f6fc7f48ba245dba6Chris Lattner            mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
26286e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner            return mCanvas;
26386e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner        }
26486e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    }
265d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner
266d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner    /**
267d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner     * Posts the new contents of the {@link Canvas} to the surface and
268d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner     * releases the {@link Canvas}.
26900545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach     *
270d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner     * @param canvas The canvas previously obtained from {@link #lockCanvas}.
27186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner     */
27200545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach    public void unlockCanvasAndPost(Canvas canvas) {
273d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner        synchronized (mLock) {
274d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner            checkNotReleasedLocked();
275d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner
27686e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner            if (mHwuiContext != null) {
27799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling                mHwuiContext.unlockAndPost(canvas);
27886e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner            } else {
27999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling                unlockSwCanvasAndPost(canvas);
28000545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach            }
28186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner        }
282d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner    }
28300545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach
28414ca177beba15e86ca410c9f6fc7f48ba245dba6Chris Lattner    private void unlockSwCanvasAndPost(Canvas canvas) {
28514ca177beba15e86ca410c9f6fc7f48ba245dba6Chris Lattner        if (canvas != mCanvas) {
28614ca177beba15e86ca410c9f6fc7f48ba245dba6Chris Lattner            throw new IllegalArgumentException("canvas object must be the same instance that "
28786e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner                    + "was previously returned by lockCanvas");
28886e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner        }
289304f6a48b1232bdad8b2c0dff7c08d677826ef86Daniel Dunbar        if (mNativeObject != mLockedObject) {
290304f6a48b1232bdad8b2c0dff7c08d677826ef86Daniel Dunbar            Log.w(TAG, "WARNING: Surface's mNativeObject (0x" +
291304f6a48b1232bdad8b2c0dff7c08d677826ef86Daniel Dunbar                    Long.toHexString(mNativeObject) + ") != mLockedObject (0x" +
292304f6a48b1232bdad8b2c0dff7c08d677826ef86Daniel Dunbar                    Long.toHexString(mLockedObject) +")");
293304f6a48b1232bdad8b2c0dff7c08d677826ef86Daniel Dunbar        }
29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (mLockedObject == 0) {
29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            throw new IllegalStateException("Surface was not locked");
29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        try {
29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            nativeUnlockCanvasAndPost(mLockedObject, canvas);
29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        } finally {
30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            nativeRelease(mLockedObject);
301df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne            mLockedObject = 0;
302df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne        }
3036c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner    }
30499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling
305a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar    /**
306a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar     * Gets a {@link Canvas} for drawing into this surface.
307a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar     *
3088906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar     * After drawing into the provided {@link Canvas}, the caller must
309ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola     * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
31071d259bc4be4f5c7a8a30c6be8da105074ff805aDaniel Dunbar     *
31199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling     * Unlike {@link #lockCanvas(Rect)} this will return a hardware-accelerated
3127d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner     * canvas. See the <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#unsupported">
313a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar     * unsupported drawing operations</a> for a list of what is and isn't
314a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar     * supported in a hardware-accelerated canvas.
31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     *
31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * @return A canvas for drawing into the surface.
31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     *
31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * @throws IllegalStateException If the canvas cannot be locked.
31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * @hide
32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     */
32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    public Canvas lockHardwareCanvas() {
32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        synchronized (mLock) {
32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            checkNotReleasedLocked();
32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            if (mHwuiContext == null) {
32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                mHwuiContext = new HwuiContext();
32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            }
32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            return mHwuiContext.lockCanvas();
32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /**
33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * @deprecated This API has been removed and is not supported.  Do not use.
33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     */
33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    @Deprecated
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    public void unlockCanvas(Canvas canvas) {
336a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner        throw new UnsupportedOperationException();
337f96db468fcf62d671cda99b68b6cfd3f2dc0b839Kevin Enderby    }
338afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim
339a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    /**
34099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling     * Sets the translator used to scale canvas's width/height in compatibility
34199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling     * mode.
34299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling     */
343f96db468fcf62d671cda99b68b6cfd3f2dc0b839Kevin Enderby    void setCompatibilityTranslator(Translator translator) {
3447d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner        if (translator != null) {
345a5c783280f83df5c60a8ed9e32c61b05a11048e3Kevin Enderby            float appScale = translator.applicationScale;
346a5c783280f83df5c60a8ed9e32c61b05a11048e3Kevin Enderby            mCompatibleMatrix = new Matrix();
347cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar            mCompatibleMatrix.setScale(appScale, appScale);
348cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar        }
349cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar    }
350cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar
351cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar    /**
352cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar     * Copy another surface to this one.  This surface now holds a reference
353cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar     * to the same data as the original surface, and is -not- the owner.
3546d49b680be6e24b547e6910c2b64914913915084Daniel Dunbar     * This is for use by the window manager when returning a window surface
355cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar     * back from a client, converting it from the representation being managed
356cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar     * by the window manager to the representation the client uses to draw
3573e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach     * in to it.
35899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling     * @hide
3593e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach     */
3603e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    public void copyFrom(SurfaceControl other) {
3613e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach        if (other == null) {
3623e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach            throw new IllegalArgumentException("other must not be null");
3633e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach        }
3643e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
3653e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach        long surfaceControlPtr = other.mNativeObject;
3663e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach        if (surfaceControlPtr == 0) {
3673e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach            throw new NullPointerException(
3683e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach                    "SurfaceControl native object is null. Are you using a released SurfaceControl?");
3693e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach        }
37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        synchronized (mLock) {
37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            if (mNativeObject != 0) {
37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                nativeRelease(mNativeObject);
37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            }
37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            setNativeObjectLocked(newNativeObject);
37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /**
38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     * This is intended to be used by {@link SurfaceView#updateWindow} only.
382ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach     * @param other access is not thread safe
383ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach     * @hide
384ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach     * @deprecated
385ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach     */
3866469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    @Deprecated
38799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    public void transferFrom(Surface other) {
388ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach        if (other == null) {
389ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach            throw new IllegalArgumentException("other must not be null");
390ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach        }
391ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach        if (other != this) {
392821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar            final long newPtr;
3937d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner            synchronized (other.mLock) {
3947d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner                newPtr = other.mNativeObject;
395fffff915d53361fc575621c5e04ae7df99dd3fabDaniel Dunbar                other.setNativeObjectLocked(0);
39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            }
397a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar
398a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar            synchronized (mLock) {
399484291c27319668ad99cb87def000254357736fbRafael Espindola                if (mNativeObject != 0) {
400484291c27319668ad99cb87def000254357736fbRafael Espindola                    nativeRelease(mNativeObject);
401484291c27319668ad99cb87def000254357736fbRafael Espindola                }
402484291c27319668ad99cb87def000254357736fbRafael Espindola                setNativeObjectLocked(newPtr);
403484291c27319668ad99cb87def000254357736fbRafael Espindola            }
4041c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool        }
405a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    }
406a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar
407858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper    @Override
408ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner    public int describeContents() {
409ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner        return 0;
410ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner    }
411ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner
412ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner    public void readFromParcel(Parcel source) {
413ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner        if (source == null) {
414e9c0ff2a76508922b3f3ec07484ba579d4c51d95Rafael Espindola            throw new IllegalArgumentException("source must not be null");
4151c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool        }
4161c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool
417523d70ec1f8daa67bb8a9fe8f7b6b3d076a26c99Dan Gohman        synchronized (mLock) {
41899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling            // nativeReadFromParcel() will either return mNativeObject, or
419ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner            // create a new native Surface and return it after reducing
4201c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool            // the reference count on mNativeObject.  Either way, it is
421ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner            // not necessary to call nativeRelease() here.
422ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner            mName = source.readString();
423ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner            setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
424ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner        }
425ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner    }
426ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner
427e9c0ff2a76508922b3f3ec07484ba579d4c51d95Rafael Espindola    @Override
428ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner    public void writeToParcel(Parcel dest, int flags) {
429ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner        if (dest == null) {
4301c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool            throw new IllegalArgumentException("dest must not be null");
431ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner        }
43299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling        synchronized (mLock) {
433ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner            dest.writeString(mName);
43461abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner            nativeWriteToParcel(mNativeObject, dest);
43561abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner        }
43661abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner        if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
43761abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner            release();
43861abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner        }
43961abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner    }
440e8e98d7f2eaa0613442ce21ab6a040c0f04f5b4dKevin Enderby
441277abc8172a19b287e9b6ea0969bc113d7ac48e4Rafael Espindola    @Override
442277abc8172a19b287e9b6ea0969bc113d7ac48e4Rafael Espindola    public String toString() {
443277abc8172a19b287e9b6ea0969bc113d7ac48e4Rafael Espindola        synchronized (mLock) {
44461abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner            return "Surface(name=" + mName + ")/@0x" +
44561abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner                    Integer.toHexString(System.identityHashCode(this));
44661abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner        }
447277abc8172a19b287e9b6ea0969bc113d7ac48e4Rafael Espindola    }
448277abc8172a19b287e9b6ea0969bc113d7ac48e4Rafael Espindola
449277abc8172a19b287e9b6ea0969bc113d7ac48e4Rafael Espindola    private void setNativeObjectLocked(long ptr) {
450a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner        if (mNativeObject != ptr) {
45199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling            if (mNativeObject == 0 && ptr != 0) {
452f59cac5ed36360b4c462781051f996b3499d7e0fKevin Enderby                mCloseGuard.open("release");
453a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar            } else if (mNativeObject != 0 && ptr == 0) {
454a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar                mCloseGuard.close();
4557d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner            }
4567d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner            mNativeObject = ptr;
4571c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool            mGenerationId += 1;
4581c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool            if (mHwuiContext != null) {
459a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar                mHwuiContext.updateSurface();
460a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar            }
46195cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby        }
4627d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner    }
4637d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner
46495cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby    private void checkNotReleasedLocked() {
46595cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby        if (mNativeObject == 0) {
466b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner            throw new IllegalStateException("Surface has already been released.");
467b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner        }
468b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    }
469b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner
470b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    /**
471b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner     * Allocate buffers ahead of time to avoid allocation delays during rendering
472b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner     * @hide
473b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner     */
474b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    public void allocateBuffers() {
475b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner        synchronized (mLock) {
476b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner            checkNotReleasedLocked();
477b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner            nativeAllocateBuffers(mNativeObject);
478b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner        }
479b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    }
480b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner
481b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    /**
482b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner     * Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or
483b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner     * when a SurfaceTexture could not successfully be allocated.
484b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner     */
485b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    @SuppressWarnings("serial")
48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    public static class OutOfResourcesException extends RuntimeException {
48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        public OutOfResourcesException() {
48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        public OutOfResourcesException(String name) {
49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            super(name);
4918f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola        }
49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
4938f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola
4948f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola    /**
4958f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola     * Returns a human readable representation of a rotation.
49699328add833807f12a4950c7de29fb2a5df04703Chris Lattner     *
49799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling     * @param rotation The rotation.
49899328add833807f12a4950c7de29fb2a5df04703Chris Lattner     * @return The rotation symbolic name.
49999328add833807f12a4950c7de29fb2a5df04703Chris Lattner     *
50099328add833807f12a4950c7de29fb2a5df04703Chris Lattner     * @hide
5019eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner     */
5027092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar    public static String rotationToString(int rotation) {
503eb46def978a60fd705cca3037feff5573122b404Richard Mitton        switch (rotation) {
504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            case Surface.ROTATION_0: {
5055cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton                return "ROTATION_0";
5069eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner            }
5076559d7688e24e204af273a1e1252639320a7b309Chris Lattner            case Surface.ROTATION_90: {
50899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling                return "ROATATION_90";
5094ed5438f4882c9fe779b1a8ff546877889b222dfChris Lattner            }
5104ed5438f4882c9fe779b1a8ff546877889b222dfChris Lattner            case Surface.ROTATION_180: {
5114ed5438f4882c9fe779b1a8ff546877889b222dfChris Lattner                return "ROATATION_180";
5124ed5438f4882c9fe779b1a8ff546877889b222dfChris Lattner            }
5137d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner            case Surface.ROTATION_270: {
5144e4db7adfc9858a8f77f841c7467bc6fcbb8110eChris Lattner                return "ROATATION_270";
5154e4db7adfc9858a8f77f841c7467bc6fcbb8110eChris Lattner            }
5169eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner            default: {
5179eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner                throw new IllegalArgumentException("Invalid rotation: " + rotation);
5189eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner            }
5199eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner        }
52036a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer    }
52136a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer
522eb46def978a60fd705cca3037feff5573122b404Richard Mitton    /**
523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines     * A Canvas class that can handle the compatibility mode.
5245cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton     * This does two things differently.
5259eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner     * <ul>
52636a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer     * <li>Returns the width and height of the target metrics, rather than
52799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling     * native. For example, the canvas returns 320x480 even if an app is running
528a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer     * in WVGA high density.
529a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer     * <li>Scales the matrix in setMatrix by the application scale, except if
530a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer     * the matrix looks like obtained from getMatrix. This is a hack to handle
53139646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer     * the case that an application uses getMatrix to keep the original matrix,
532a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer     * set matrix of its own, then set the original matrix back. There is no
533a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer     * perfect solution that works for all cases, and there are a lot of cases
53439646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer     * that this model does not work, but we hope this works for many apps.
53539646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer     * </ul>
536a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer     */
53739646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer    private final class CompatibleCanvas extends Canvas {
53836a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer        // A temp matrix to remember what an application obtained via {@link getMatrix}
5399eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner        private Matrix mOrigMatrix = null;
5409eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner
5419eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner        @Override
5428751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbar        public void setMatrix(Matrix matrix) {
543c90a1fcf9f44858b20e0f5f7e0b98049aec7a1e0Evan Cheng            if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) {
5445cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton                // don't scale the matrix if it's not compatibility mode, or
5455cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton                // the matrix was obtained from getMatrix.
5465cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton                super.setMatrix(matrix);
547011e4db845b5c4166142338c77adc8ac03e5e041Daniel Dunbar            } else {
54893b6db3de934a3cfca5586df25184fef4a54c500Chris Lattner                Matrix m = new Matrix(mCompatibleMatrix);
54900545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach                m.preConcat(matrix);
55093b6db3de934a3cfca5586df25184fef4a54c500Chris Lattner                super.setMatrix(m);
551ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner            }
55212de0df59fdab799d8d1432fcfd9190829d7f292Daniel Dunbar        }
55300545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach
554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        @SuppressWarnings("deprecation")
55510b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner        @Override
5567092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar        public void getMatrix(Matrix m) {
5577092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar            super.getMatrix(m);
5589be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner            if (mOrigMatrix == null) {
5597d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner                mOrigMatrix = new Matrix();
5609be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner            }
5619be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner            mOrigMatrix.set(m);
562d04d98d24fe5c82c7e69b711cd989ef96980fb8eEric Christopher        }
563d04d98d24fe5c82c7e69b711cd989ef96980fb8eEric Christopher    }
564d04d98d24fe5c82c7e69b711cd989ef96980fb8eEric Christopher
5654d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher    private final class HwuiContext {
5664d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher        private final RenderNode mRenderNode;
5675cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton        private long mHwuiRenderer;
5685cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton        private HardwareCanvas mCanvas;
569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
5704d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher        HwuiContext() {
5714d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher            mRenderNode = RenderNode.create("HwuiCanvas", null);
572d04d98d24fe5c82c7e69b711cd989ef96980fb8eEric Christopher            mRenderNode.setClipToBounds(false);
57300545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach            mHwuiRenderer = nHwuiCreate(mRenderNode.mNativeRenderNode, mNativeObject);
5744d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher        }
5754d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher
5764d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher        Canvas lockCanvas() {
57700545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach            if (mCanvas != null) {
578482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher                throw new IllegalStateException("Surface was already locked!");
579482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher            }
580482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher            mCanvas = mRenderNode.start(0, 0);
58112e555c36ce11c39ce15cd0b27bf7b02a068beb2Chris Lattner            return mCanvas;
58212e555c36ce11c39ce15cd0b27bf7b02a068beb2Chris Lattner        }
583a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner
584a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner        void unlockAndPost(Canvas canvas) {
58500545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach            if (canvas != mCanvas) {
586a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner                throw new IllegalArgumentException("canvas object must be the same instance that "
587a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner                        + "was previously returned by lockCanvas");
588a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner            }
589a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner            mRenderNode.end(mCanvas);
590a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner            mCanvas = null;
591a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner            nHwuiDraw(mHwuiRenderer);
59200545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach        }
593a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner
594a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner        void updateSurface() {
595a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner            nHwuiSetSurface(mHwuiRenderer, mNativeObject);
596a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner        }
59700545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach
598a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner        void destroy() {
599a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner            if (mHwuiRenderer != 0) {
600a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner                nHwuiDestroy(mHwuiRenderer);
601a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner                mHwuiRenderer = 0;
602a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner            }
603a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner        }
604a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner
605a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner        @Override
606a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner        protected void finalize() throws Throwable {
607a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner            try {
608a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner                destroy();
609a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner            } finally {
610a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner                super.finalize();
611a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner            }
61200545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach        }
613a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner    }
614a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner
615a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner    private static native long nHwuiCreate(long rootNode, long surface);
616a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner    private static native void nHwuiSetSurface(long renderer, long surface);
617a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola    private static native void nHwuiDraw(long renderer);
618df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    private static native void nHwuiDestroy(long renderer);
619df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne}
62012e555c36ce11c39ce15cd0b27bf7b02a068beb2Chris Lattner