Surface.java revision d7e559675c96071b6ee46c3b45aa3c9e7216a9c4
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 5664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public static final Parcelable.Creator<Surface> CREATOR = 5764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown new Parcelable.Creator<Surface>() { 58fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown @Override 5964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public Surface createFromParcel(Parcel source) { 6064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown try { 6164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown Surface s = new Surface(); 6264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown s.readFromParcel(source); 6364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown return s; 6464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } catch (Exception e) { 6564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown Log.e(TAG, "Exception creating surface from parcel", e); 6664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown return null; 6764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 68b85c933d850286874005f97a9764c9b22e49a597Kevin Hester } 69fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown 70fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown @Override 7164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public Surface[] newArray(int size) { 7264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown return new Surface[size]; 73df0c84f90894c677c50bdc967a0598f516ac86d7Jamie Gennis } 7464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown }; 75df0c84f90894c677c50bdc967a0598f516ac86d7Jamie Gennis 7664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown private final CloseGuard mCloseGuard = CloseGuard.get(); 77c87c4a3e3b3c3949ae3c6f8fd245b71691d5ca3bMathias Agopian 78fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown // Guarded state. 79fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown final Object mLock = new Object(); // protects the native state 80fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown private String mName; 8136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat long mNativeObject; // package scope only for SurfaceControl access 8236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat private long mLockedObject; 83fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown private int mGenerationId; // incremented each time mNativeObject changes 8464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown private final Canvas mCanvas = new CompatibleCanvas(); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 86240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima // A matrix to scale the matrix set by application. This is set to null for 87240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima // non compatibility mode. 88240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima private Matrix mCompatibleMatrix; 8938ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima 90d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye /** @hide */ 91d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270}) 92d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye @Retention(RetentionPolicy.SOURCE) 93d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye public @interface Rotation {} 94d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye 9564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown /** 9629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian * Rotation constant: 0 degree rotation (natural orientation) 9729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian */ 9829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian public static final int ROTATION_0 = 0; 9929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian 10029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian /** 10129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian * Rotation constant: 90 degree rotation. 10229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian */ 10329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian public static final int ROTATION_90 = 1; 10429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian 10529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian /** 10629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian * Rotation constant: 180 degree rotation. 10729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian */ 10829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian public static final int ROTATION_180 = 2; 10929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian 11029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian /** 11129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian * Rotation constant: 270 degree rotation. 11229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian */ 11329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian public static final int ROTATION_270 = 3; 11429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian 11529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian /** 11664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Create an empty surface, which will later be filled in by readFromParcel(). 11764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * @hide 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public Surface() { 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Create Surface from a {@link SurfaceTexture}. 12464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * 12564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Images drawn to the Surface will be made available to the {@link 12664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link 12764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * SurfaceTexture#updateTexImage}. 12864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * 12964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * @param surfaceTexture The {@link SurfaceTexture} that is updated by this 13064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Surface. 131a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * @throws OutOfResourcesException if the surface could not be created. 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public Surface(SurfaceTexture surfaceTexture) { 13464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown if (surfaceTexture == null) { 13564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown throw new IllegalArgumentException("surfaceTexture must not be null"); 13664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 13764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 138fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 139fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown mName = surfaceTexture.toString(); 140a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture)); 141f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian } 142240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima } 143240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima 14486e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian /* called from android_view_Surface_createFromIGraphicBufferProducer() */ 14536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat private Surface(long nativeObject) { 146fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 147fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown setNativeObjectLocked(nativeObject); 148fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown } 1493866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian } 1503866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian 15164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown @Override 15264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown protected void finalize() throws Throwable { 15364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown try { 15464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown if (mCloseGuard != null) { 15564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown mCloseGuard.warnIfOpen(); 15664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 15786e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian release(); 15864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } finally { 15964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown super.finalize(); 16064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 161b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian } 162b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian 163240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima /** 16464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Release the local reference to the server-side surface. 16564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Always call release() when you're done with a Surface. 16664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * This will make the surface invalid. 16764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown */ 16864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public void release() { 169fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 1707c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian if (mNativeObject != 0) { 1717c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian nativeRelease(mNativeObject); 172fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown setNativeObjectLocked(0); 1737c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian } 1743866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian } 17564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 17664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 17764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown /** 17864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Free all server-side state associated with this surface and 17964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * release this object's reference. This method can only be 18064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * called from the process that created the service. 181b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian * @hide 182b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian */ 18364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public void destroy() { 18486e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian release(); 18564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 18661566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn 18761566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn /** 18864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Returns true if this object holds a valid surface. 18964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * 19064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * @return True if it holds a physical surface, so lockCanvas() will succeed. 19164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Otherwise returns false. 19261566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn */ 19364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public boolean isValid() { 194fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 1957c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian if (mNativeObject == 0) return false; 1967c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian return nativeIsValid(mNativeObject); 1977c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian } 19864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 19961566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn 20064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown /** 20164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Gets the generation number of this surface, incremented each time 20264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * the native surface contained within this object changes. 20364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * 20464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * @return The current generation number. 20564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * @hide 20664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown */ 207b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian public int getGenerationId() { 208fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 209fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown return mGenerationId; 210fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown } 211b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian } 212b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian 213c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian /** 21464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Returns true if the consumer of this Surface is running behind the producer. 21564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * 21664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * @return True if the consumer is more than one buffer ahead of the producer. 217c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian * @hide 218c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian */ 21964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public boolean isConsumerRunningBehind() { 220fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 2217c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian checkNotReleasedLocked(); 2227c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian return nativeIsConsumerRunningBehind(mNativeObject); 2237c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian } 22464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 225c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian 226b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian /** 22764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Gets a {@link Canvas} for drawing into this surface. 22864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * 2299ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * After drawing into the provided {@link Canvas}, the caller must 23064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. 23164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * 23230d7ab9a10fcde397bae7bed5f16d1094fded8b2Mathias Agopian * @param inOutDirty A rectangle that represents the dirty region that the caller wants 23364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * to redraw. This function may choose to expand the dirty rectangle if for example 23464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * the surface has been resized or if the previous contents of the surface were 2359ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * not available. The caller must redraw the entire dirty region as represented 2369ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * by the contents of the inOutDirty rectangle upon return from this function. 23764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * The caller may also pass <code>null</code> instead, in the case where the 23864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * entire surface should be redrawn. 23964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * @return A canvas for drawing into the surface. 240a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 241a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * @throws IllegalArgumentException If the inOutDirty rectangle is not valid. 242a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * @throws OutOfResourcesException If the canvas cannot be locked. 243240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima */ 2443866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian public Canvas lockCanvas(Rect inOutDirty) 245a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin throws Surface.OutOfResourcesException, IllegalArgumentException { 246fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 2477c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian checkNotReleasedLocked(); 248ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden if (mLockedObject != 0) { 249ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden // Ideally, nativeLockCanvas() would throw in this situation and prevent the 250ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden // double-lock, but that won't happen if mNativeObject was updated. We can't 251ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden // abandon the old mLockedObject because it might still be in use, so instead 252ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden // we just refuse to re-lock the Surface. 253d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall throw new IllegalArgumentException("Surface was already locked"); 254ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden } 255ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty); 256fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown return mCanvas; 2577c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian } 25864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 259240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima 26064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown /** 26164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Posts the new contents of the {@link Canvas} to the surface and 26264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * releases the {@link Canvas}. 26364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * 26464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * @param canvas The canvas previously obtained from {@link #lockCanvas}. 26564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown */ 26664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public void unlockCanvasAndPost(Canvas canvas) { 267fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown if (canvas != mCanvas) { 268fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown throw new IllegalArgumentException("canvas object must be the same instance that " 269fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown + "was previously returned by lockCanvas"); 270fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown } 271fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown 272fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 2737c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian checkNotReleasedLocked(); 274ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden if (mNativeObject != mLockedObject) { 275ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden Log.w(TAG, "WARNING: Surface's mNativeObject (0x" + 27636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat Long.toHexString(mNativeObject) + ") != mLockedObject (0x" + 27736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat Long.toHexString(mLockedObject) +")"); 278ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden } 279ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden if (mLockedObject == 0) { 280a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin throw new IllegalStateException("Surface was not locked"); 281ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden } 282d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall try { 283d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall nativeUnlockCanvasAndPost(mLockedObject, canvas); 284d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall } finally { 285d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall nativeRelease(mLockedObject); 286d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall mLockedObject = 0; 287d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall } 2887c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian } 28964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 290240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima 291ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden /** 29264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * @deprecated This API has been removed and is not supported. Do not use. 29364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown */ 29464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown @Deprecated 29564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public void unlockCanvas(Canvas canvas) { 29664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown throw new UnsupportedOperationException(); 297d10cd5765a2b706fc174f16b951d6b0a5d3740d3Romain Guy } 29838ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima 29938ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima /** 300b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian * Sets the translator used to scale canvas's width/height in compatibility 301b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian * mode. 30238ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima */ 3035be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn void setCompatibilityTranslator(Translator translator) { 304240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima if (translator != null) { 305240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima float appScale = translator.applicationScale; 306240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima mCompatibleMatrix = new Matrix(); 307240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima mCompatibleMatrix.setScale(appScale, appScale); 308240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown /** 31264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Copy another surface to this one. This surface now holds a reference 31364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * to the same data as the original surface, and is -not- the owner. 31464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * This is for use by the window manager when returning a window surface 31564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * back from a client, converting it from the representation being managed 31664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * by the window manager to the representation the client uses to draw 31764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * in to it. 31864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * @hide 31964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown */ 3203866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian public void copyFrom(SurfaceControl other) { 32164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown if (other == null) { 32264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown throw new IllegalArgumentException("other must not be null"); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 324fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown 32536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat long surfaceControlPtr = other.mNativeObject; 326fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown if (surfaceControlPtr == 0) { 3273866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian throw new NullPointerException( 3283866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian "SurfaceControl native object is null. Are you using a released SurfaceControl?"); 32964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 33036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr); 331fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown 332fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 333fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown if (mNativeObject != 0) { 334fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown nativeRelease(mNativeObject); 3357c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian } 336fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown setNativeObjectLocked(newNativeObject); 33786e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian } 33864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 33964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 34064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown /** 341fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown * This is intended to be used by {@link SurfaceView#updateWindow} only. 3427c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian * @param other access is not thread safe 3437c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian * @hide 3447c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian * @deprecated 34564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown */ 3467c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian @Deprecated 34764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public void transferFrom(Surface other) { 34864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown if (other == null) { 34964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown throw new IllegalArgumentException("other must not be null"); 35064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 35164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown if (other != this) { 35236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat final long newPtr; 353fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (other.mLock) { 354fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown newPtr = other.mNativeObject; 355fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown other.setNativeObjectLocked(0); 356fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown } 357fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown 358fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 3597c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian if (mNativeObject != 0) { 3607c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian nativeRelease(mNativeObject); 3617c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian } 362fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown setNativeObjectLocked(newPtr); 3633866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian } 36464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 36564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 36864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public int describeContents() { 36964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown return 0; 37064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 37164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 37264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public void readFromParcel(Parcel source) { 37364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown if (source == null) { 37464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown throw new IllegalArgumentException("source must not be null"); 375f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian } 376fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown 377fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 378ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden // nativeReadFromParcel() will either return mNativeObject, or 379ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden // create a new native Surface and return it after reducing 380ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden // the reference count on mNativeObject. Either way, it is 381ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden // not necessary to call nativeRelease() here. 3827c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian mName = source.readString(); 383fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source)); 38486e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown @Override 38864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public void writeToParcel(Parcel dest, int flags) { 38964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown if (dest == null) { 39064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown throw new IllegalArgumentException("dest must not be null"); 39164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 392fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 3937c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian dest.writeString(mName); 3947c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian nativeWriteToParcel(mNativeObject, dest); 3957c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian } 39664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { 39764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown release(); 39864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 39964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 4000de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg 40164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown @Override 40264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public String toString() { 403fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown synchronized (mLock) { 404ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden return "Surface(name=" + mName + ")/@0x" + 405ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden Integer.toHexString(System.identityHashCode(this)); 406fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown } 407fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown } 408fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown 40936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat private void setNativeObjectLocked(long ptr) { 410fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown if (mNativeObject != ptr) { 411fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown if (mNativeObject == 0 && ptr != 0) { 412fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown mCloseGuard.open("release"); 413fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown } else if (mNativeObject != 0 && ptr == 0) { 414fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown mCloseGuard.close(); 415fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown } 416fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown mNativeObject = ptr; 417fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown mGenerationId += 1; 418fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown } 419fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown } 420fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown 421fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown private void checkNotReleasedLocked() { 422fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown if (mNativeObject == 0) { 423fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown throw new IllegalStateException("Surface has already been released."); 424fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown } 42564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 42664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 42764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown /** 4285795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza * Allocate buffers ahead of time to avoid allocation delays during rendering 4295795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza * @hide 4305795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza */ 4315795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza public void allocateBuffers() { 4325795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza synchronized (mLock) { 4335795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza checkNotReleasedLocked(); 4345795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza nativeAllocateBuffers(mNativeObject); 4355795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza } 4365795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza } 4375795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza 4385795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza /** 439a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or 440a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * when a SurfaceTexture could not successfully be allocated. 44164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown */ 442a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @SuppressWarnings("serial") 443a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin public static class OutOfResourcesException extends RuntimeException { 44464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public OutOfResourcesException() { 44564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 44664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public OutOfResourcesException(String name) { 44764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown super(name); 44864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 44964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 45064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 45164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown /** 452152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov * Returns a human readable representation of a rotation. 453152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov * 454152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov * @param rotation The rotation. 455152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov * @return The rotation symbolic name. 456545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov * 457545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov * @hide 458152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov */ 459152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov public static String rotationToString(int rotation) { 460152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov switch (rotation) { 461152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov case Surface.ROTATION_0: { 462152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov return "ROTATION_0"; 463152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov } 464152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov case Surface.ROTATION_90: { 465152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov return "ROATATION_90"; 466152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov } 467152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov case Surface.ROTATION_180: { 468152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov return "ROATATION_180"; 469152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov } 470152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov case Surface.ROTATION_270: { 471152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov return "ROATATION_270"; 472152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov } 473152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov default: { 474152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov throw new IllegalArgumentException("Invalid rotation: " + rotation); 475152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov } 476152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov } 477152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov } 478152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov 479152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov /** 48064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * A Canvas class that can handle the compatibility mode. 48164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * This does two things differently. 48264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * <ul> 48364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * <li>Returns the width and height of the target metrics, rather than 48464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * native. For example, the canvas returns 320x480 even if an app is running 48564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * in WVGA high density. 48664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * <li>Scales the matrix in setMatrix by the application scale, except if 48764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * the matrix looks like obtained from getMatrix. This is a hack to handle 48864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * the case that an application uses getMatrix to keep the original matrix, 48964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * set matrix of its own, then set the original matrix back. There is no 49064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * perfect solution that works for all cases, and there are a lot of cases 49164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * that this model does not work, but we hope this works for many apps. 49264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * </ul> 49364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown */ 49464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown private final class CompatibleCanvas extends Canvas { 49564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown // A temp matrix to remember what an application obtained via {@link getMatrix} 49664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown private Matrix mOrigMatrix = null; 49764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 49864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown @Override 49964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public void setMatrix(Matrix matrix) { 50064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) { 50164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown // don't scale the matrix if it's not compatibility mode, or 50264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown // the matrix was obtained from getMatrix. 50364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown super.setMatrix(matrix); 50464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } else { 50564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown Matrix m = new Matrix(mCompatibleMatrix); 50664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown m.preConcat(matrix); 50764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown super.setMatrix(m); 50864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 50964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 51064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 5118b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy @SuppressWarnings("deprecation") 51264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown @Override 51364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown public void getMatrix(Matrix m) { 51464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown super.getMatrix(m); 51564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown if (mOrigMatrix == null) { 516ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden mOrigMatrix = new Matrix(); 51764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 51864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown mOrigMatrix.set(m); 51964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 52064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 522