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