Surface.java revision 7c1ad0cac642dc9a2e84499d7503b7804e0552fe
1a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar/* 2a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * Copyright (C) 2007 The Android Open Source Project 3a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * 4a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * Licensed under the Apache License, Version 2.0 (the "License"); 5a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * you may not use this file except in compliance with the License. 6a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * You may obtain a copy of the License at 7a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * 8a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * http://www.apache.org/licenses/LICENSE-2.0 9a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * 10a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * Unless required by applicable law or agreed to in writing, software 11d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth * distributed under the License is distributed on an "AS IS" BASIS, 12dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth * See the License for the specific language governing permissions and 14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth * limitations under the License. 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth */ 168c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar 174a0abd80f18f9c2a10bf5b14cd6731d51972a426Daniel Dunbarpackage android.view; 18a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar 198c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbarimport android.annotation.IntDef; 202761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbarimport android.content.res.CompatibilityInfo.Translator; 21abde2982e3c660398ff5a8e5f7ac3d1467b83062Daniel Dunbarimport android.graphics.Canvas; 2290edac0e8b35f766599362b6301863229f0ddcdbChris Lattnerimport android.graphics.Matrix; 23bfe3686aee881cb7599c42fc96afc44ff9bcf356Evan Chengimport android.graphics.Rect; 240e6a052331f674dd70e28af41f654a7874405eabEvan Chengimport android.graphics.SurfaceTexture; 25e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Chengimport android.os.Parcel; 26f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattnerimport android.os.Parcelable; 27a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbarimport android.util.Log; 285e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola 29c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwinimport java.lang.annotation.Retention; 304a0abd80f18f9c2a10bf5b14cd6731d51972a426Daniel Dunbarimport java.lang.annotation.RetentionPolicy; 3186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner 32d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruthimport dalvik.system.CloseGuard; 33a11c3e25015a62c817e60ec4f955a7f3f3bb6c67Rafael Espindola 34476b242fe7a61e5f9ac6214b0bc5c680d24f152eNick Lewycky/** 35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines * Handle onto a raw buffer that is being managed by the screen compositor. 36a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar */ 37a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbarpublic class Surface implements Parcelable { 38a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar private static final String TAG = "Surface"; 39a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar 4046a947d8c191e5c218e736330c9d4d59ac4bcab3Chris Lattner private static native long nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture) 41916a94b870042772568fca7995cf45aef7a6e333Bill Wendling throws OutOfResourcesException; 4286e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner private static native long nativeCreateFromSurfaceControl(long surfaceControlNativeObject); 4399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling 44916a94b870042772568fca7995cf45aef7a6e333Bill Wendling private static native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty) 4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines throws OutOfResourcesException; 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines private static native void nativeUnlockCanvasAndPost(long nativeObject, Canvas canvas); 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 4800545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach private static native void nativeRelease(long nativeObject); 4986e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner private static native boolean nativeIsValid(long nativeObject); 50d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner private static native boolean nativeIsConsumerRunningBehind(long nativeObject); 519dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar private static native long nativeReadFromParcel(long nativeObject, Parcel source); 529dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar private static native void nativeWriteToParcel(long nativeObject, Parcel dest); 539dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar 5444d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky private static native void nativeAllocateBuffers(long nativeObject); 559dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar 566e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola public static final Parcelable.Creator<Surface> CREATOR = 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new Parcelable.Creator<Surface>() { 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines @Override 596e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola public Surface createFromParcel(Parcel source) { 6046a947d8c191e5c218e736330c9d4d59ac4bcab3Chris Lattner try { 6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Surface s = new Surface(); 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines s.readFromParcel(source); 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return s; 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } catch (Exception e) { 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Log.e(TAG, "Exception creating surface from parcel", e); 66320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola return null; 67320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola } 68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 695d672cfab096390690a1a5f33b0057c4cf252c55Chris Lattner 705d672cfab096390690a1a5f33b0057c4cf252c55Chris Lattner @Override 715d672cfab096390690a1a5f33b0057c4cf252c55Chris Lattner public Surface[] newArray(int size) { 72a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar return new Surface[size]; 7386e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner } 74d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner }; 75d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner 7686e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner private final CloseGuard mCloseGuard = CloseGuard.get(); 7786e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner 7886e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner // Guarded state. 7986e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner final Object mLock = new Object(); // protects the native state 8086e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner private String mName; 8186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner long mNativeObject; // package scope only for SurfaceControl access 8256591ab218639d8a6e4c756ca37adaf20215c3b6Chris Lattner private long mLockedObject; 8356591ab218639d8a6e4c756ca37adaf20215c3b6Chris Lattner private int mGenerationId; // incremented each time mNativeObject changes 8456591ab218639d8a6e4c756ca37adaf20215c3b6Chris Lattner private final Canvas mCanvas = new CompatibleCanvas(); 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8600545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach // A matrix to scale the matrix set by application. This is set to null for 8791bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner // non compatibility mode. 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines private Matrix mCompatibleMatrix; 896b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar 90d32c7cfa248f685e6e3064c0958dc2f0c31a4df6Chris Lattner private HwuiContext mHwuiContext; 9186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner 9286e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner /** @hide */ 9386e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270}) 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines @Retention(RetentionPolicy.SOURCE) 956b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar public @interface Rotation {} 966b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /** 986b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar * Rotation constant: 0 degree rotation (natural orientation) 99d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner */ 100d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner public static final int ROTATION_0 = 0; 101d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /** 103d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner * Rotation constant: 90 degree rotation. 104d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner */ 105d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner public static final int ROTATION_90 = 1; 106d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner 1076b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar /** 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Rotation constant: 180 degree rotation. 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */ 1100fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner public static final int ROTATION_180 = 2; 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1120fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner /** 1130fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner * Rotation constant: 270 degree rotation. 1146b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar */ 11546a947d8c191e5c218e736330c9d4d59ac4bcab3Chris Lattner public static final int ROTATION_270 = 3; 11646a947d8c191e5c218e736330c9d4d59ac4bcab3Chris Lattner 117a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar /** 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Create an empty surface, which will later be filled in by readFromParcel(). 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @hide 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */ 12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public Surface() { 12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /** 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Create Surface from a {@link SurfaceTexture}. 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Images drawn to the Surface will be made available to the {@link 12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * SurfaceTexture#updateTexImage}. 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @param surfaceTexture The {@link SurfaceTexture} that is updated by this 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Surface. 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @throws OutOfResourcesException if the surface could not be created. 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */ 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public Surface(SurfaceTexture surfaceTexture) { 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (surfaceTexture == null) { 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines throw new IllegalArgumentException("surfaceTexture must not be null"); 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines synchronized (mLock) { 14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines mName = surfaceTexture.toString(); 14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture)); 14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 14595cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby 1469eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner /* called from android_view_Surface_createFromIGraphicBufferProducer() */ 1479eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner private Surface(long nativeObject) { 1489eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner synchronized (mLock) { 1499eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner setNativeObjectLocked(nativeObject); 150a00b80b04c5edb08639c1c6b32e9231fd8b066f7Dmitri Gribenko } 15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines @Override 154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines protected void finalize() throws Throwable { 15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines try { 15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (mCloseGuard != null) { 15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines mCloseGuard.warnIfOpen(); 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines release(); 16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } finally { 16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines super.finalize(); 162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /** 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Release the local reference to the server-side surface. 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Always call release() when you're done with a Surface. 16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * This will make the surface invalid. 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */ 17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public void release() { 17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines synchronized (mLock) { 17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (mNativeObject != 0) { 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines nativeRelease(mNativeObject); 17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setNativeObjectLocked(0); 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (mHwuiContext != null) { 17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines mHwuiContext.destroy(); 17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines mHwuiContext = null; 17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /** 18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Free all server-side state associated with this surface and 18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * release this object's reference. This method can only be 18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * called from the process that created the service. 18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @hide 18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */ 18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public void destroy() { 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines release(); 19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /** 19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Returns true if this object holds a valid surface. 19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @return True if it holds a physical surface, so lockCanvas() will succeed. 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Otherwise returns false. 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */ 19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public boolean isValid() { 20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines synchronized (mLock) { 20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (mNativeObject == 0) return false; 20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return nativeIsValid(mNativeObject); 20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /** 20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Gets the generation number of this surface, incremented each time 20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * the native surface contained within this object changes. 20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * 21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @return The current generation number. 21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @hide 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */ 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public int getGenerationId() { 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines synchronized (mLock) { 215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return mGenerationId; 216cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 217cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /** 220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines * Returns true if the consumer of this Surface is running behind the producer. 221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines * 222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines * @return True if the consumer is more than one buffer ahead of the producer. 223cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines * @hide 224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines */ 225cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines public boolean isConsumerRunningBehind() { 226cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines synchronized (mLock) { 227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines checkNotReleasedLocked(); 228cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return nativeIsConsumerRunningBehind(mNativeObject); 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /** 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Gets a {@link Canvas} for drawing into this surface. 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * 2354766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky * After drawing into the provided {@link Canvas}, the caller must 236bd4ec84d154bdd3f19b07de1076a06c16f7ebce8Jim Grosbach * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. 23791bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner * 23891bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner * @param inOutDirty A rectangle that represents the dirty region that the caller wants 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * to redraw. This function may choose to expand the dirty rectangle if for example 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * the surface has been resized or if the previous contents of the surface were 24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * not available. The caller must redraw the entire dirty region as represented 24246a947d8c191e5c218e736330c9d4d59ac4bcab3Chris Lattner * by the contents of the inOutDirty rectangle upon return from this function. 24384a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar * The caller may also pass <code>null</code> instead, in the case where the 24446a947d8c191e5c218e736330c9d4d59ac4bcab3Chris Lattner * entire surface should be redrawn. 245a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * @return A canvas for drawing into the surface. 246d32c7cfa248f685e6e3064c0958dc2f0c31a4df6Chris Lattner * 24786e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner * @throws IllegalArgumentException If the inOutDirty rectangle is not valid. 24886e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner * @throws OutOfResourcesException If the canvas cannot be locked. 24986e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner */ 250d32c7cfa248f685e6e3064c0958dc2f0c31a4df6Chris Lattner public Canvas lockCanvas(Rect inOutDirty) 25186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner throws Surface.OutOfResourcesException, IllegalArgumentException { 25200545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach synchronized (mLock) { 253d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner checkNotReleasedLocked(); 254d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner if (mLockedObject != 0) { 25500545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach // Ideally, nativeLockCanvas() would throw in this situation and prevent the 25686e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner // double-lock, but that won't happen if mNativeObject was updated. We can't 257d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner // abandon the old mLockedObject because it might still be in use, so instead 258d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner // we just refuse to re-lock the Surface. 25900545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach throw new IllegalArgumentException("Surface was already locked"); 26014ca177beba15e86ca410c9f6fc7f48ba245dba6Chris Lattner } 26114ca177beba15e86ca410c9f6fc7f48ba245dba6Chris Lattner mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty); 26286e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner return mCanvas; 26386e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner } 26486e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner } 265d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner 266d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner /** 267d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner * Posts the new contents of the {@link Canvas} to the surface and 268d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner * releases the {@link Canvas}. 26900545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach * 270d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner * @param canvas The canvas previously obtained from {@link #lockCanvas}. 27186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner */ 27200545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach public void unlockCanvasAndPost(Canvas canvas) { 273d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner synchronized (mLock) { 274d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner checkNotReleasedLocked(); 275d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner 27686e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner if (mHwuiContext != null) { 27799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling mHwuiContext.unlockAndPost(canvas); 27886e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner } else { 27999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unlockSwCanvasAndPost(canvas); 28000545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach } 28186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner } 282d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner } 28300545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach 28414ca177beba15e86ca410c9f6fc7f48ba245dba6Chris Lattner private void unlockSwCanvasAndPost(Canvas canvas) { 28514ca177beba15e86ca410c9f6fc7f48ba245dba6Chris Lattner if (canvas != mCanvas) { 28614ca177beba15e86ca410c9f6fc7f48ba245dba6Chris Lattner throw new IllegalArgumentException("canvas object must be the same instance that " 28786e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner + "was previously returned by lockCanvas"); 28886e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner } 289304f6a48b1232bdad8b2c0dff7c08d677826ef86Daniel Dunbar if (mNativeObject != mLockedObject) { 290304f6a48b1232bdad8b2c0dff7c08d677826ef86Daniel Dunbar Log.w(TAG, "WARNING: Surface's mNativeObject (0x" + 291304f6a48b1232bdad8b2c0dff7c08d677826ef86Daniel Dunbar Long.toHexString(mNativeObject) + ") != mLockedObject (0x" + 292304f6a48b1232bdad8b2c0dff7c08d677826ef86Daniel Dunbar Long.toHexString(mLockedObject) +")"); 293304f6a48b1232bdad8b2c0dff7c08d677826ef86Daniel Dunbar } 29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (mLockedObject == 0) { 29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines throw new IllegalStateException("Surface was not locked"); 29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines try { 29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines nativeUnlockCanvasAndPost(mLockedObject, canvas); 29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } finally { 30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines nativeRelease(mLockedObject); 301df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne mLockedObject = 0; 302df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne } 3036c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner } 30499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling 305a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar /** 306a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * Gets a {@link Canvas} for drawing into this surface. 307a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * 3088906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar * After drawing into the provided {@link Canvas}, the caller must 309ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. 31071d259bc4be4f5c7a8a30c6be8da105074ff805aDaniel Dunbar * 31199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling * Unlike {@link #lockCanvas(Rect)} this will return a hardware-accelerated 3127d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner * canvas. See the <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#unsupported"> 313a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * unsupported drawing operations</a> for a list of what is and isn't 314a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar * supported in a hardware-accelerated canvas. 31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * 31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @return A canvas for drawing into the surface. 31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * 31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @throws IllegalStateException If the canvas cannot be locked. 31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @hide 32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */ 32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public Canvas lockHardwareCanvas() { 32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines synchronized (mLock) { 32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines checkNotReleasedLocked(); 32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (mHwuiContext == null) { 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines mHwuiContext = new HwuiContext(); 32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return mHwuiContext.lockCanvas(); 32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /** 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @deprecated This API has been removed and is not supported. Do not use. 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */ 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines @Deprecated 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public void unlockCanvas(Canvas canvas) { 336a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner throw new UnsupportedOperationException(); 337f96db468fcf62d671cda99b68b6cfd3f2dc0b839Kevin Enderby } 338afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim 339a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner /** 34099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling * Sets the translator used to scale canvas's width/height in compatibility 34199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling * mode. 34299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling */ 343f96db468fcf62d671cda99b68b6cfd3f2dc0b839Kevin Enderby void setCompatibilityTranslator(Translator translator) { 3447d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner if (translator != null) { 345a5c783280f83df5c60a8ed9e32c61b05a11048e3Kevin Enderby float appScale = translator.applicationScale; 346a5c783280f83df5c60a8ed9e32c61b05a11048e3Kevin Enderby mCompatibleMatrix = new Matrix(); 347cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar mCompatibleMatrix.setScale(appScale, appScale); 348cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar } 349cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar } 350cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar 351cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar /** 352cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar * Copy another surface to this one. This surface now holds a reference 353cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar * to the same data as the original surface, and is -not- the owner. 3546d49b680be6e24b547e6910c2b64914913915084Daniel Dunbar * This is for use by the window manager when returning a window surface 355cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar * back from a client, converting it from the representation being managed 356cddd236e8a5acb80e9a0e79dc63f6cfaa8205b86Daniel Dunbar * by the window manager to the representation the client uses to draw 3573e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach * in to it. 35899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling * @hide 3593e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach */ 3603e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach public void copyFrom(SurfaceControl other) { 3613e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach if (other == null) { 3623e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach throw new IllegalArgumentException("other must not be null"); 3633e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach } 3643e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach 3653e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach long surfaceControlPtr = other.mNativeObject; 3663e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach if (surfaceControlPtr == 0) { 3673e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach throw new NullPointerException( 3683e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach "SurfaceControl native object is null. Are you using a released SurfaceControl?"); 3693e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach } 37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr); 37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines synchronized (mLock) { 37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (mNativeObject != 0) { 37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines nativeRelease(mNativeObject); 37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setNativeObjectLocked(newNativeObject); 37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /** 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * This is intended to be used by {@link SurfaceView#updateWindow} only. 382ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach * @param other access is not thread safe 383ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach * @hide 384ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach * @deprecated 385ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach */ 3866469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola @Deprecated 38799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling public void transferFrom(Surface other) { 388ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach if (other == null) { 389ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach throw new IllegalArgumentException("other must not be null"); 390ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach } 391ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach if (other != this) { 392821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar final long newPtr; 3937d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner synchronized (other.mLock) { 3947d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner newPtr = other.mNativeObject; 395fffff915d53361fc575621c5e04ae7df99dd3fabDaniel Dunbar other.setNativeObjectLocked(0); 39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 397a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar 398a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar synchronized (mLock) { 399484291c27319668ad99cb87def000254357736fbRafael Espindola if (mNativeObject != 0) { 400484291c27319668ad99cb87def000254357736fbRafael Espindola nativeRelease(mNativeObject); 401484291c27319668ad99cb87def000254357736fbRafael Espindola } 402484291c27319668ad99cb87def000254357736fbRafael Espindola setNativeObjectLocked(newPtr); 403484291c27319668ad99cb87def000254357736fbRafael Espindola } 4041c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool } 405a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner } 406a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar 407858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper @Override 408ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner public int describeContents() { 409ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner return 0; 410ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner } 411ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner 412ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner public void readFromParcel(Parcel source) { 413ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner if (source == null) { 414e9c0ff2a76508922b3f3ec07484ba579d4c51d95Rafael Espindola throw new IllegalArgumentException("source must not be null"); 4151c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool } 4161c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool 417523d70ec1f8daa67bb8a9fe8f7b6b3d076a26c99Dan Gohman synchronized (mLock) { 41899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling // nativeReadFromParcel() will either return mNativeObject, or 419ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner // create a new native Surface and return it after reducing 4201c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool // the reference count on mNativeObject. Either way, it is 421ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner // not necessary to call nativeRelease() here. 422ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner mName = source.readString(); 423ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source)); 424ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner } 425ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner } 426ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner 427e9c0ff2a76508922b3f3ec07484ba579d4c51d95Rafael Espindola @Override 428ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner public void writeToParcel(Parcel dest, int flags) { 429ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner if (dest == null) { 4301c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool throw new IllegalArgumentException("dest must not be null"); 431ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner } 43299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling synchronized (mLock) { 433ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner dest.writeString(mName); 43461abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner nativeWriteToParcel(mNativeObject, dest); 43561abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner } 43661abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { 43761abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner release(); 43861abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner } 43961abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner } 440e8e98d7f2eaa0613442ce21ab6a040c0f04f5b4dKevin Enderby 441277abc8172a19b287e9b6ea0969bc113d7ac48e4Rafael Espindola @Override 442277abc8172a19b287e9b6ea0969bc113d7ac48e4Rafael Espindola public String toString() { 443277abc8172a19b287e9b6ea0969bc113d7ac48e4Rafael Espindola synchronized (mLock) { 44461abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner return "Surface(name=" + mName + ")/@0x" + 44561abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner Integer.toHexString(System.identityHashCode(this)); 44661abd7b395d0bbebd8cc44c870b02609abef6976Chris Lattner } 447277abc8172a19b287e9b6ea0969bc113d7ac48e4Rafael Espindola } 448277abc8172a19b287e9b6ea0969bc113d7ac48e4Rafael Espindola 449277abc8172a19b287e9b6ea0969bc113d7ac48e4Rafael Espindola private void setNativeObjectLocked(long ptr) { 450a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner if (mNativeObject != ptr) { 45199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling if (mNativeObject == 0 && ptr != 0) { 452f59cac5ed36360b4c462781051f996b3499d7e0fKevin Enderby mCloseGuard.open("release"); 453a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar } else if (mNativeObject != 0 && ptr == 0) { 454a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar mCloseGuard.close(); 4557d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner } 4567d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner mNativeObject = ptr; 4571c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool mGenerationId += 1; 4581c9cd021c8999d9c2c0786dff074d1e75bbd0eb2Saleem Abdulrasool if (mHwuiContext != null) { 459a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar mHwuiContext.updateSurface(); 460a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar } 46195cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby } 4627d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner } 4637d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner 46495cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby private void checkNotReleasedLocked() { 46595cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby if (mNativeObject == 0) { 466b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner throw new IllegalStateException("Surface has already been released."); 467b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner } 468b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner } 469b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner 470b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner /** 471b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner * Allocate buffers ahead of time to avoid allocation delays during rendering 472b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner * @hide 473b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner */ 474b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner public void allocateBuffers() { 475b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner synchronized (mLock) { 476b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner checkNotReleasedLocked(); 477b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner nativeAllocateBuffers(mNativeObject); 478b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner } 479b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner } 480b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner 481b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner /** 482b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner * Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or 483b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner * when a SurfaceTexture could not successfully be allocated. 484b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner */ 485b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner @SuppressWarnings("serial") 48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public static class OutOfResourcesException extends RuntimeException { 48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public OutOfResourcesException() { 48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public OutOfResourcesException(String name) { 49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines super(name); 4918f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola } 49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 4938f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola 4948f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola /** 4958f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola * Returns a human readable representation of a rotation. 49699328add833807f12a4950c7de29fb2a5df04703Chris Lattner * 49799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling * @param rotation The rotation. 49899328add833807f12a4950c7de29fb2a5df04703Chris Lattner * @return The rotation symbolic name. 49999328add833807f12a4950c7de29fb2a5df04703Chris Lattner * 50099328add833807f12a4950c7de29fb2a5df04703Chris Lattner * @hide 5019eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner */ 5027092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar public static String rotationToString(int rotation) { 503eb46def978a60fd705cca3037feff5573122b404Richard Mitton switch (rotation) { 504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Surface.ROTATION_0: { 5055cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton return "ROTATION_0"; 5069eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner } 5076559d7688e24e204af273a1e1252639320a7b309Chris Lattner case Surface.ROTATION_90: { 50899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling return "ROATATION_90"; 5094ed5438f4882c9fe779b1a8ff546877889b222dfChris Lattner } 5104ed5438f4882c9fe779b1a8ff546877889b222dfChris Lattner case Surface.ROTATION_180: { 5114ed5438f4882c9fe779b1a8ff546877889b222dfChris Lattner return "ROATATION_180"; 5124ed5438f4882c9fe779b1a8ff546877889b222dfChris Lattner } 5137d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner case Surface.ROTATION_270: { 5144e4db7adfc9858a8f77f841c7467bc6fcbb8110eChris Lattner return "ROATATION_270"; 5154e4db7adfc9858a8f77f841c7467bc6fcbb8110eChris Lattner } 5169eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner default: { 5179eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner throw new IllegalArgumentException("Invalid rotation: " + rotation); 5189eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner } 5199eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner } 52036a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer } 52136a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer 522eb46def978a60fd705cca3037feff5573122b404Richard Mitton /** 523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines * A Canvas class that can handle the compatibility mode. 5245cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton * This does two things differently. 5259eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner * <ul> 52636a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer * <li>Returns the width and height of the target metrics, rather than 52799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling * native. For example, the canvas returns 320x480 even if an app is running 528a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer * in WVGA high density. 529a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer * <li>Scales the matrix in setMatrix by the application scale, except if 530a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer * the matrix looks like obtained from getMatrix. This is a hack to handle 53139646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer * the case that an application uses getMatrix to keep the original matrix, 532a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer * set matrix of its own, then set the original matrix back. There is no 533a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer * perfect solution that works for all cases, and there are a lot of cases 53439646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer * that this model does not work, but we hope this works for many apps. 53539646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer * </ul> 536a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer */ 53739646d96e76aea5d20bffb386233a0dbb5932a21Benjamin Kramer private final class CompatibleCanvas extends Canvas { 53836a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer // A temp matrix to remember what an application obtained via {@link getMatrix} 5399eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner private Matrix mOrigMatrix = null; 5409eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner 5419eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner @Override 5428751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbar public void setMatrix(Matrix matrix) { 543c90a1fcf9f44858b20e0f5f7e0b98049aec7a1e0Evan Cheng if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) { 5445cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton // don't scale the matrix if it's not compatibility mode, or 5455cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton // the matrix was obtained from getMatrix. 5465cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton super.setMatrix(matrix); 547011e4db845b5c4166142338c77adc8ac03e5e041Daniel Dunbar } else { 54893b6db3de934a3cfca5586df25184fef4a54c500Chris Lattner Matrix m = new Matrix(mCompatibleMatrix); 54900545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach m.preConcat(matrix); 55093b6db3de934a3cfca5586df25184fef4a54c500Chris Lattner super.setMatrix(m); 551ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner } 55212de0df59fdab799d8d1432fcfd9190829d7f292Daniel Dunbar } 55300545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach 554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines @SuppressWarnings("deprecation") 55510b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner @Override 5567092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar public void getMatrix(Matrix m) { 5577092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar super.getMatrix(m); 5589be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner if (mOrigMatrix == null) { 5597d1e49c98332ff336bd6a6837855c8cdb1b36e97Chris Lattner mOrigMatrix = new Matrix(); 5609be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner } 5619be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner mOrigMatrix.set(m); 562d04d98d24fe5c82c7e69b711cd989ef96980fb8eEric Christopher } 563d04d98d24fe5c82c7e69b711cd989ef96980fb8eEric Christopher } 564d04d98d24fe5c82c7e69b711cd989ef96980fb8eEric Christopher 5654d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher private final class HwuiContext { 5664d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher private final RenderNode mRenderNode; 5675cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton private long mHwuiRenderer; 5685cc319a42a914b24b164a94d9a563c728a7a4026Richard Mitton private HardwareCanvas mCanvas; 569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 5704d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher HwuiContext() { 5714d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher mRenderNode = RenderNode.create("HwuiCanvas", null); 572d04d98d24fe5c82c7e69b711cd989ef96980fb8eEric Christopher mRenderNode.setClipToBounds(false); 57300545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach mHwuiRenderer = nHwuiCreate(mRenderNode.mNativeRenderNode, mNativeObject); 5744d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher } 5754d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher 5764d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher Canvas lockCanvas() { 57700545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach if (mCanvas != null) { 578482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher throw new IllegalStateException("Surface was already locked!"); 579482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher } 580482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher mCanvas = mRenderNode.start(0, 0); 58112e555c36ce11c39ce15cd0b27bf7b02a068beb2Chris Lattner return mCanvas; 58212e555c36ce11c39ce15cd0b27bf7b02a068beb2Chris Lattner } 583a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner 584a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner void unlockAndPost(Canvas canvas) { 58500545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach if (canvas != mCanvas) { 586a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner throw new IllegalArgumentException("canvas object must be the same instance that " 587a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner + "was previously returned by lockCanvas"); 588a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner } 589a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner mRenderNode.end(mCanvas); 590a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner mCanvas = null; 591a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner nHwuiDraw(mHwuiRenderer); 59200545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach } 593a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner 594a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner void updateSurface() { 595a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner nHwuiSetSurface(mHwuiRenderer, mNativeObject); 596a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner } 59700545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach 598a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner void destroy() { 599a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner if (mHwuiRenderer != 0) { 600a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner nHwuiDestroy(mHwuiRenderer); 601a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner mHwuiRenderer = 0; 602a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner } 603a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner } 604a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner 605a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner @Override 606a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner protected void finalize() throws Throwable { 607a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner try { 608a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner destroy(); 609a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner } finally { 610a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner super.finalize(); 611a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner } 61200545e1cd50073ed8a3af98070a16b50f3c3401cJim Grosbach } 613a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner } 614a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner 615a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner private static native long nHwuiCreate(long rootNode, long surface); 616a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner private static native void nHwuiSetSurface(long renderer, long surface); 617a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola private static native void nHwuiDraw(long renderer); 618df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne private static native void nHwuiDestroy(long renderer); 619df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne} 62012e555c36ce11c39ce15cd0b27bf7b02a068beb2Chris Lattner