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;
22a35e5de13cbeb20459b0946828846a18c356e550Robert Carrimport android.graphics.GraphicBuffer;
230b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Matrix;
240b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Rect;
250b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.SurfaceTexture;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
273866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.os.Parcelable;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
29d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye
3067e2ae86396c6d0f989285275cbf908dee5e71f7Aurimas Liutikasimport dalvik.system.CloseGuard;
3167e2ae86396c6d0f989285275cbf908dee5e71f7Aurimas Liutikas
32d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbyeimport java.lang.annotation.Retention;
33d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbyeimport java.lang.annotation.RetentionPolicy;
34d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
36334031cd07c3bd09d23fce0ebaf946fc6ecfee26Glenn Kasten * Handle onto a raw buffer that is being managed by the screen compositor.
37c4faf0cb132a04bff91e4dc8bd83748162258ba1Eino-Ville Talvala *
38c4faf0cb132a04bff91e4dc8bd83748162258ba1Eino-Ville Talvala * <p>A Surface is generally created by or from a consumer of image buffers (such as a
39c4faf0cb132a04bff91e4dc8bd83748162258ba1Eino-Ville Talvala * {@link android.graphics.SurfaceTexture}, {@link android.media.MediaRecorder}, or
40c4faf0cb132a04bff91e4dc8bd83748162258ba1Eino-Ville Talvala * {@link android.renderscript.Allocation}), and is handed to some kind of producer (such as
41c4faf0cb132a04bff91e4dc8bd83748162258ba1Eino-Ville Talvala * {@link android.opengl.EGL14#eglCreateWindowSurface(android.opengl.EGLDisplay,android.opengl.EGLConfig,java.lang.Object,int[],int) OpenGL},
42c4faf0cb132a04bff91e4dc8bd83748162258ba1Eino-Ville Talvala * {@link android.media.MediaPlayer#setSurface MediaPlayer}, or
43c4faf0cb132a04bff91e4dc8bd83748162258ba1Eino-Ville Talvala * {@link android.hardware.camera2.CameraDevice#createCaptureSession CameraDevice}) to draw
44c4faf0cb132a04bff91e4dc8bd83748162258ba1Eino-Ville Talvala * into.</p>
45c4faf0cb132a04bff91e4dc8bd83748162258ba1Eino-Ville Talvala *
46c4faf0cb132a04bff91e4dc8bd83748162258ba1Eino-Ville Talvala * <p><strong>Note:</strong> A Surface acts like a
47c4faf0cb132a04bff91e4dc8bd83748162258ba1Eino-Ville Talvala * {@link java.lang.ref.WeakReference weak reference} to the consumer it is associated with. By
48c4faf0cb132a04bff91e4dc8bd83748162258ba1Eino-Ville Talvala * itself it will not keep its parent consumer from being reclaimed.</p>
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Surface implements Parcelable {
5164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private static final String TAG = "Surface";
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture)
5429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian            throws OutOfResourcesException;
5502949f14151f10f906f1fab58e788fadb98baba8Bryce Lee
5636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeCreateFromSurfaceControl(long surfaceControlNativeObject);
5702949f14151f10f906f1fab58e788fadb98baba8Bryce Lee    private static native long nativeGetFromSurfaceControl(long surfaceControlNativeObject);
5852800617946c456e78ed010c82d0ec4358368164Mathias Agopian
5936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty)
60fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            throws OutOfResourcesException;
6136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeUnlockCanvasAndPost(long nativeObject, Canvas canvas);
6229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
6336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeRelease(long nativeObject);
6436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeIsValid(long nativeObject);
6536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeIsConsumerRunningBehind(long nativeObject);
6636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeReadFromParcel(long nativeObject, Parcel source);
6736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeWriteToParcel(long nativeObject, Parcel dest);
6829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
695795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza    private static native void nativeAllocateBuffers(long nativeObject);
705795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza
71b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck    private static native int nativeGetWidth(long nativeObject);
72b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck    private static native int nativeGetHeight(long nativeObject);
73b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck
7464e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr    private static native long nativeGetNextFrameNumber(long nativeObject);
75cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr    private static native int nativeSetScalingMode(long nativeObject, int scalingMode);
76387838be955a44422509c2c7bc124327e9fe61d7Robert Carr    private static native int nativeForceScopedDisconnect(long nativeObject);
77a35e5de13cbeb20459b0946828846a18c356e550Robert Carr    private static native int nativeAttachAndQueueBuffer(long nativeObject, GraphicBuffer buffer);
7864e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr
790bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    private static native int nativeSetSharedBufferModeEnabled(long nativeObject, boolean enabled);
800bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    private static native int nativeSetAutoRefreshEnabled(long nativeObject, boolean enabled);
810bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy
8264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public static final Parcelable.Creator<Surface> CREATOR =
8364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            new Parcelable.Creator<Surface>() {
84fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        @Override
8564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public Surface createFromParcel(Parcel source) {
8664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            try {
8764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Surface s = new Surface();
8864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                s.readFromParcel(source);
8964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                return s;
9064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            } catch (Exception e) {
9164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Log.e(TAG, "Exception creating surface from parcel", e);
9264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                return null;
9364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
94b85c933d850286874005f97a9764c9b22e49a597Kevin Hester        }
95fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
96fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        @Override
9764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public Surface[] newArray(int size) {
9864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            return new Surface[size];
99df0c84f90894c677c50bdc967a0598f516ac86d7Jamie Gennis        }
10064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    };
101df0c84f90894c677c50bdc967a0598f516ac86d7Jamie Gennis
10264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final CloseGuard mCloseGuard = CloseGuard.get();
103c87c4a3e3b3c3949ae3c6f8fd245b71691d5ca3bMathias Agopian
104fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    // Guarded state.
105fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    final Object mLock = new Object(); // protects the native state
106fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    private String mName;
10736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    long mNativeObject; // package scope only for SurfaceControl access
10836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private long mLockedObject;
109fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    private int mGenerationId; // incremented each time mNativeObject changes
11064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final Canvas mCanvas = new CompatibleCanvas();
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
112240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    // A matrix to scale the matrix set by application. This is set to null for
113240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    // non compatibility mode.
114240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    private Matrix mCompatibleMatrix;
11538ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima
116bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private HwuiContext mHwuiContext;
117bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
118aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos    private boolean mIsSingleBuffered;
1190bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    private boolean mIsSharedBufferModeEnabled;
1200bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    private boolean mIsAutoRefreshEnabled;
121aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos
122d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    /** @hide */
123cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr    @Retention(RetentionPolicy.SOURCE)
124ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey    @IntDef(prefix = { "SCALING_MODE_" }, value = {
125ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            SCALING_MODE_FREEZE,
126ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            SCALING_MODE_SCALE_TO_WINDOW,
127ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            SCALING_MODE_SCALE_CROP,
128ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            SCALING_MODE_NO_SCALE_CROP
129ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey    })
130cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr    public @interface ScalingMode {}
131cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr    // From system/window.h
132cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr    /** @hide */
1331ca6a33f36357281b3445e85d9e67cacd1a12edeRobert Carr    public static final int SCALING_MODE_FREEZE = 0;
134cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr    /** @hide */
1351ca6a33f36357281b3445e85d9e67cacd1a12edeRobert Carr    public static final int SCALING_MODE_SCALE_TO_WINDOW = 1;
136cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr    /** @hide */
1371ca6a33f36357281b3445e85d9e67cacd1a12edeRobert Carr    public static final int SCALING_MODE_SCALE_CROP = 2;
138cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr    /** @hide */
1391ca6a33f36357281b3445e85d9e67cacd1a12edeRobert Carr    public static final int SCALING_MODE_NO_SCALE_CROP = 3;
140cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr
141cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr    /** @hide */
142ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey    @IntDef(prefix = { "ROTATION_" }, value = {
143ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            ROTATION_0,
144ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            ROTATION_90,
145ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            ROTATION_180,
146ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey            ROTATION_270
147ce8db9911494225fcd99711d7df85a130de5a6ceJeff Sharkey    })
148d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    @Retention(RetentionPolicy.SOURCE)
149d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    public @interface Rotation {}
150d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye
15164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
15229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 0 degree rotation (natural orientation)
15329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
15429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_0 = 0;
15529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
15629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
15729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 90 degree rotation.
15829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
15929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_90 = 1;
16029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
16129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
16229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 180 degree rotation.
16329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
16429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_180 = 2;
16529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
16629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
16729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 270 degree rotation.
16829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
16929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_270 = 3;
17029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
17129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
17264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Create an empty surface, which will later be filled in by readFromParcel().
17364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public Surface() {
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Create Surface from a {@link SurfaceTexture}.
18064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
18164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Images drawn to the Surface will be made available to the {@link
18264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link
18364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * SurfaceTexture#updateTexImage}.
18464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
185ec99efa03bfee9b2cc898191655983fda20e0ca4Eino-Ville Talvala     * Please note that holding onto the Surface created here is not enough to
186ec99efa03bfee9b2cc898191655983fda20e0ca4Eino-Ville Talvala     * keep the provided SurfaceTexture from being reclaimed.  In that sense,
187ec99efa03bfee9b2cc898191655983fda20e0ca4Eino-Ville Talvala     * the Surface will act like a
188ec99efa03bfee9b2cc898191655983fda20e0ca4Eino-Ville Talvala     * {@link java.lang.ref.WeakReference weak reference} to the SurfaceTexture.
189ec99efa03bfee9b2cc898191655983fda20e0ca4Eino-Ville Talvala     *
19064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @param surfaceTexture The {@link SurfaceTexture} that is updated by this
19164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Surface.
192a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * @throws OutOfResourcesException if the surface could not be created.
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public Surface(SurfaceTexture surfaceTexture) {
19564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (surfaceTexture == null) {
19664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("surfaceTexture must not be null");
19764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
198aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos        mIsSingleBuffered = surfaceTexture.isSingleBuffered();
199fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
200fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            mName = surfaceTexture.toString();
201a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin            setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
202f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian        }
203240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    }
204240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
20586e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian    /* called from android_view_Surface_createFromIGraphicBufferProducer() */
20636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private Surface(long nativeObject) {
207fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
208fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            setNativeObjectLocked(nativeObject);
209fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
2103866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    }
2113866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian
21264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
21364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    protected void finalize() throws Throwable {
21464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        try {
21564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mCloseGuard != null) {
21664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                mCloseGuard.warnIfOpen();
21764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
21886e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian            release();
21964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        } finally {
22064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super.finalize();
22164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
222b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    }
223b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian
224240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    /**
22564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Release the local reference to the server-side surface.
22664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Always call release() when you're done with a Surface.
22764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This will make the surface invalid.
22864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
22964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void release() {
230fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
2317c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            if (mNativeObject != 0) {
2327c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian                nativeRelease(mNativeObject);
233fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                setNativeObjectLocked(0);
2347c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            }
235bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (mHwuiContext != null) {
236bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                mHwuiContext.destroy();
237bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                mHwuiContext = null;
238bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
2393866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        }
24064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
24164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
24264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
24364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Free all server-side state associated with this surface and
24464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * release this object's reference.  This method can only be
24564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * called from the process that created the service.
246b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * @hide
247b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     */
24864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void destroy() {
24986e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian        release();
25064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
25161566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn
25261566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn    /**
25341c25cee06abec189ba60b9b76454867c2d64cfdLucas Dupin     * Destroys the HwuiContext without completely
25441c25cee06abec189ba60b9b76454867c2d64cfdLucas Dupin     * releasing the Surface.
25541c25cee06abec189ba60b9b76454867c2d64cfdLucas Dupin     * @hide
25641c25cee06abec189ba60b9b76454867c2d64cfdLucas Dupin     */
25741c25cee06abec189ba60b9b76454867c2d64cfdLucas Dupin    public void hwuiDestroy() {
25841c25cee06abec189ba60b9b76454867c2d64cfdLucas Dupin        if (mHwuiContext != null) {
25941c25cee06abec189ba60b9b76454867c2d64cfdLucas Dupin            mHwuiContext.destroy();
26041c25cee06abec189ba60b9b76454867c2d64cfdLucas Dupin            mHwuiContext = null;
26141c25cee06abec189ba60b9b76454867c2d64cfdLucas Dupin        }
26241c25cee06abec189ba60b9b76454867c2d64cfdLucas Dupin    }
26341c25cee06abec189ba60b9b76454867c2d64cfdLucas Dupin
26441c25cee06abec189ba60b9b76454867c2d64cfdLucas Dupin    /**
26564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Returns true if this object holds a valid surface.
26664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
26764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return True if it holds a physical surface, so lockCanvas() will succeed.
26864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Otherwise returns false.
26961566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn     */
27064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public boolean isValid() {
271fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
2727c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            if (mNativeObject == 0) return false;
2737c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            return nativeIsValid(mNativeObject);
2747c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
27564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
27661566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn
27764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
27864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Gets the generation number of this surface, incremented each time
27964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the native surface contained within this object changes.
28064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
28164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return The current generation number.
28264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
28364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
284b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    public int getGenerationId() {
285fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
286fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            return mGenerationId;
287fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
288b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    }
289b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian
290c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian    /**
29164e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr     * Returns the next frame number which will be dequeued for rendering.
29264e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr     * Intended for use with SurfaceFlinger's deferred transactions API.
29364e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr     *
29464e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr     * @hide
29564e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr     */
29664e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr    public long getNextFrameNumber() {
29764e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr        synchronized (mLock) {
298388090fbdd1f38dedf49b12dac425a0807215a02Jorim Jaggi            checkNotReleasedLocked();
29964e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr            return nativeGetNextFrameNumber(mNativeObject);
30064e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr        }
30164e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr    }
30264e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr
30364e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr    /**
30464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Returns true if the consumer of this Surface is running behind the producer.
30564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
30664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return True if the consumer is more than one buffer ahead of the producer.
307c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian     * @hide
308c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian     */
30964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public boolean isConsumerRunningBehind() {
310fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
3117c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            checkNotReleasedLocked();
3127c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            return nativeIsConsumerRunningBehind(mNativeObject);
3137c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
31464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
315c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian
316b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    /**
31764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Gets a {@link Canvas} for drawing into this surface.
31864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
3199ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian     * After drawing into the provided {@link Canvas}, the caller must
32064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
32164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
32230d7ab9a10fcde397bae7bed5f16d1094fded8b2Mathias Agopian     * @param inOutDirty A rectangle that represents the dirty region that the caller wants
32364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * to redraw.  This function may choose to expand the dirty rectangle if for example
32464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the surface has been resized or if the previous contents of the surface were
3259ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian     * not available.  The caller must redraw the entire dirty region as represented
3269ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian     * by the contents of the inOutDirty rectangle upon return from this function.
32764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * The caller may also pass <code>null</code> instead, in the case where the
32864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * entire surface should be redrawn.
32964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return A canvas for drawing into the surface.
330a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     *
331a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * @throws IllegalArgumentException If the inOutDirty rectangle is not valid.
332a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * @throws OutOfResourcesException If the canvas cannot be locked.
333240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima     */
3343866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    public Canvas lockCanvas(Rect inOutDirty)
335a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin            throws Surface.OutOfResourcesException, IllegalArgumentException {
336fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
3377c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            checkNotReleasedLocked();
338ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            if (mLockedObject != 0) {
339ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                // Ideally, nativeLockCanvas() would throw in this situation and prevent the
340ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                // double-lock, but that won't happen if mNativeObject was updated.  We can't
341ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                // abandon the old mLockedObject because it might still be in use, so instead
342ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                // we just refuse to re-lock the Surface.
343d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall                throw new IllegalArgumentException("Surface was already locked");
344ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            }
345ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
346fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            return mCanvas;
3477c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
34864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
349240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
35064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
35164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Posts the new contents of the {@link Canvas} to the surface and
35264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * releases the {@link Canvas}.
35364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
35464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @param canvas The canvas previously obtained from {@link #lockCanvas}.
35564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
35664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void unlockCanvasAndPost(Canvas canvas) {
357bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        synchronized (mLock) {
358bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            checkNotReleasedLocked();
359bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
360bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (mHwuiContext != null) {
361bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                mHwuiContext.unlockAndPost(canvas);
362bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            } else {
363bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                unlockSwCanvasAndPost(canvas);
364bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
365bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
366bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    }
367bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
368bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private void unlockSwCanvasAndPost(Canvas canvas) {
369fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        if (canvas != mCanvas) {
370fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            throw new IllegalArgumentException("canvas object must be the same instance that "
371fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                    + "was previously returned by lockCanvas");
372fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
373bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        if (mNativeObject != mLockedObject) {
374bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            Log.w(TAG, "WARNING: Surface's mNativeObject (0x" +
375bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                    Long.toHexString(mNativeObject) + ") != mLockedObject (0x" +
376bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                    Long.toHexString(mLockedObject) +")");
377bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
378bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        if (mLockedObject == 0) {
379bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            throw new IllegalStateException("Surface was not locked");
380bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
381bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        try {
382bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            nativeUnlockCanvasAndPost(mLockedObject, canvas);
383bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        } finally {
384bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            nativeRelease(mLockedObject);
385bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mLockedObject = 0;
386bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
387bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    }
388fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
389bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    /**
390bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * Gets a {@link Canvas} for drawing into this surface.
391bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     *
392bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * After drawing into the provided {@link Canvas}, the caller must
393bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
394bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     *
395bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * Unlike {@link #lockCanvas(Rect)} this will return a hardware-accelerated
396bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * canvas. See the <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#unsupported">
397bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * unsupported drawing operations</a> for a list of what is and isn't
39843a5328c8377aa29acd51098d915503e87f13a9aJohn Reck     * supported in a hardware-accelerated canvas. It is also required to
39943a5328c8377aa29acd51098d915503e87f13a9aJohn Reck     * fully cover the surface every time {@link #lockHardwareCanvas()} is
40043a5328c8377aa29acd51098d915503e87f13a9aJohn Reck     * called as the buffer is not preserved between frames. Partial updates
40143a5328c8377aa29acd51098d915503e87f13a9aJohn Reck     * are not supported.
402bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     *
403bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * @return A canvas for drawing into the surface.
404bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     *
405bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     * @throws IllegalStateException If the canvas cannot be locked.
406bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck     */
407bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    public Canvas lockHardwareCanvas() {
408fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
4097c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            checkNotReleasedLocked();
410bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (mHwuiContext == null) {
411d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin                mHwuiContext = new HwuiContext(false);
412d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin            }
413d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin            return mHwuiContext.lockCanvas(
414d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin                    nativeGetWidth(mNativeObject),
415d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin                    nativeGetHeight(mNativeObject));
416d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin        }
417d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin    }
418d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin
419d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin    /**
420d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * Gets a {@link Canvas} for drawing into this surface that supports wide color gamut.
421d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     *
422d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * After drawing into the provided {@link Canvas}, the caller must
423d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
424d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     *
425d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * Unlike {@link #lockCanvas(Rect)} and {@link #lockHardwareCanvas()},
426d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * this will return a hardware-accelerated canvas that supports wide color gamut.
427d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * See the <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#unsupported">
428d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * unsupported drawing operations</a> for a list of what is and isn't
429d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * supported in a hardware-accelerated canvas. It is also required to
430d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * fully cover the surface every time {@link #lockHardwareCanvas()} is
431d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * called as the buffer is not preserved between frames. Partial updates
432d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * are not supported.
433d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     *
434d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * @return A canvas for drawing into the surface.
435d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     *
436d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * @throws IllegalStateException If the canvas cannot be locked.
437d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     *
438d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     * @hide
439d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin     */
440d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin    public Canvas lockHardwareWideColorGamutCanvas() {
441d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin        synchronized (mLock) {
442d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin            checkNotReleasedLocked();
443d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin            if (mHwuiContext != null && !mHwuiContext.isWideColorGamut()) {
444d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin                mHwuiContext.destroy();
445d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin                mHwuiContext = null;
446d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin            }
447d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin            if (mHwuiContext == null) {
448d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin                mHwuiContext = new HwuiContext(true);
449d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall            }
450b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck            return mHwuiContext.lockCanvas(
451b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck                    nativeGetWidth(mNativeObject),
452b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck                    nativeGetHeight(mNativeObject));
4537c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
45464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
455240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
456ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden    /**
45764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @deprecated This API has been removed and is not supported.  Do not use.
45864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
45964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Deprecated
46064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void unlockCanvas(Canvas canvas) {
46164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        throw new UnsupportedOperationException();
462d10cd5765a2b706fc174f16b951d6b0a5d3740d3Romain Guy    }
46338ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima
46438ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima    /**
465b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * Sets the translator used to scale canvas's width/height in compatibility
466b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * mode.
46738ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima     */
4685be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn    void setCompatibilityTranslator(Translator translator) {
469240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima        if (translator != null) {
470240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            float appScale = translator.applicationScale;
471240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            mCompatibleMatrix = new Matrix();
472240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            mCompatibleMatrix.setScale(appScale, appScale);
473240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima        }
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
47764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Copy another surface to this one.  This surface now holds a reference
47864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * to the same data as the original surface, and is -not- the owner.
47964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This is for use by the window manager when returning a window surface
48064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * back from a client, converting it from the representation being managed
48164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * by the window manager to the representation the client uses to draw
48264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * in to it.
48302949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     *
48402949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     * @param other {@link SurfaceControl} to copy from.
48502949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     *
48664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
48764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
4883866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    public void copyFrom(SurfaceControl other) {
48964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other == null) {
49064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("other must not be null");
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
492fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
49336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        long surfaceControlPtr = other.mNativeObject;
494fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        if (surfaceControlPtr == 0) {
4953866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            throw new NullPointerException(
49602949f14151f10f906f1fab58e788fadb98baba8Bryce Lee                    "null SurfaceControl native object. Are you using a released SurfaceControl?");
49702949f14151f10f906f1fab58e788fadb98baba8Bryce Lee        }
49802949f14151f10f906f1fab58e788fadb98baba8Bryce Lee        long newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr);
49902949f14151f10f906f1fab58e788fadb98baba8Bryce Lee
50002949f14151f10f906f1fab58e788fadb98baba8Bryce Lee        synchronized (mLock) {
50102949f14151f10f906f1fab58e788fadb98baba8Bryce Lee            if (mNativeObject != 0) {
50202949f14151f10f906f1fab58e788fadb98baba8Bryce Lee                nativeRelease(mNativeObject);
50302949f14151f10f906f1fab58e788fadb98baba8Bryce Lee            }
50402949f14151f10f906f1fab58e788fadb98baba8Bryce Lee            setNativeObjectLocked(newNativeObject);
50502949f14151f10f906f1fab58e788fadb98baba8Bryce Lee        }
50602949f14151f10f906f1fab58e788fadb98baba8Bryce Lee    }
50702949f14151f10f906f1fab58e788fadb98baba8Bryce Lee
50802949f14151f10f906f1fab58e788fadb98baba8Bryce Lee    /**
50902949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     * Gets a reference a surface created from this one.  This surface now holds a reference
51002949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     * to the same data as the original surface, and is -not- the owner.
51102949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     * This is for use by the window manager when returning a window surface
51202949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     * back from a client, converting it from the representation being managed
51302949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     * by the window manager to the representation the client uses to draw
51402949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     * in to it.
51502949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     *
51602949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     * @param other {@link SurfaceControl} to create surface from.
51702949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     *
51802949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     * @hide
51902949f14151f10f906f1fab58e788fadb98baba8Bryce Lee     */
52002949f14151f10f906f1fab58e788fadb98baba8Bryce Lee    public void createFrom(SurfaceControl other) {
52102949f14151f10f906f1fab58e788fadb98baba8Bryce Lee        if (other == null) {
52202949f14151f10f906f1fab58e788fadb98baba8Bryce Lee            throw new IllegalArgumentException("other must not be null");
52302949f14151f10f906f1fab58e788fadb98baba8Bryce Lee        }
52402949f14151f10f906f1fab58e788fadb98baba8Bryce Lee
52502949f14151f10f906f1fab58e788fadb98baba8Bryce Lee        long surfaceControlPtr = other.mNativeObject;
52602949f14151f10f906f1fab58e788fadb98baba8Bryce Lee        if (surfaceControlPtr == 0) {
52702949f14151f10f906f1fab58e788fadb98baba8Bryce Lee            throw new NullPointerException(
52802949f14151f10f906f1fab58e788fadb98baba8Bryce Lee                    "null SurfaceControl native object. Are you using a released SurfaceControl?");
52964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
53036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
531fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
532fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
533fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            if (mNativeObject != 0) {
534fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                nativeRelease(mNativeObject);
5357c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            }
536fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            setNativeObjectLocked(newNativeObject);
53786e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian        }
53864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
53964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
54064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
541fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown     * This is intended to be used by {@link SurfaceView#updateWindow} only.
5427c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian     * @param other access is not thread safe
5437c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian     * @hide
5447c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian     * @deprecated
54564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
5467c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian    @Deprecated
54764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void transferFrom(Surface other) {
54864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other == null) {
54964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("other must not be null");
55064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
55164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other != this) {
55236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat            final long newPtr;
553fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            synchronized (other.mLock) {
554fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                newPtr = other.mNativeObject;
555fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                other.setNativeObjectLocked(0);
556fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            }
557fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
558fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            synchronized (mLock) {
5597c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian                if (mNativeObject != 0) {
5607c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian                    nativeRelease(mNativeObject);
5617c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian                }
562fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                setNativeObjectLocked(newPtr);
5633866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            }
56464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
56564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
56864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public int describeContents() {
56964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return 0;
57064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
57164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
57264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void readFromParcel(Parcel source) {
57364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (source == null) {
57464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("source must not be null");
575f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian        }
576fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
577fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
578ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            // nativeReadFromParcel() will either return mNativeObject, or
579ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            // create a new native Surface and return it after reducing
580ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            // the reference count on mNativeObject.  Either way, it is
581ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            // not necessary to call nativeRelease() here.
582f005f5ed88aa67bed6c678a7e89b47e3ec436835Eino-Ville Talvala            // NOTE: This must be kept synchronized with the native parceling code
583f005f5ed88aa67bed6c678a7e89b47e3ec436835Eino-Ville Talvala            // in frameworks/native/libs/Surface.cpp
5847c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            mName = source.readString();
585aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos            mIsSingleBuffered = source.readInt() != 0;
586fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
58786e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian        }
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
59064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
59164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void writeToParcel(Parcel dest, int flags) {
59264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (dest == null) {
59364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("dest must not be null");
59464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
595fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
596f005f5ed88aa67bed6c678a7e89b47e3ec436835Eino-Ville Talvala            // NOTE: This must be kept synchronized with the native parceling code
597f005f5ed88aa67bed6c678a7e89b47e3ec436835Eino-Ville Talvala            // in frameworks/native/libs/Surface.cpp
5987c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            dest.writeString(mName);
599aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos            dest.writeInt(mIsSingleBuffered ? 1 : 0);
6007c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            nativeWriteToParcel(mNativeObject, dest);
6017c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
60264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
60364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            release();
60464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
60564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
6060de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg
60764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
60864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public String toString() {
609fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
610ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            return "Surface(name=" + mName + ")/@0x" +
611ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                    Integer.toHexString(System.identityHashCode(this));
612fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
613fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    }
614fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
61536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private void setNativeObjectLocked(long ptr) {
616fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        if (mNativeObject != ptr) {
617fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            if (mNativeObject == 0 && ptr != 0) {
618fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                mCloseGuard.open("release");
619fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            } else if (mNativeObject != 0 && ptr == 0) {
620fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                mCloseGuard.close();
621fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            }
622fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            mNativeObject = ptr;
623fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            mGenerationId += 1;
624bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (mHwuiContext != null) {
625bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                mHwuiContext.updateSurface();
626bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
627fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
628fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    }
629fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
630fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    private void checkNotReleasedLocked() {
631fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        if (mNativeObject == 0) {
632fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            throw new IllegalStateException("Surface has already been released.");
633fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
63464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
63564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
63664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
6375795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza     * Allocate buffers ahead of time to avoid allocation delays during rendering
6385795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza     * @hide
6395795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza     */
6405795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza    public void allocateBuffers() {
6415795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        synchronized (mLock) {
6425795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza            checkNotReleasedLocked();
6435795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza            nativeAllocateBuffers(mNativeObject);
6445795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        }
6455795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza    }
6465795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza
6475795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza    /**
648cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr     * Set the scaling mode to be used for this surfaces buffers
649cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr     * @hide
650cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr     */
651cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr    void setScalingMode(@ScalingMode int scalingMode) {
652cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr        synchronized (mLock) {
653cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr            checkNotReleasedLocked();
654cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr            int err = nativeSetScalingMode(mNativeObject, scalingMode);
655cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr            if (err != 0) {
656cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr                throw new IllegalArgumentException("Invalid scaling mode: " + scalingMode);
657cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr            }
658cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr        }
659cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr    }
660cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr
661387838be955a44422509c2c7bc124327e9fe61d7Robert Carr    void forceScopedDisconnect() {
662387838be955a44422509c2c7bc124327e9fe61d7Robert Carr        synchronized (mLock) {
663387838be955a44422509c2c7bc124327e9fe61d7Robert Carr            checkNotReleasedLocked();
664387838be955a44422509c2c7bc124327e9fe61d7Robert Carr            int err = nativeForceScopedDisconnect(mNativeObject);
665387838be955a44422509c2c7bc124327e9fe61d7Robert Carr            if (err != 0) {
666387838be955a44422509c2c7bc124327e9fe61d7Robert Carr                throw new RuntimeException("Failed to disconnect Surface instance (bad object?)");
667387838be955a44422509c2c7bc124327e9fe61d7Robert Carr            }
668387838be955a44422509c2c7bc124327e9fe61d7Robert Carr        }
669387838be955a44422509c2c7bc124327e9fe61d7Robert Carr    }
670387838be955a44422509c2c7bc124327e9fe61d7Robert Carr
671cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr    /**
672a35e5de13cbeb20459b0946828846a18c356e550Robert Carr     * Transfer ownership of buffer and present it on the Surface.
673a35e5de13cbeb20459b0946828846a18c356e550Robert Carr     * @hide
674a35e5de13cbeb20459b0946828846a18c356e550Robert Carr     */
675a35e5de13cbeb20459b0946828846a18c356e550Robert Carr    public void attachAndQueueBuffer(GraphicBuffer buffer) {
676a35e5de13cbeb20459b0946828846a18c356e550Robert Carr        synchronized (mLock) {
677a35e5de13cbeb20459b0946828846a18c356e550Robert Carr            checkNotReleasedLocked();
678a35e5de13cbeb20459b0946828846a18c356e550Robert Carr            int err = nativeAttachAndQueueBuffer(mNativeObject, buffer);
679a35e5de13cbeb20459b0946828846a18c356e550Robert Carr            if (err != 0) {
680a35e5de13cbeb20459b0946828846a18c356e550Robert Carr                throw new RuntimeException(
681a35e5de13cbeb20459b0946828846a18c356e550Robert Carr                        "Failed to attach and queue buffer to Surface (bad object?)");
682a35e5de13cbeb20459b0946828846a18c356e550Robert Carr            }
683a35e5de13cbeb20459b0946828846a18c356e550Robert Carr        }
684a35e5de13cbeb20459b0946828846a18c356e550Robert Carr    }
685a35e5de13cbeb20459b0946828846a18c356e550Robert Carr
686a35e5de13cbeb20459b0946828846a18c356e550Robert Carr    /**
687aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos     * Returns whether or not this Surface is backed by a single-buffered SurfaceTexture
688aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos     * @hide
689aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos     */
690aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos    public boolean isSingleBuffered() {
691aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos        return mIsSingleBuffered;
692aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos    }
693aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos
694aff2f949395725f4bb82802bd12201b65d514e68Pablo Ceballos    /**
6950bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * <p>The shared buffer mode allows both the application and the surface compositor
6960bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * (SurfaceFlinger) to concurrently access this surface's buffer. While the
6970bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * application is still required to issue a present request
6980bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * (see {@link #unlockCanvasAndPost(Canvas)}) to the compositor when an update is required,
6990bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * the compositor may trigger an update at any time. Since the surface's buffer is shared
7000bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * between the application and the compositor, updates triggered by the compositor may
7010bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * cause visible tearing.</p>
7020bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     *
7030bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * <p>The shared buffer mode can be used with
7040bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * {@link #setAutoRefreshEnabled(boolean) auto-refresh} to avoid the overhead of
7050bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * issuing present requests.</p>
7060bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     *
7070bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * <p>If the application uses the shared buffer mode to reduce latency, it is
7080bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * recommended to use software rendering (see {@link #lockCanvas(Rect)} to ensure
7090bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * the graphics workloads are not affected by other applications and/or the system
7100bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * using the GPU. When using software rendering, the application should update the
7110bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * smallest possible region of the surface required.</p>
7120bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     *
7130bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * <p class="note">The shared buffer mode might not be supported by the underlying
7140bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * hardware. Enabling shared buffer mode on hardware that does not support it will
7150bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * not yield an error but the application will not benefit from lower latency (and
7160bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * tearing will not be visible).</p>
7170bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     *
7180bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * <p class="note">Depending on how many and what kind of surfaces are visible, the
7190bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * surface compositor may need to copy the shared buffer before it is displayed. When
7200bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * this happens, the latency benefits of shared buffer mode will be reduced.</p>
7210bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     *
7220bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * @param enabled True to enable the shared buffer mode on this surface, false otherwise
7230bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     *
7240bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * @see #isSharedBufferModeEnabled()
7250bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * @see #setAutoRefreshEnabled(boolean)
726010f0824900bb110a3c6763b538191125577fad8Romain Guy     *
727010f0824900bb110a3c6763b538191125577fad8Romain Guy     * @hide
7280bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     */
7290bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    public void setSharedBufferModeEnabled(boolean enabled) {
7300bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy        if (mIsSharedBufferModeEnabled != enabled) {
7310bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy            int error = nativeSetSharedBufferModeEnabled(mNativeObject, enabled);
7320bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy            if (error != 0) {
7330bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy                throw new RuntimeException(
7340bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy                        "Failed to set shared buffer mode on Surface (bad object?)");
7350bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy            } else {
7360bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy                mIsSharedBufferModeEnabled = enabled;
7370bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy            }
7380bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy        }
7390bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    }
7400bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy
7410bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    /**
7420bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * @return True if shared buffer mode is enabled on this surface, false otherwise
7430bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     *
7440bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * @see #setSharedBufferModeEnabled(boolean)
745010f0824900bb110a3c6763b538191125577fad8Romain Guy     *
746010f0824900bb110a3c6763b538191125577fad8Romain Guy     * @hide
7470bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     */
7480bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    public boolean isSharedBufferModeEnabled() {
7490bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy        return mIsSharedBufferModeEnabled;
7500bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    }
7510bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy
7520bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    /**
7530bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * <p>When auto-refresh is enabled, the surface compositor (SurfaceFlinger)
7540bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * automatically updates the display on a regular refresh cycle. The application
7550bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * can continue to issue present requests but it is not required. Enabling
7560bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * auto-refresh may result in visible tearing.</p>
7570bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     *
7580bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * <p>Auto-refresh has no effect if the {@link #setSharedBufferModeEnabled(boolean)
7590bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * shared buffer mode} is not enabled.</p>
7600bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     *
7610bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * <p>Because auto-refresh will trigger continuous updates of the display, it is
7620bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * recommended to turn it on only when necessary. For example, in a drawing/painting
7630bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * application auto-refresh should be enabled on finger/pen down and disabled on
7640bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * finger/pen up.</p>
7650bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     *
7660bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * @param enabled True to enable auto-refresh on this surface, false otherwise
7670bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     *
7680bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * @see #isAutoRefreshEnabled()
7690bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * @see #setSharedBufferModeEnabled(boolean)
770010f0824900bb110a3c6763b538191125577fad8Romain Guy     *
771010f0824900bb110a3c6763b538191125577fad8Romain Guy     * @hide
7720bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     */
7730bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    public void setAutoRefreshEnabled(boolean enabled) {
7740bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy        if (mIsAutoRefreshEnabled != enabled) {
7750bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy            int error = nativeSetAutoRefreshEnabled(mNativeObject, enabled);
7760bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy            if (error != 0) {
7770bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy                throw new RuntimeException("Failed to set auto refresh on Surface (bad object?)");
7780bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy            } else {
7790bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy                mIsAutoRefreshEnabled = enabled;
7800bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy            }
7810bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy        }
7820bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    }
7830bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy
7840bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    /**
7850bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     * @return True if auto-refresh is enabled on this surface, false otherwise
786010f0824900bb110a3c6763b538191125577fad8Romain Guy     *
787010f0824900bb110a3c6763b538191125577fad8Romain Guy     * @hide
7880bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy     */
7890bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    public boolean isAutoRefreshEnabled() {
7900bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy        return mIsAutoRefreshEnabled;
7910bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    }
7920bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy
7930bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy    /**
794a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or
795a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * when a SurfaceTexture could not successfully be allocated.
79664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
797a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin    @SuppressWarnings("serial")
798a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin    public static class OutOfResourcesException extends RuntimeException {
79964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public OutOfResourcesException() {
80064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
80164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public OutOfResourcesException(String name) {
80264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super(name);
80364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
80464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
80564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
80664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
807152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * Returns a human readable representation of a rotation.
808152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     *
809152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * @param rotation The rotation.
810152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * @return The rotation symbolic name.
811545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov     *
812545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov     * @hide
813152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     */
814152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    public static String rotationToString(int rotation) {
815152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        switch (rotation) {
816152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_0: {
817152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROTATION_0";
818152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
819152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_90: {
8200bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy                return "ROTATION_90";
821152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
822152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_180: {
8230bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy                return "ROTATION_180";
824152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
825152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_270: {
8260bbf0b41cc091cbf7348b0a1bb5335cbd5312923Romain Guy                return "ROTATION_270";
827152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
828152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            default: {
8291985976b6672f2c858b0dc46ca8e43c65cde388bMichael Wright                return Integer.toString(rotation);
830152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
831152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        }
832152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    }
833152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov
834152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    /**
83564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * A Canvas class that can handle the compatibility mode.
83664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This does two things differently.
83764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <ul>
83864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <li>Returns the width and height of the target metrics, rather than
83964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * native. For example, the canvas returns 320x480 even if an app is running
84064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * in WVGA high density.
84164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <li>Scales the matrix in setMatrix by the application scale, except if
84264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the matrix looks like obtained from getMatrix. This is a hack to handle
84364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the case that an application uses getMatrix to keep the original matrix,
84464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * set matrix of its own, then set the original matrix back. There is no
84564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * perfect solution that works for all cases, and there are a lot of cases
84664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * that this model does not work, but we hope this works for many apps.
84764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * </ul>
84864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
84964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final class CompatibleCanvas extends Canvas {
85064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        // A temp matrix to remember what an application obtained via {@link getMatrix}
85164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        private Matrix mOrigMatrix = null;
85264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
85364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        @Override
85464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public void setMatrix(Matrix matrix) {
85564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) {
85664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                // don't scale the matrix if it's not compatibility mode, or
85764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                // the matrix was obtained from getMatrix.
85864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                super.setMatrix(matrix);
85964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            } else {
86064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Matrix m = new Matrix(mCompatibleMatrix);
86164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                m.preConcat(matrix);
86264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                super.setMatrix(m);
86364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
86464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
86564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
8668b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy        @SuppressWarnings("deprecation")
86764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        @Override
86864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public void getMatrix(Matrix m) {
86964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super.getMatrix(m);
87064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mOrigMatrix == null) {
871ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                mOrigMatrix = new Matrix();
87264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
87364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            mOrigMatrix.set(m);
87464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
87564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
876bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
877bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private final class HwuiContext {
878bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        private final RenderNode mRenderNode;
879bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        private long mHwuiRenderer;
880f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik        private DisplayListCanvas mCanvas;
881d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin        private final boolean mIsWideColorGamut;
882bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
883d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin        HwuiContext(boolean isWideColorGamut) {
884bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mRenderNode = RenderNode.create("HwuiCanvas", null);
885bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mRenderNode.setClipToBounds(false);
886d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin            mIsWideColorGamut = isWideColorGamut;
887d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin            mHwuiRenderer = nHwuiCreate(mRenderNode.mNativeRenderNode, mNativeObject,
888d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin                    isWideColorGamut);
889bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
890bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
891b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck        Canvas lockCanvas(int width, int height) {
892bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (mCanvas != null) {
893bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                throw new IllegalStateException("Surface was already locked!");
894bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
895b35c9602cf5c628c621e4fe102a461505f302bfeJohn Reck            mCanvas = mRenderNode.start(width, height);
896bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            return mCanvas;
897bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
898bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
899bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        void unlockAndPost(Canvas canvas) {
900bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (canvas != mCanvas) {
901bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                throw new IllegalArgumentException("canvas object must be the same instance that "
902bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                        + "was previously returned by lockCanvas");
903bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
904bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mRenderNode.end(mCanvas);
905bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mCanvas = null;
906bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            nHwuiDraw(mHwuiRenderer);
907bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
908bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
909bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        void updateSurface() {
910bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            nHwuiSetSurface(mHwuiRenderer, mNativeObject);
911bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
912bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
913bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        void destroy() {
914bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            if (mHwuiRenderer != 0) {
915bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                nHwuiDestroy(mHwuiRenderer);
916bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                mHwuiRenderer = 0;
917bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
918bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
919d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin
920d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin        boolean isWideColorGamut() {
921d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin            return mIsWideColorGamut;
922d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin        }
923bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    }
924bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
925d8b68717400487a3dd20d1cc7c11f6e1ee6d3fd9Peiyong Lin    private static native long nHwuiCreate(long rootNode, long surface, boolean isWideColorGamut);
926bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private static native void nHwuiSetSurface(long renderer, long surface);
927bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private static native void nHwuiDraw(long renderer);
928bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private static native void nHwuiDestroy(long renderer);
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
930