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