19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbyeimport android.annotation.IntDef;
20240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshimaimport android.content.res.CompatibilityInfo.Translator;
210b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Canvas;
220b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Matrix;
230b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Rect;
240b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.SurfaceTexture;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
263866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.os.Parcelable;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
28d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye
29d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbyeimport java.lang.annotation.Retention;
30d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbyeimport java.lang.annotation.RetentionPolicy;
31d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye
323866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport dalvik.system.CloseGuard;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
35334031cd07c3bd09d23fce0ebaf946fc6ecfee26Glenn Kasten * Handle onto a raw buffer that is being managed by the screen compositor.
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Surface implements Parcelable {
3864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private static final String TAG = "Surface";
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture)
4129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian            throws OutOfResourcesException;
4236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeCreateFromSurfaceControl(long surfaceControlNativeObject);
4352800617946c456e78ed010c82d0ec4358368164Mathias Agopian
4436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty)
45fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            throws OutOfResourcesException;
4636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeUnlockCanvasAndPost(long nativeObject, Canvas canvas);
4729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
4836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeRelease(long nativeObject);
4936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeIsValid(long nativeObject);
5036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeIsConsumerRunningBehind(long nativeObject);
5136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeReadFromParcel(long nativeObject, Parcel source);
5236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeWriteToParcel(long nativeObject, Parcel dest);
5329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
545795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza    private static native void nativeAllocateBuffers(long nativeObject);
555795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza
56b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck    private static native int nativeGetWidth(long nativeObject);
57b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck    private static native int nativeGetHeight(long nativeObject);
58b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck
5964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public static final Parcelable.Creator<Surface> CREATOR =
6064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            new Parcelable.Creator<Surface>() {
61fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        @Override
6264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public Surface createFromParcel(Parcel source) {
6364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            try {
6464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Surface s = new Surface();
6564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                s.readFromParcel(source);
6664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                return s;
6764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            } catch (Exception e) {
6864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Log.e(TAG, "Exception creating surface from parcel", e);
6964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                return null;
7064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
71b85c933d850286874005f97a9764c9b22e49a597Kevin Hester        }
72fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
73fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        @Override
7464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public Surface[] newArray(int size) {
7564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            return new Surface[size];
76df0c84f90894c677c50bdc967a0598f516ac86d7Jamie Gennis        }
7764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    };
78df0c84f90894c677c50bdc967a0598f516ac86d7Jamie Gennis
7964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final CloseGuard mCloseGuard = CloseGuard.get();
80c87c4a3e3b3c3949ae3c6f8fd245b71691d5ca3bMathias Agopian
81fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    // Guarded state.
82fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    final Object mLock = new Object(); // protects the native state
83fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    private String mName;
8436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    long mNativeObject; // package scope only for SurfaceControl access
8536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private long mLockedObject;
86fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    private int mGenerationId; // incremented each time mNativeObject changes
8764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final Canvas mCanvas = new CompatibleCanvas();
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
89240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    // A matrix to scale the matrix set by application. This is set to null for
90240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    // non compatibility mode.
91240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    private Matrix mCompatibleMatrix;
9238ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima
93bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private HwuiContext mHwuiContext;
94bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
95d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    /** @hide */
96d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
97d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    @Retention(RetentionPolicy.SOURCE)
98d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    public @interface Rotation {}
99d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye
10064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
10129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 0 degree rotation (natural orientation)
10229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
10329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_0 = 0;
10429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
10529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
10629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 90 degree rotation.
10729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
10829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_90 = 1;
10929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
11029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
11129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 180 degree rotation.
11229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
11329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_180 = 2;
11429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
11529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
11629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 270 degree rotation.
11729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
11829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_270 = 3;
11929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
12029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
12164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Create an empty surface, which will later be filled in by readFromParcel().
12264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public Surface() {
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Create Surface from a {@link SurfaceTexture}.
12964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
13064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Images drawn to the Surface will be made available to the {@link
13164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link
13264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * SurfaceTexture#updateTexImage}.
13364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
13464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @param surfaceTexture The {@link SurfaceTexture} that is updated by this
13564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Surface.
136a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * @throws OutOfResourcesException if the surface could not be created.
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public Surface(SurfaceTexture surfaceTexture) {
13964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (surfaceTexture == null) {
14064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("surfaceTexture must not be null");
14164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
14264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
143fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
144fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            mName = surfaceTexture.toString();
145a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin            setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
146f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian        }
147240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    }
148240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
14986e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian    /* called from android_view_Surface_createFromIGraphicBufferProducer() */
15036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private Surface(long nativeObject) {
151fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
152fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            setNativeObjectLocked(nativeObject);
153fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
1543866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    }
1553866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian
15664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
15764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    protected void finalize() throws Throwable {
15864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        try {
15964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mCloseGuard != null) {
16064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                mCloseGuard.warnIfOpen();
16164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
16286e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian            release();
16364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        } finally {
16464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super.finalize();
16564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
166b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    }
167b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian
168240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    /**
16964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Release the local reference to the server-side surface.
17064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Always call release() when you're done with a Surface.
17164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This will make the surface invalid.
17264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
17364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void release() {
174fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
1757c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            if (mNativeObject != 0) {
1767c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian                nativeRelease(mNativeObject);
177fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                setNativeObjectLocked(0);
1787c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            }
179bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (mHwuiContext != null) {
180bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                mHwuiContext.destroy();
181bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                mHwuiContext = null;
182bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
1833866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        }
18464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
18564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
18664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
18764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Free all server-side state associated with this surface and
18864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * release this object's reference.  This method can only be
18964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * called from the process that created the service.
190b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * @hide
191b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     */
19264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void destroy() {
19386e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian        release();
19464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
19561566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn
19661566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn    /**
19764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Returns true if this object holds a valid surface.
19864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
19964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return True if it holds a physical surface, so lockCanvas() will succeed.
20064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Otherwise returns false.
20161566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn     */
20264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public boolean isValid() {
203fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
2047c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            if (mNativeObject == 0) return false;
2057c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            return nativeIsValid(mNativeObject);
2067c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
20764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
20861566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn
20964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
21064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Gets the generation number of this surface, incremented each time
21164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the native surface contained within this object changes.
21264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
21364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return The current generation number.
21464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
21564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
216b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    public int getGenerationId() {
217fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
218fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            return mGenerationId;
219fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
220b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    }
221b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian
222c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian    /**
22364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Returns true if the consumer of this Surface is running behind the producer.
22464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
22564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return True if the consumer is more than one buffer ahead of the producer.
226c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian     * @hide
227c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian     */
22864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public boolean isConsumerRunningBehind() {
229fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
2307c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            checkNotReleasedLocked();
2317c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            return nativeIsConsumerRunningBehind(mNativeObject);
2327c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
23364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
234c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian
235b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    /**
23664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Gets a {@link Canvas} for drawing into this surface.
23764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
2389ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian     * After drawing into the provided {@link Canvas}, the caller must
23964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
24064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
24130d7ab9a10fcde397bae7bed5f16d1094fded8b2Mathias Agopian     * @param inOutDirty A rectangle that represents the dirty region that the caller wants
24264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * to redraw.  This function may choose to expand the dirty rectangle if for example
24364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the surface has been resized or if the previous contents of the surface were
2449ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian     * not available.  The caller must redraw the entire dirty region as represented
2459ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian     * by the contents of the inOutDirty rectangle upon return from this function.
24664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * The caller may also pass <code>null</code> instead, in the case where the
24764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * entire surface should be redrawn.
24864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return A canvas for drawing into the surface.
249a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     *
250a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * @throws IllegalArgumentException If the inOutDirty rectangle is not valid.
251a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * @throws OutOfResourcesException If the canvas cannot be locked.
252240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima     */
2533866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    public Canvas lockCanvas(Rect inOutDirty)
254a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin            throws Surface.OutOfResourcesException, IllegalArgumentException {
255fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
2567c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            checkNotReleasedLocked();
257ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            if (mLockedObject != 0) {
258ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                // Ideally, nativeLockCanvas() would throw in this situation and prevent the
259ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                // double-lock, but that won't happen if mNativeObject was updated.  We can't
260ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                // abandon the old mLockedObject because it might still be in use, so instead
261ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                // we just refuse to re-lock the Surface.
262d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall                throw new IllegalArgumentException("Surface was already locked");
263ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            }
264ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
265fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            return mCanvas;
2667c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
26764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
268240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
26964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
27064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Posts the new contents of the {@link Canvas} to the surface and
27164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * releases the {@link Canvas}.
27264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
27364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @param canvas The canvas previously obtained from {@link #lockCanvas}.
27464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
27564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void unlockCanvasAndPost(Canvas canvas) {
276bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        synchronized (mLock) {
277bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            checkNotReleasedLocked();
278bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
279bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (mHwuiContext != null) {
280bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                mHwuiContext.unlockAndPost(canvas);
281bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            } else {
282bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                unlockSwCanvasAndPost(canvas);
283bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
284bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
285bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    }
286bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
287bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private void unlockSwCanvasAndPost(Canvas canvas) {
288fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        if (canvas != mCanvas) {
289fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            throw new IllegalArgumentException("canvas object must be the same instance that "
290fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                    + "was previously returned by lockCanvas");
291fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
292bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        if (mNativeObject != mLockedObject) {
293bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            Log.w(TAG, "WARNING: Surface's mNativeObject (0x" +
294bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                    Long.toHexString(mNativeObject) + ") != mLockedObject (0x" +
295bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                    Long.toHexString(mLockedObject) +")");
296bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
297bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        if (mLockedObject == 0) {
298bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            throw new IllegalStateException("Surface was not locked");
299bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
300bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        try {
301bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            nativeUnlockCanvasAndPost(mLockedObject, canvas);
302bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        } finally {
303bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            nativeRelease(mLockedObject);
304bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mLockedObject = 0;
305bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
306bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    }
307fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
308bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    /**
309bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * Gets a {@link Canvas} for drawing into this surface.
310bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     *
311bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * After drawing into the provided {@link Canvas}, the caller must
312bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
313bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     *
314bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * Unlike {@link #lockCanvas(Rect)} this will return a hardware-accelerated
315bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * canvas. See the <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#unsupported">
316bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * unsupported drawing operations</a> for a list of what is and isn't
31743a5328c8377aa29acd51098d915503e87f13a9aJohn Reck     * supported in a hardware-accelerated canvas. It is also required to
31843a5328c8377aa29acd51098d915503e87f13a9aJohn Reck     * fully cover the surface every time {@link #lockHardwareCanvas()} is
31943a5328c8377aa29acd51098d915503e87f13a9aJohn Reck     * called as the buffer is not preserved between frames. Partial updates
32043a5328c8377aa29acd51098d915503e87f13a9aJohn Reck     * are not supported.
321bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     *
322bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * @return A canvas for drawing into the surface.
323bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     *
324bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * @throws IllegalStateException If the canvas cannot be locked.
3257c1ad0cac642dc9a2e84499d7503b7804e0552feJustin Koh     * @hide
326bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     */
327bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    public Canvas lockHardwareCanvas() {
328fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
3297c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            checkNotReleasedLocked();
330bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (mHwuiContext == null) {
331bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                mHwuiContext = new HwuiContext();
332d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall            }
333b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck            return mHwuiContext.lockCanvas(
334b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck                    nativeGetWidth(mNativeObject),
335b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck                    nativeGetHeight(mNativeObject));
3367c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
33764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
338240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
339ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden    /**
34064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @deprecated This API has been removed and is not supported.  Do not use.
34164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
34264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Deprecated
34364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void unlockCanvas(Canvas canvas) {
34464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        throw new UnsupportedOperationException();
345d10cd5765a2b706fc174f16b951d6b0a5d3740d3Romain Guy    }
34638ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima
34738ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima    /**
348b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * Sets the translator used to scale canvas's width/height in compatibility
349b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * mode.
35038ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima     */
3515be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn    void setCompatibilityTranslator(Translator translator) {
352240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima        if (translator != null) {
353240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            float appScale = translator.applicationScale;
354240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            mCompatibleMatrix = new Matrix();
355240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            mCompatibleMatrix.setScale(appScale, appScale);
356240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima        }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
36064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Copy another surface to this one.  This surface now holds a reference
36164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * to the same data as the original surface, and is -not- the owner.
36264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This is for use by the window manager when returning a window surface
36364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * back from a client, converting it from the representation being managed
36464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * by the window manager to the representation the client uses to draw
36564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * in to it.
36664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
36764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
3683866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    public void copyFrom(SurfaceControl other) {
36964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other == null) {
37064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("other must not be null");
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
372fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
37336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        long surfaceControlPtr = other.mNativeObject;
374fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        if (surfaceControlPtr == 0) {
3753866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            throw new NullPointerException(
3763866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                    "SurfaceControl native object is null. Are you using a released SurfaceControl?");
37764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
37836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
379fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
380fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
381fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            if (mNativeObject != 0) {
382fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                nativeRelease(mNativeObject);
3837c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            }
384fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            setNativeObjectLocked(newNativeObject);
38586e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian        }
38664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
38764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
38864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
389fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown     * This is intended to be used by {@link SurfaceView#updateWindow} only.
3907c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian     * @param other access is not thread safe
3917c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian     * @hide
3927c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian     * @deprecated
39364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
3947c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian    @Deprecated
39564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void transferFrom(Surface other) {
39664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other == null) {
39764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("other must not be null");
39864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
39964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other != this) {
40036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat            final long newPtr;
401fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            synchronized (other.mLock) {
402fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                newPtr = other.mNativeObject;
403fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                other.setNativeObjectLocked(0);
404fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            }
405fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
406fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            synchronized (mLock) {
4077c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian                if (mNativeObject != 0) {
4087c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian                    nativeRelease(mNativeObject);
4097c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian                }
410fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                setNativeObjectLocked(newPtr);
4113866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            }
41264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
41364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
41664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public int describeContents() {
41764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return 0;
41864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
41964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
42064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void readFromParcel(Parcel source) {
42164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (source == null) {
42264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("source must not be null");
423f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian        }
424fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
425fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
426ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            // nativeReadFromParcel() will either return mNativeObject, or
427ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            // create a new native Surface and return it after reducing
428ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            // the reference count on mNativeObject.  Either way, it is
429ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            // not necessary to call nativeRelease() here.
4307c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            mName = source.readString();
431fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
43286e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian        }
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
43564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
43664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void writeToParcel(Parcel dest, int flags) {
43764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (dest == null) {
43864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("dest must not be null");
43964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
440fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
4417c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            dest.writeString(mName);
4427c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            nativeWriteToParcel(mNativeObject, dest);
4437c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
44464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
44564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            release();
44664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
44764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
4480de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg
44964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
45064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public String toString() {
451fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
452ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            return "Surface(name=" + mName + ")/@0x" +
453ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                    Integer.toHexString(System.identityHashCode(this));
454fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
455fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    }
456fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
45736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private void setNativeObjectLocked(long ptr) {
458fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        if (mNativeObject != ptr) {
459fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            if (mNativeObject == 0 && ptr != 0) {
460fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                mCloseGuard.open("release");
461fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            } else if (mNativeObject != 0 && ptr == 0) {
462fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                mCloseGuard.close();
463fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            }
464fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            mNativeObject = ptr;
465fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            mGenerationId += 1;
466bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (mHwuiContext != null) {
467bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                mHwuiContext.updateSurface();
468bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
469fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
470fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    }
471fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
472fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    private void checkNotReleasedLocked() {
473fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        if (mNativeObject == 0) {
474fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            throw new IllegalStateException("Surface has already been released.");
475fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
47664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
47764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
47864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
4795795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza     * Allocate buffers ahead of time to avoid allocation delays during rendering
4805795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza     * @hide
4815795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza     */
4825795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza    public void allocateBuffers() {
4835795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        synchronized (mLock) {
4845795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza            checkNotReleasedLocked();
4855795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza            nativeAllocateBuffers(mNativeObject);
4865795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        }
4875795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza    }
4885795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza
4895795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza    /**
490a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or
491a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * when a SurfaceTexture could not successfully be allocated.
49264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
493a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin    @SuppressWarnings("serial")
494a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin    public static class OutOfResourcesException extends RuntimeException {
49564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public OutOfResourcesException() {
49664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
49764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public OutOfResourcesException(String name) {
49864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super(name);
49964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
50064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
50164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
50264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
503152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * Returns a human readable representation of a rotation.
504152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     *
505152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * @param rotation The rotation.
506152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * @return The rotation symbolic name.
507545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov     *
508545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov     * @hide
509152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     */
510152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    public static String rotationToString(int rotation) {
511152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        switch (rotation) {
512152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_0: {
513152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROTATION_0";
514152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
515152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_90: {
516152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROATATION_90";
517152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
518152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_180: {
519152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROATATION_180";
520152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
521152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_270: {
522152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROATATION_270";
523152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
524152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            default: {
525152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                throw new IllegalArgumentException("Invalid rotation: " + rotation);
526152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
527152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        }
528152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    }
529152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov
530152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    /**
53164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * A Canvas class that can handle the compatibility mode.
53264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This does two things differently.
53364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <ul>
53464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <li>Returns the width and height of the target metrics, rather than
53564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * native. For example, the canvas returns 320x480 even if an app is running
53664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * in WVGA high density.
53764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <li>Scales the matrix in setMatrix by the application scale, except if
53864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the matrix looks like obtained from getMatrix. This is a hack to handle
53964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the case that an application uses getMatrix to keep the original matrix,
54064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * set matrix of its own, then set the original matrix back. There is no
54164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * perfect solution that works for all cases, and there are a lot of cases
54264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * that this model does not work, but we hope this works for many apps.
54364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * </ul>
54464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
54564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final class CompatibleCanvas extends Canvas {
54664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        // A temp matrix to remember what an application obtained via {@link getMatrix}
54764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        private Matrix mOrigMatrix = null;
54864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
54964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        @Override
55064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public void setMatrix(Matrix matrix) {
55164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) {
55264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                // don't scale the matrix if it's not compatibility mode, or
55364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                // the matrix was obtained from getMatrix.
55464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                super.setMatrix(matrix);
55564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            } else {
55664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Matrix m = new Matrix(mCompatibleMatrix);
55764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                m.preConcat(matrix);
55864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                super.setMatrix(m);
55964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
56064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
56164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
5628b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy        @SuppressWarnings("deprecation")
56364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        @Override
56464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public void getMatrix(Matrix m) {
56564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super.getMatrix(m);
56664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mOrigMatrix == null) {
567ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                mOrigMatrix = new Matrix();
56864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
56964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            mOrigMatrix.set(m);
57064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
57164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
572bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
573bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private final class HwuiContext {
574bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        private final RenderNode mRenderNode;
575bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        private long mHwuiRenderer;
576bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        private HardwareCanvas mCanvas;
577bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
578bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        HwuiContext() {
579bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mRenderNode = RenderNode.create("HwuiCanvas", null);
580bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mRenderNode.setClipToBounds(false);
581bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mHwuiRenderer = nHwuiCreate(mRenderNode.mNativeRenderNode, mNativeObject);
582bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
583bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
584b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck        Canvas lockCanvas(int width, int height) {
585bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (mCanvas != null) {
586bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                throw new IllegalStateException("Surface was already locked!");
587bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
588b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck            mCanvas = mRenderNode.start(width, height);
589bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            return mCanvas;
590bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
591bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
592bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        void unlockAndPost(Canvas canvas) {
593bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (canvas != mCanvas) {
594bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                throw new IllegalArgumentException("canvas object must be the same instance that "
595bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                        + "was previously returned by lockCanvas");
596bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
597bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mRenderNode.end(mCanvas);
598bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mCanvas = null;
599bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            nHwuiDraw(mHwuiRenderer);
600bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
601bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
602bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        void updateSurface() {
603bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            nHwuiSetSurface(mHwuiRenderer, mNativeObject);
604bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
605bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
606bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        void destroy() {
607bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (mHwuiRenderer != 0) {
608bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                nHwuiDestroy(mHwuiRenderer);
609bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                mHwuiRenderer = 0;
610bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
611bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
612bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    }
613bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
614bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private static native long nHwuiCreate(long rootNode, long surface);
615bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private static native void nHwuiSetSurface(long renderer, long surface);
616bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private static native void nHwuiDraw(long renderer);
617bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private static native void nHwuiDestroy(long renderer);
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
619