1aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy/* 2aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Copyright (C) 2011 The Android Open Source Project 3aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 4aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * you may not use this file except in compliance with the License. 6aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * You may obtain a copy of the License at 7aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 8aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 9aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 10aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Unless required by applicable law or agreed to in writing, software 11aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * See the License for the specific language governing permissions and 14aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * limitations under the License. 15aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 16aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 17aa6c24c21c727a196451332448d4e3b11a80be69Romain Guypackage android.view; 18aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 19342a7e6a7cdf0f3ddf9302c0fd9d8a73ba98bb7fsergeyvimport android.annotation.Nullable; 20aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.content.Context; 2177a811610f99e21da7f88dafef60d09f345d0506Romain Guyimport android.graphics.Bitmap; 22aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.graphics.Canvas; 23302a9df1d50373c82923bb84ff665dfce584fb22Romain Guyimport android.graphics.Matrix; 24aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.graphics.Paint; 256be3d5561cbeccf0a8257a4acb155657f868e548Romain Guyimport android.graphics.Rect; 26aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.graphics.SurfaceTexture; 272e931eae355c27df4df82a7345e1f06d0d188201Chris Craikimport android.graphics.drawable.Drawable; 28aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.util.AttributeSet; 29aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.util.Log; 30aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 31aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy/** 32aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * <p>A TextureView can be used to display a content stream. Such a content 33aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * stream can for instance be a video or an OpenGL scene. The content stream 34aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * can come from the application's process as well as a remote process.</p> 355ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 36aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * <p>TextureView can only be used in a hardware accelerated window. When 37aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * rendered in software, TextureView will draw nothing.</p> 385ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 39aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * <p>Unlike {@link SurfaceView}, TextureView does not create a separate 40aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * window but behaves as a regular View. This key difference allows a 41aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * TextureView to be moved, transformed, animated, etc. For instance, you 42aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * can make a TextureView semi-translucent by calling 43aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * <code>myView.setAlpha(0.5f)</code>.</p> 445ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 45aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * <p>Using a TextureView is simple: all you need to do is get its 46aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * {@link SurfaceTexture}. The {@link SurfaceTexture} can then be used to 475ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * render content. The following example demonstrates how to render the 48aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * camera preview into a TextureView:</p> 495ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 50aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * <pre> 51aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * public class LiveCameraActivity extends Activity implements TextureView.SurfaceTextureListener { 52aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * private Camera mCamera; 53aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * private TextureView mTextureView; 54aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 55aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * protected void onCreate(Bundle savedInstanceState) { 56aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * super.onCreate(savedInstanceState); 57aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 58aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * mTextureView = new TextureView(this); 59aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * mTextureView.setSurfaceTextureListener(this); 60aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 61aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * setContentView(mTextureView); 62aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * } 63aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 64451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy * public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 65aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * mCamera = Camera.open(); 66aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 67aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * try { 68aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * mCamera.setPreviewTexture(surface); 69aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * mCamera.startPreview(); 70aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * } catch (IOException ioe) { 71aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * // Something bad happened 72aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * } 73aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * } 74cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba * 758f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 768f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * // Ignored, Camera does all the work for us 778f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * } 78cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba * 79402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba * public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 80451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy * mCamera.stopPreview(); 81451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy * mCamera.release(); 82402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba * return true; 83451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy * } 84cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba * 85cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba * public void onSurfaceTextureUpdated(SurfaceTexture surface) { 8658f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy * // Invoked every time there's a new Camera preview frame 87cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba * } 88aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * } 89aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * </pre> 905ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 91aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * <p>A TextureView's SurfaceTexture can be obtained either by invoking 92aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * {@link #getSurfaceTexture()} or by using a {@link SurfaceTextureListener}. 93aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * It is important to know that a SurfaceTexture is available only after the 94aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * TextureView is attached to a window (and {@link #onAttachedToWindow()} has 95aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * been invoked.) It is therefore highly recommended you use a listener to 96aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * be notified when the SurfaceTexture becomes available.</p> 975ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 98462785fa257671fe4905d1d3e6ca27e4a61ee946Romain Guy * <p>It is important to note that only one producer can use the TextureView. 99462785fa257671fe4905d1d3e6ca27e4a61ee946Romain Guy * For instance, if you use a TextureView to display the camera preview, you 100462785fa257671fe4905d1d3e6ca27e4a61ee946Romain Guy * cannot use {@link #lockCanvas()} to draw onto the TextureView at the same 101462785fa257671fe4905d1d3e6ca27e4a61ee946Romain Guy * time.</p> 1025ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 103aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @see SurfaceView 104aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @see SurfaceTexture 105aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 106aa6c24c21c727a196451332448d4e3b11a80be69Romain Guypublic class TextureView extends View { 10777a811610f99e21da7f88dafef60d09f345d0506Romain Guy private static final String LOG_TAG = "TextureView"; 10877a811610f99e21da7f88dafef60d09f345d0506Romain Guy 109aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy private HardwareLayer mLayer; 110aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy private SurfaceTexture mSurface; 111aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy private SurfaceTextureListener mListener; 11267603c6e1b88fa20db58f69354e3925ffba037d1Romain Guy private boolean mHadSurface; 113aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 114a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy private boolean mOpaque = true; 115c989d867f2580a99cde25fab0e49e445aea33f2fRomain Guy 116302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy private final Matrix mMatrix = new Matrix(); 117302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy private boolean mMatrixChanged; 118302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy 11958f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy private final Object[] mLock = new Object[0]; 12058f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy private boolean mUpdateLayer; 1212af3524beb75150d347accc925022daa53b4a789Jamie Gennis private boolean mUpdateSurface; 12258f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy 1236be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy private Canvas mCanvas; 1246be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy private int mSaveCount; 1256be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy 1266be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy private final Object[] mNativeWindowLock = new Object[0]; 127918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck // Set by native code, do not write! 12836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat private long mNativeWindow; 1296be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy 130aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 131aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Creates a new TextureView. 1325ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 133aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @param context The context to associate this view with. 134aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 135aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy public TextureView(Context context) { 136aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy super(context); 137aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 138aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 139aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 140aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Creates a new TextureView. 1415ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 142aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @param context The context to associate this view with. 143aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @param attrs The attributes of the XML tag that is inflating the view. 144aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 145aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy public TextureView(Context context, AttributeSet attrs) { 146aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy super(context, attrs); 147aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 148aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 149aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 150aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Creates a new TextureView. 1515ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 152aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @param context The context to associate this view with. 153aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @param attrs The attributes of the XML tag that is inflating the view. 154617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param defStyleAttr An attribute in the current theme that contains a 155617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * reference to a style resource that supplies default values for 156617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * the view. Can be 0 to not look for defaults. 157aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 158617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public TextureView(Context context, AttributeSet attrs, int defStyleAttr) { 159617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr); 160617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette } 161617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 162617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette /** 163617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * Creates a new TextureView. 164617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * 165617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param context The context to associate this view with. 166617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param attrs The attributes of the XML tag that is inflating the view. 167617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param defStyleAttr An attribute in the current theme that contains a 168617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * reference to a style resource that supplies default values for 169617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * the view. Can be 0 to not look for defaults. 170617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param defStyleRes A resource identifier of a style resource that 171617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * supplies default values for the view, used only if 172617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * defStyleAttr is 0 or can not be found in the theme. Can be 0 173617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * to not look for defaults. 174617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette */ 175617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public TextureView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 176617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr, defStyleRes); 177aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 178aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 179a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy /** 180a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy * {@inheritDoc} 181a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy */ 182a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy @Override 183a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy public boolean isOpaque() { 184a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy return mOpaque; 185a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy } 186a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy 187a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy /** 188a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy * Indicates whether the content of this TextureView is opaque. The 189a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy * content is assumed to be opaque by default. 1905ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 191a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy * @param opaque True if the content of this TextureView is opaque, 192a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy * false otherwise 193a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy */ 194a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy public void setOpaque(boolean opaque) { 195a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy if (opaque != mOpaque) { 196a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy mOpaque = opaque; 197a8a2f97c100af4ba52c61c3b59c933f44a53dad4Romain Guy if (mLayer != null) { 19888801b270f693ffd4125534724f204135f592f72Romain Guy updateLayerAndInvalidate(); 199a8a2f97c100af4ba52c61c3b59c933f44a53dad4Romain Guy } 200a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy } 201a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy } 202a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy 203aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy @Override 204aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy protected void onAttachedToWindow() { 205aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy super.onAttachedToWindow(); 206aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 207aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy if (!isHardwareAccelerated()) { 20877a811610f99e21da7f88dafef60d09f345d0506Romain Guy Log.w(LOG_TAG, "A TextureView or a subclass can only be " 209aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy + "used with hardware acceleration enabled."); 210aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 21167603c6e1b88fa20db58f69354e3925ffba037d1Romain Guy 21267603c6e1b88fa20db58f69354e3925ffba037d1Romain Guy if (mHadSurface) { 21367603c6e1b88fa20db58f69354e3925ffba037d1Romain Guy invalidate(true); 21467603c6e1b88fa20db58f69354e3925ffba037d1Romain Guy mHadSurface = false; 21567603c6e1b88fa20db58f69354e3925ffba037d1Romain Guy } 216aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 217aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 218b14dfe20ef300c47cc5cdfbd844c21f7fd302f0cJohn Reck /** @hide */ 219451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy @Override 220b14dfe20ef300c47cc5cdfbd844c21f7fd302f0cJohn Reck protected void onDetachedFromWindowInternal() { 22119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck destroySurface(); 222b14dfe20ef300c47cc5cdfbd844c21f7fd302f0cJohn Reck super.onDetachedFromWindowInternal(); 22331f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy } 224451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy 22531f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy private void destroySurface() { 22680429c458506485904715180d10584092a5cd082Romain Guy if (mLayer != null) { 227918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck mLayer.detachSurfaceTexture(); 2282af3524beb75150d347accc925022daa53b4a789Jamie Gennis 229402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba boolean shouldRelease = true; 230451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy if (mListener != null) { 231402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba shouldRelease = mListener.onSurfaceTextureDestroyed(mSurface); 232451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 233451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy 2346be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy synchronized (mNativeWindowLock) { 2356be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy nDestroyNativeWindow(); 2366be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy } 2376be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy 2386be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy mLayer.destroy(); 239402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba if (shouldRelease) mSurface.release(); 240451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mSurface = null; 241451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mLayer = null; 24267603c6e1b88fa20db58f69354e3925ffba037d1Romain Guy 2436b471995cb0d4647474fc112ef3946c2d51e6476Doris Liu // Make sure if/when new layer gets re-created, transform matrix will 2446b471995cb0d4647474fc112ef3946c2d51e6476Doris Liu // be re-applied. 2456b471995cb0d4647474fc112ef3946c2d51e6476Doris Liu mMatrixChanged = true; 24667603c6e1b88fa20db58f69354e3925ffba037d1Romain Guy mHadSurface = true; 247451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 248451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 249451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy 250aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 251aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * The layer type of a TextureView is ignored since a TextureView is always 252aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * considered to act as a hardware layer. The optional paint supplied to this 253aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * method will however be taken into account when rendering the content of 254aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * this TextureView. 2555ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 256342a7e6a7cdf0f3ddf9302c0fd9d8a73ba98bb7fsergeyv * @param layerType The type of layer to use with this view, must be one of 257aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or 258aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * {@link #LAYER_TYPE_HARDWARE} 259aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @param paint The paint used to compose the layer. This argument is optional 260aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * and can be null. It is ignored when the layer type is 261aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * {@link #LAYER_TYPE_NONE} 262aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 263aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy @Override 264342a7e6a7cdf0f3ddf9302c0fd9d8a73ba98bb7fsergeyv public void setLayerType(int layerType, @Nullable Paint paint) { 265342a7e6a7cdf0f3ddf9302c0fd9d8a73ba98bb7fsergeyv setLayerPaint(paint); 266aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 267aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 26825fbb3fa1138675379102a44405852555cefccbdJohn Reck @Override 269342a7e6a7cdf0f3ddf9302c0fd9d8a73ba98bb7fsergeyv public void setLayerPaint(@Nullable Paint paint) { 270342a7e6a7cdf0f3ddf9302c0fd9d8a73ba98bb7fsergeyv if (paint != mLayerPaint) { 271342a7e6a7cdf0f3ddf9302c0fd9d8a73ba98bb7fsergeyv mLayerPaint = paint; 272342a7e6a7cdf0f3ddf9302c0fd9d8a73ba98bb7fsergeyv invalidate(); 273342a7e6a7cdf0f3ddf9302c0fd9d8a73ba98bb7fsergeyv } 27425fbb3fa1138675379102a44405852555cefccbdJohn Reck } 27525fbb3fa1138675379102a44405852555cefccbdJohn Reck 276aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 277aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Always returns {@link #LAYER_TYPE_HARDWARE}. 278aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 279aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy @Override 280aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy public int getLayerType() { 281aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy return LAYER_TYPE_HARDWARE; 282aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 283aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 284aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 285aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Calling this method has no effect. 286aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 287aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy @Override 288aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy public void buildLayer() { 289aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 290aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 2912e931eae355c27df4df82a7345e1f06d0d188201Chris Craik @Override 2922e931eae355c27df4df82a7345e1f06d0d188201Chris Craik public void setForeground(Drawable foreground) { 293b7244809f51ff95863c5ff8ba6226e26b9a9cf76Chris Craik if (foreground != null && !sTextureViewIgnoresDrawableSetters) { 2942e931eae355c27df4df82a7345e1f06d0d188201Chris Craik throw new UnsupportedOperationException( 2952e931eae355c27df4df82a7345e1f06d0d188201Chris Craik "TextureView doesn't support displaying a foreground drawable"); 2962e931eae355c27df4df82a7345e1f06d0d188201Chris Craik } 2972e931eae355c27df4df82a7345e1f06d0d188201Chris Craik } 2982e931eae355c27df4df82a7345e1f06d0d188201Chris Craik 2992e931eae355c27df4df82a7345e1f06d0d188201Chris Craik @Override 3002e931eae355c27df4df82a7345e1f06d0d188201Chris Craik public void setBackgroundDrawable(Drawable background) { 301b7244809f51ff95863c5ff8ba6226e26b9a9cf76Chris Craik if (background != null && !sTextureViewIgnoresDrawableSetters) { 3022e931eae355c27df4df82a7345e1f06d0d188201Chris Craik throw new UnsupportedOperationException( 3032e931eae355c27df4df82a7345e1f06d0d188201Chris Craik "TextureView doesn't support displaying a background drawable"); 3042e931eae355c27df4df82a7345e1f06d0d188201Chris Craik } 3052e931eae355c27df4df82a7345e1f06d0d188201Chris Craik } 3062e931eae355c27df4df82a7345e1f06d0d188201Chris Craik 307aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 308aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Subclasses of TextureView cannot do their own rendering 309aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * with the {@link Canvas} object. 3105ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 311aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @param canvas The Canvas to which the View is rendered. 312aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 313aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy @Override 314aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy public final void draw(Canvas canvas) { 3153aadd60521960be063ee06208562ccb63dc414e3Chris Craik // NOTE: Maintain this carefully (see View#draw) 31652b307ebc86e12e368694442eb8751e7e0de239eRomain Guy mPrivateFlags = (mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN; 31752b307ebc86e12e368694442eb8751e7e0de239eRomain Guy 3183aadd60521960be063ee06208562ccb63dc414e3Chris Craik /* Simplify drawing to guarantee the layer is the only thing drawn - so e.g. no background, 3193aadd60521960be063ee06208562ccb63dc414e3Chris Craik scrolling, or fading edges. This guarantees all drawing is in the layer, so drawing 3203aadd60521960be063ee06208562ccb63dc414e3Chris Craik properties (alpha, layer paint) affect all of the content of a TextureView. */ 3213aadd60521960be063ee06208562ccb63dc414e3Chris Craik 3223aadd60521960be063ee06208562ccb63dc414e3Chris Craik if (canvas.isHardwareAccelerated()) { 3233aadd60521960be063ee06208562ccb63dc414e3Chris Craik DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas; 3243aadd60521960be063ee06208562ccb63dc414e3Chris Craik 3253aadd60521960be063ee06208562ccb63dc414e3Chris Craik HardwareLayer layer = getHardwareLayer(); 3263aadd60521960be063ee06208562ccb63dc414e3Chris Craik if (layer != null) { 3273aadd60521960be063ee06208562ccb63dc414e3Chris Craik applyUpdate(); 3283aadd60521960be063ee06208562ccb63dc414e3Chris Craik applyTransformMatrix(); 3293aadd60521960be063ee06208562ccb63dc414e3Chris Craik 3303aadd60521960be063ee06208562ccb63dc414e3Chris Craik mLayer.setLayerPaint(mLayerPaint); // ensure layer paint is up to date 3313aadd60521960be063ee06208562ccb63dc414e3Chris Craik displayListCanvas.drawHardwareLayer(layer); 3323aadd60521960be063ee06208562ccb63dc414e3Chris Craik } 3333aadd60521960be063ee06208562ccb63dc414e3Chris Craik } 334aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 335aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 336aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 337aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Subclasses of TextureView cannot do their own rendering 338aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * with the {@link Canvas} object. 3395ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 340aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @param canvas The Canvas to which the View is rendered. 341aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 342aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy @Override 343aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy protected final void onDraw(Canvas canvas) { 344aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 345aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 346aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy @Override 3478f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy protected void onSizeChanged(int w, int h, int oldw, int oldh) { 3488f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy super.onSizeChanged(w, h, oldw, oldh); 3498f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (mSurface != null) { 35052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian mSurface.setDefaultBufferSize(getWidth(), getHeight()); 35188801b270f693ffd4125534724f204135f592f72Romain Guy updateLayer(); 352451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy if (mListener != null) { 353451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mListener.onSurfaceTextureSizeChanged(mSurface, getWidth(), getHeight()); 354451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 3558f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3568f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3578f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 3581766b0e25de5a66f9d0f6e73a2c342272fcadc71Romain Guy /** 3591766b0e25de5a66f9d0f6e73a2c342272fcadc71Romain Guy * @hide 3601766b0e25de5a66f9d0f6e73a2c342272fcadc71Romain Guy */ 36116260e73f6c1c9dc94acf0d328a3c564426b8711Romain Guy @Override 36231f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy protected void destroyHardwareResources() { 36331f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy super.destroyHardwareResources(); 36431f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy destroySurface(); 36531f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy invalidateParentCaches(); 36631f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy invalidate(true); 36731f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy } 36831f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy 3697e52caf6db5feef2b847cfaa3d13690257122c3aMichael Jurka HardwareLayer getHardwareLayer() { 370aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy if (mLayer == null) { 37158f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) { 37258f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy return null; 37358f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy } 37458f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy 37504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mLayer = mAttachInfo.mHardwareRenderer.createTextureLayer(); 3762af3524beb75150d347accc925022daa53b4a789Jamie Gennis if (!mUpdateSurface) { 3778a34d6800e70da45bac662873f6951c8d8295a15Jamie Gennis // Create a new SurfaceTexture for the layer. 378918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck mSurface = new SurfaceTexture(false); 379918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck mLayer.setSurfaceTexture(mSurface); 3802af3524beb75150d347accc925022daa53b4a789Jamie Gennis } 38152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian mSurface.setDefaultBufferSize(getWidth(), getHeight()); 3822af3524beb75150d347accc925022daa53b4a789Jamie Gennis nCreateNativeWindow(mSurface); 383aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 384c7282e57cd01f1576baac04356bf99bee34e4c18Jeff Brown mSurface.setOnFrameAvailableListener(mUpdateListener, mAttachInfo.mHandler); 385aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 3868a34d6800e70da45bac662873f6951c8d8295a15Jamie Gennis if (mListener != null && !mUpdateSurface) { 387451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mListener.onSurfaceTextureAvailable(mSurface, getWidth(), getHeight()); 388aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 389d15ebf25c595b855f6978d0600218e3ea5f31e92Chet Haase mLayer.setLayerPaint(mLayerPaint); 390aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 391aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 3922af3524beb75150d347accc925022daa53b4a789Jamie Gennis if (mUpdateSurface) { 3932af3524beb75150d347accc925022daa53b4a789Jamie Gennis // Someone has requested that we use a specific SurfaceTexture, so 3942af3524beb75150d347accc925022daa53b4a789Jamie Gennis // tell mLayer about it and set the SurfaceTexture to use the 3952af3524beb75150d347accc925022daa53b4a789Jamie Gennis // current view size. 3962af3524beb75150d347accc925022daa53b4a789Jamie Gennis mUpdateSurface = false; 39751f7c6b3620549429cd6c62e38bace43085e04fbRomain Guy 39851f7c6b3620549429cd6c62e38bace43085e04fbRomain Guy // Since we are updating the layer, force an update to ensure its 39951f7c6b3620549429cd6c62e38bace43085e04fbRomain Guy // parameters are correct (width, height, transform, etc.) 40088801b270f693ffd4125534724f204135f592f72Romain Guy updateLayer(); 40151f7c6b3620549429cd6c62e38bace43085e04fbRomain Guy mMatrixChanged = true; 40251f7c6b3620549429cd6c62e38bace43085e04fbRomain Guy 40304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mLayer.setSurfaceTexture(mSurface); 40452a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian mSurface.setDefaultBufferSize(getWidth(), getHeight()); 4052af3524beb75150d347accc925022daa53b4a789Jamie Gennis } 4062af3524beb75150d347accc925022daa53b4a789Jamie Gennis 407aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy return mLayer; 408aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 409aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 4108f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy @Override 4118f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy protected void onVisibilityChanged(View changedView, int visibility) { 4128f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy super.onVisibilityChanged(changedView, visibility); 4138f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 4148f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (mSurface != null) { 4158f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy // When the view becomes invisible, stop updating it, it's a waste of CPU 4168f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy // To cancel updates, the easiest thing to do is simply to remove the 4178f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy // updates listener 4188f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (visibility == VISIBLE) { 4192dedafb48f85e34a2f48262f12908866fc9de132John Reck if (mLayer != null) { 4202dedafb48f85e34a2f48262f12908866fc9de132John Reck mSurface.setOnFrameAvailableListener(mUpdateListener, mAttachInfo.mHandler); 4212dedafb48f85e34a2f48262f12908866fc9de132John Reck } 42288801b270f693ffd4125534724f204135f592f72Romain Guy updateLayerAndInvalidate(); 4238f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } else { 4248f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mSurface.setOnFrameAvailableListener(null); 4258f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 4268f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 4278f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 4288f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 429a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy private void updateLayer() { 43088801b270f693ffd4125534724f204135f592f72Romain Guy synchronized (mLock) { 43188801b270f693ffd4125534724f204135f592f72Romain Guy mUpdateLayer = true; 43288801b270f693ffd4125534724f204135f592f72Romain Guy } 43388801b270f693ffd4125534724f204135f592f72Romain Guy } 43488801b270f693ffd4125534724f204135f592f72Romain Guy 43588801b270f693ffd4125534724f204135f592f72Romain Guy private void updateLayerAndInvalidate() { 43688801b270f693ffd4125534724f204135f592f72Romain Guy synchronized (mLock) { 43788801b270f693ffd4125534724f204135f592f72Romain Guy mUpdateLayer = true; 43888801b270f693ffd4125534724f204135f592f72Romain Guy } 43958f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy invalidate(); 44058f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy } 4412af3524beb75150d347accc925022daa53b4a789Jamie Gennis 44258f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy private void applyUpdate() { 44358f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy if (mLayer == null) { 444a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy return; 445a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy } 446a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy 44758f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy synchronized (mLock) { 44858f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy if (mUpdateLayer) { 44958f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy mUpdateLayer = false; 45058f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy } else { 45158f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy return; 45258f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy } 45358f4edb7701bf20925468fa5fd1a06a461ff085bRomain Guy } 4545ba09488d600aa4914001ae1dd806fa63d1fec14John Reck 45504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mLayer.prepare(getWidth(), getHeight(), mOpaque); 45604fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck mLayer.updateSurfaceTexture(); 457a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy 458cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba if (mListener != null) { 459cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba mListener.onSurfaceTextureUpdated(mSurface); 460cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba } 461a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy } 462a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy 463aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 464302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * <p>Sets the transform to associate with this texture view. 465302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * The specified transform applies to the underlying surface 466302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * texture and does not affect the size or position of the view 467302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * itself, only of its content.</p> 4685ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 469302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * <p>Some transforms might prevent the content from drawing 470302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * all the pixels contained within this view's bounds. In such 471302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * situations, make sure this texture view is not marked opaque.</p> 4725ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 473302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * @param transform The transform to apply to the content of 474302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * this view. 4755ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 4765ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #getTransform(android.graphics.Matrix) 4775ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #isOpaque() 4785ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #setOpaque(boolean) 479302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy */ 480302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy public void setTransform(Matrix transform) { 481302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy mMatrix.set(transform); 482302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy mMatrixChanged = true; 483c01391fb4eb0eef33d142e89e060eac7e75de39dAlexandre Elias invalidateParentIfNeeded(); 484302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy } 485302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy 486302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy /** 487302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * Returns the transform associated with this texture view. 4885ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 489302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * @param transform The {@link Matrix} in which to copy the current 490302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * transform. Can be null. 4915ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 492302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * @return The specified matrix if not null or a new {@link Matrix} 493302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy * instance otherwise. 4945ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 4955ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #setTransform(android.graphics.Matrix) 496302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy */ 497302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy public Matrix getTransform(Matrix transform) { 498302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy if (transform == null) { 499302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy transform = new Matrix(); 500302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy } 501302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy 502302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy transform.set(mMatrix); 503302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy 504302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy return transform; 505302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy } 506302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy 507c01391fb4eb0eef33d142e89e060eac7e75de39dAlexandre Elias private void applyTransformMatrix() { 50851f7c6b3620549429cd6c62e38bace43085e04fbRomain Guy if (mMatrixChanged && mLayer != null) { 509c01391fb4eb0eef33d142e89e060eac7e75de39dAlexandre Elias mLayer.setTransform(mMatrix); 510c01391fb4eb0eef33d142e89e060eac7e75de39dAlexandre Elias mMatrixChanged = false; 511c01391fb4eb0eef33d142e89e060eac7e75de39dAlexandre Elias } 512c01391fb4eb0eef33d142e89e060eac7e75de39dAlexandre Elias } 513c01391fb4eb0eef33d142e89e060eac7e75de39dAlexandre Elias 514302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy /** 51577a811610f99e21da7f88dafef60d09f345d0506Romain Guy * <p>Returns a {@link android.graphics.Bitmap} representation of the content 51677a811610f99e21da7f88dafef60d09f345d0506Romain Guy * of the associated surface texture. If the surface texture is not available, 51777a811610f99e21da7f88dafef60d09f345d0506Romain Guy * this method returns null.</p> 5185ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 51977a811610f99e21da7f88dafef60d09f345d0506Romain Guy * <p>The bitmap returned by this method uses the {@link Bitmap.Config#ARGB_8888} 52077a811610f99e21da7f88dafef60d09f345d0506Romain Guy * pixel format and its dimensions are the same as this view's.</p> 5215ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 52277a811610f99e21da7f88dafef60d09f345d0506Romain Guy * <p><strong>Do not</strong> invoke this method from a drawing method 52377a811610f99e21da7f88dafef60d09f345d0506Romain Guy * ({@link #onDraw(android.graphics.Canvas)} for instance).</p> 5245ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 525d6b2a00dd43257d1498b09175bff63663f6cb861Romain Guy * <p>If an error occurs during the copy, an empty bitmap will be returned.</p> 5265ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 52777a811610f99e21da7f88dafef60d09f345d0506Romain Guy * @return A valid {@link Bitmap.Config#ARGB_8888} bitmap, or null if the surface 52877a811610f99e21da7f88dafef60d09f345d0506Romain Guy * texture is not available or the width <= 0 or the height <= 0 5295ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 5305ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #isAvailable() 5315ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #getBitmap(android.graphics.Bitmap) 5325ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #getBitmap(int, int) 53377a811610f99e21da7f88dafef60d09f345d0506Romain Guy */ 53477a811610f99e21da7f88dafef60d09f345d0506Romain Guy public Bitmap getBitmap() { 53577a811610f99e21da7f88dafef60d09f345d0506Romain Guy return getBitmap(getWidth(), getHeight()); 53677a811610f99e21da7f88dafef60d09f345d0506Romain Guy } 53777a811610f99e21da7f88dafef60d09f345d0506Romain Guy 53877a811610f99e21da7f88dafef60d09f345d0506Romain Guy /** 53977a811610f99e21da7f88dafef60d09f345d0506Romain Guy * <p>Returns a {@link android.graphics.Bitmap} representation of the content 54077a811610f99e21da7f88dafef60d09f345d0506Romain Guy * of the associated surface texture. If the surface texture is not available, 54177a811610f99e21da7f88dafef60d09f345d0506Romain Guy * this method returns null.</p> 5425ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 54377a811610f99e21da7f88dafef60d09f345d0506Romain Guy * <p>The bitmap returned by this method uses the {@link Bitmap.Config#ARGB_8888} 54477a811610f99e21da7f88dafef60d09f345d0506Romain Guy * pixel format.</p> 5455ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 54677a811610f99e21da7f88dafef60d09f345d0506Romain Guy * <p><strong>Do not</strong> invoke this method from a drawing method 54777a811610f99e21da7f88dafef60d09f345d0506Romain Guy * ({@link #onDraw(android.graphics.Canvas)} for instance).</p> 5485ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 549d6b2a00dd43257d1498b09175bff63663f6cb861Romain Guy * <p>If an error occurs during the copy, an empty bitmap will be returned.</p> 5505ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 55177a811610f99e21da7f88dafef60d09f345d0506Romain Guy * @param width The width of the bitmap to create 55277a811610f99e21da7f88dafef60d09f345d0506Romain Guy * @param height The height of the bitmap to create 5535ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 55477a811610f99e21da7f88dafef60d09f345d0506Romain Guy * @return A valid {@link Bitmap.Config#ARGB_8888} bitmap, or null if the surface 55577a811610f99e21da7f88dafef60d09f345d0506Romain Guy * texture is not available or width is <= 0 or height is <= 0 5565ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 5575ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #isAvailable() 5585ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #getBitmap(android.graphics.Bitmap) 5595ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #getBitmap() 56077a811610f99e21da7f88dafef60d09f345d0506Romain Guy */ 56177a811610f99e21da7f88dafef60d09f345d0506Romain Guy public Bitmap getBitmap(int width, int height) { 56277a811610f99e21da7f88dafef60d09f345d0506Romain Guy if (isAvailable() && width > 0 && height > 0) { 563dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn return getBitmap(Bitmap.createBitmap(getResources().getDisplayMetrics(), 564dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn width, height, Bitmap.Config.ARGB_8888)); 56577a811610f99e21da7f88dafef60d09f345d0506Romain Guy } 56677a811610f99e21da7f88dafef60d09f345d0506Romain Guy return null; 56777a811610f99e21da7f88dafef60d09f345d0506Romain Guy } 56877a811610f99e21da7f88dafef60d09f345d0506Romain Guy 56977a811610f99e21da7f88dafef60d09f345d0506Romain Guy /** 57077a811610f99e21da7f88dafef60d09f345d0506Romain Guy * <p>Copies the content of this view's surface texture into the specified 57177a811610f99e21da7f88dafef60d09f345d0506Romain Guy * bitmap. If the surface texture is not available, the copy is not executed. 57277a811610f99e21da7f88dafef60d09f345d0506Romain Guy * The content of the surface texture will be scaled to fit exactly inside 57377a811610f99e21da7f88dafef60d09f345d0506Romain Guy * the specified bitmap.</p> 5745ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 57577a811610f99e21da7f88dafef60d09f345d0506Romain Guy * <p><strong>Do not</strong> invoke this method from a drawing method 57677a811610f99e21da7f88dafef60d09f345d0506Romain Guy * ({@link #onDraw(android.graphics.Canvas)} for instance).</p> 5775ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 578d6b2a00dd43257d1498b09175bff63663f6cb861Romain Guy * <p>If an error occurs, the bitmap is left unchanged.</p> 5795ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 58077a811610f99e21da7f88dafef60d09f345d0506Romain Guy * @param bitmap The bitmap to copy the content of the surface texture into, 58177a811610f99e21da7f88dafef60d09f345d0506Romain Guy * cannot be null, all configurations are supported 5825ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 58377a811610f99e21da7f88dafef60d09f345d0506Romain Guy * @return The bitmap specified as a parameter 5845ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 5855ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #isAvailable() 5865ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #getBitmap(int, int) 5875ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #getBitmap() 5885ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 589589b0bb6ab81657ba201cbc441a49f85305170bcRomain Guy * @throws IllegalStateException if the hardware rendering context cannot be 590589b0bb6ab81657ba201cbc441a49f85305170bcRomain Guy * acquired to capture the bitmap 59177a811610f99e21da7f88dafef60d09f345d0506Romain Guy */ 59277a811610f99e21da7f88dafef60d09f345d0506Romain Guy public Bitmap getBitmap(Bitmap bitmap) { 59377a811610f99e21da7f88dafef60d09f345d0506Romain Guy if (bitmap != null && isAvailable()) { 594589b0bb6ab81657ba201cbc441a49f85305170bcRomain Guy applyUpdate(); 595589b0bb6ab81657ba201cbc441a49f85305170bcRomain Guy applyTransformMatrix(); 596589b0bb6ab81657ba201cbc441a49f85305170bcRomain Guy 59778245f77d2724ee3a053f13fbcb0359751b9f842Romain Guy // This case can happen if the app invokes setSurfaceTexture() before 59878245f77d2724ee3a053f13fbcb0359751b9f842Romain Guy // we are able to create the hardware layer. We can safely initialize 59978245f77d2724ee3a053f13fbcb0359751b9f842Romain Guy // the layer here thanks to the validate() call at the beginning of 60078245f77d2724ee3a053f13fbcb0359751b9f842Romain Guy // this method 60178245f77d2724ee3a053f13fbcb0359751b9f842Romain Guy if (mLayer == null && mUpdateSurface) { 60278245f77d2724ee3a053f13fbcb0359751b9f842Romain Guy getHardwareLayer(); 60378245f77d2724ee3a053f13fbcb0359751b9f842Romain Guy } 60478245f77d2724ee3a053f13fbcb0359751b9f842Romain Guy 60578245f77d2724ee3a053f13fbcb0359751b9f842Romain Guy if (mLayer != null) { 60678245f77d2724ee3a053f13fbcb0359751b9f842Romain Guy mLayer.copyInto(bitmap); 60778245f77d2724ee3a053f13fbcb0359751b9f842Romain Guy } 60877a811610f99e21da7f88dafef60d09f345d0506Romain Guy } 60977a811610f99e21da7f88dafef60d09f345d0506Romain Guy return bitmap; 61077a811610f99e21da7f88dafef60d09f345d0506Romain Guy } 61177a811610f99e21da7f88dafef60d09f345d0506Romain Guy 61277a811610f99e21da7f88dafef60d09f345d0506Romain Guy /** 61377a811610f99e21da7f88dafef60d09f345d0506Romain Guy * Returns true if the {@link SurfaceTexture} associated with this 61477a811610f99e21da7f88dafef60d09f345d0506Romain Guy * TextureView is available for rendering. When this method returns 61577a811610f99e21da7f88dafef60d09f345d0506Romain Guy * true, {@link #getSurfaceTexture()} returns a valid surface texture. 61677a811610f99e21da7f88dafef60d09f345d0506Romain Guy */ 61777a811610f99e21da7f88dafef60d09f345d0506Romain Guy public boolean isAvailable() { 61877a811610f99e21da7f88dafef60d09f345d0506Romain Guy return mSurface != null; 61977a811610f99e21da7f88dafef60d09f345d0506Romain Guy } 62077a811610f99e21da7f88dafef60d09f345d0506Romain Guy 62177a811610f99e21da7f88dafef60d09f345d0506Romain Guy /** 6226be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * <p>Start editing the pixels in the surface. The returned Canvas can be used 6236be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * to draw into the surface's bitmap. A null is returned if the surface has 6246be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * not been created or otherwise cannot be edited. You will usually need 6256be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * to implement 6266be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * {@link SurfaceTextureListener#onSurfaceTextureAvailable(android.graphics.SurfaceTexture, int, int)} 6276be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * to find out when the Surface is available for use.</p> 6285ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 6296be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * <p>The content of the Surface is never preserved between unlockCanvas() 6306be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * and lockCanvas(), for this reason, every pixel within the Surface area 6316be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * must be written. The only exception to this rule is when a dirty 6326be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * rectangle is specified, in which case, non-dirty pixels will be 6336be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * preserved.</p> 6345ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 635462785fa257671fe4905d1d3e6ca27e4a61ee946Romain Guy * <p>This method can only be used if the underlying surface is not already 636462785fa257671fe4905d1d3e6ca27e4a61ee946Romain Guy * owned by another producer. For instance, if the TextureView is being used 637462785fa257671fe4905d1d3e6ca27e4a61ee946Romain Guy * to render the camera's preview you cannot invoke this method.</p> 6385ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 6396be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * @return A Canvas used to draw into the surface. 6405ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 6415ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #lockCanvas(android.graphics.Rect) 6425ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #unlockCanvasAndPost(android.graphics.Canvas) 6436be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy */ 6446be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy public Canvas lockCanvas() { 6456be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy return lockCanvas(null); 6466be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy } 6476be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy 6486be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy /** 6496be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * Just like {@link #lockCanvas()} but allows specification of a dirty 6506be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * rectangle. Every pixel within that rectangle must be written; however 6516be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * pixels outside the dirty rectangle will be preserved by the next call 6526be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * to lockCanvas(). 65353bacf5a91a760f6c0a966ed2f50a25e7fe12aebRomain Guy * 65453bacf5a91a760f6c0a966ed2f50a25e7fe12aebRomain Guy * This method can return null if the underlying surface texture is not 65553bacf5a91a760f6c0a966ed2f50a25e7fe12aebRomain Guy * available (see {@link #isAvailable()} or if the surface texture is 65653bacf5a91a760f6c0a966ed2f50a25e7fe12aebRomain Guy * already connected to an image producer (for instance: the camera, 65753bacf5a91a760f6c0a966ed2f50a25e7fe12aebRomain Guy * OpenGL, a media player, etc.) 6585ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 6596be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * @param dirty Area of the surface that will be modified. 6606be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy 6616be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * @return A Canvas used to draw into the surface. 6625ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 6635ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #lockCanvas() 66453bacf5a91a760f6c0a966ed2f50a25e7fe12aebRomain Guy * @see #unlockCanvasAndPost(android.graphics.Canvas) 66553bacf5a91a760f6c0a966ed2f50a25e7fe12aebRomain Guy * @see #isAvailable() 6666be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy */ 6676be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy public Canvas lockCanvas(Rect dirty) { 6686be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy if (!isAvailable()) return null; 6696be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy 6706be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy if (mCanvas == null) { 6716be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy mCanvas = new Canvas(); 6726be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy } 6736be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy 6746be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy synchronized (mNativeWindowLock) { 67553bacf5a91a760f6c0a966ed2f50a25e7fe12aebRomain Guy if (!nLockCanvas(mNativeWindow, mCanvas, dirty)) { 67653bacf5a91a760f6c0a966ed2f50a25e7fe12aebRomain Guy return null; 67753bacf5a91a760f6c0a966ed2f50a25e7fe12aebRomain Guy } 6786be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy } 6796be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy mSaveCount = mCanvas.save(); 6806be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy 6816be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy return mCanvas; 6826be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy } 6836be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy 6846be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy /** 6856be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * Finish editing pixels in the surface. After this call, the surface's 6866be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * current pixels will be shown on the screen, but its content is lost, 6876be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * in particular there is no guarantee that the content of the Surface 6886be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * will remain unchanged when lockCanvas() is called again. 6895ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 6906be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * @param canvas The Canvas previously returned by lockCanvas() 6915ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 6926be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy * @see #lockCanvas() 6935ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #lockCanvas(android.graphics.Rect) 6946be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy */ 6956be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy public void unlockCanvasAndPost(Canvas canvas) { 6966be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy if (mCanvas != null && canvas == mCanvas) { 6976be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy canvas.restoreToCount(mSaveCount); 6986be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy mSaveCount = 0; 6996be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy 7006be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy synchronized (mNativeWindowLock) { 7016be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy nUnlockCanvasAndPost(mNativeWindow, mCanvas); 7026be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy } 7036be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy } 7046be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy } 7056be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy 7066be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy /** 707aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Returns the {@link SurfaceTexture} used by this view. This method 70877a811610f99e21da7f88dafef60d09f345d0506Romain Guy * may return null if the view is not attached to a window or if the surface 70977a811610f99e21da7f88dafef60d09f345d0506Romain Guy * texture has not been initialized yet. 7105ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 7115ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #isAvailable() 712aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 713aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy public SurfaceTexture getSurfaceTexture() { 714aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy return mSurface; 715aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 716aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 717aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 7182af3524beb75150d347accc925022daa53b4a789Jamie Gennis * Set the {@link SurfaceTexture} for this view to use. If a {@link 7192af3524beb75150d347accc925022daa53b4a789Jamie Gennis * SurfaceTexture} is already being used by this view, it is immediately 7202af3524beb75150d347accc925022daa53b4a789Jamie Gennis * released and not be usable any more. The {@link 7212af3524beb75150d347accc925022daa53b4a789Jamie Gennis * SurfaceTextureListener#onSurfaceTextureDestroyed} callback is <b>not</b> 7228a34d6800e70da45bac662873f6951c8d8295a15Jamie Gennis * called for the previous {@link SurfaceTexture}. Similarly, the {@link 7238a34d6800e70da45bac662873f6951c8d8295a15Jamie Gennis * SurfaceTextureListener#onSurfaceTextureAvailable} callback is <b>not</b> 7248a34d6800e70da45bac662873f6951c8d8295a15Jamie Gennis * called for the {@link SurfaceTexture} passed to setSurfaceTexture. 7252af3524beb75150d347accc925022daa53b4a789Jamie Gennis * 7262af3524beb75150d347accc925022daa53b4a789Jamie Gennis * The {@link SurfaceTexture} object must be detached from all OpenGL ES 7272af3524beb75150d347accc925022daa53b4a789Jamie Gennis * contexts prior to calling this method. 7282af3524beb75150d347accc925022daa53b4a789Jamie Gennis * 7292af3524beb75150d347accc925022daa53b4a789Jamie Gennis * @param surfaceTexture The {@link SurfaceTexture} that the view should use. 7302af3524beb75150d347accc925022daa53b4a789Jamie Gennis * @see SurfaceTexture#detachFromGLContext() 7312af3524beb75150d347accc925022daa53b4a789Jamie Gennis */ 7322af3524beb75150d347accc925022daa53b4a789Jamie Gennis public void setSurfaceTexture(SurfaceTexture surfaceTexture) { 7332af3524beb75150d347accc925022daa53b4a789Jamie Gennis if (surfaceTexture == null) { 7342af3524beb75150d347accc925022daa53b4a789Jamie Gennis throw new NullPointerException("surfaceTexture must not be null"); 7352af3524beb75150d347accc925022daa53b4a789Jamie Gennis } 7366d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck if (surfaceTexture == mSurface) { 7376d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck throw new IllegalArgumentException("Trying to setSurfaceTexture to " + 7386d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck "the same SurfaceTexture that's already set."); 7396d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck } 7406d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck if (surfaceTexture.isReleased()) { 7416d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck throw new IllegalArgumentException("Cannot setSurfaceTexture to a " + 7426d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck "released SurfaceTexture"); 7436d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck } 7442af3524beb75150d347accc925022daa53b4a789Jamie Gennis if (mSurface != null) { 7452af3524beb75150d347accc925022daa53b4a789Jamie Gennis mSurface.release(); 7462af3524beb75150d347accc925022daa53b4a789Jamie Gennis } 7472af3524beb75150d347accc925022daa53b4a789Jamie Gennis mSurface = surfaceTexture; 748fd69e2a258c76300c47aff703d34281263d2a373Naveen Kalla 7498bc511e4eb2f306350a6710dea5e5ec250fe696cJohn Reck /* 7508bc511e4eb2f306350a6710dea5e5ec250fe696cJohn Reck * If the view is visible and we already made a layer, update the 7518bc511e4eb2f306350a6710dea5e5ec250fe696cJohn Reck * listener in the new surface to use the existing listener in the view. 7528bc511e4eb2f306350a6710dea5e5ec250fe696cJohn Reck * Otherwise this will be called when the view becomes visible or the 7538bc511e4eb2f306350a6710dea5e5ec250fe696cJohn Reck * layer is created 7548bc511e4eb2f306350a6710dea5e5ec250fe696cJohn Reck */ 7558bc511e4eb2f306350a6710dea5e5ec250fe696cJohn Reck if (((mViewFlags & VISIBILITY_MASK) == VISIBLE) && mLayer != null) { 756fd69e2a258c76300c47aff703d34281263d2a373Naveen Kalla mSurface.setOnFrameAvailableListener(mUpdateListener, mAttachInfo.mHandler); 757fd69e2a258c76300c47aff703d34281263d2a373Naveen Kalla } 7582af3524beb75150d347accc925022daa53b4a789Jamie Gennis mUpdateSurface = true; 7592af3524beb75150d347accc925022daa53b4a789Jamie Gennis invalidateParentIfNeeded(); 7602af3524beb75150d347accc925022daa53b4a789Jamie Gennis } 7612af3524beb75150d347accc925022daa53b4a789Jamie Gennis 7622af3524beb75150d347accc925022daa53b4a789Jamie Gennis /** 763aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Returns the {@link SurfaceTextureListener} currently associated with this 764aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * texture view. 7655ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 7665ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener) 767aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @see SurfaceTextureListener 768aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 769aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy public SurfaceTextureListener getSurfaceTextureListener() { 770aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy return mListener; 771aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 772aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 773aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 774aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Sets the {@link SurfaceTextureListener} used to listen to surface 775aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * texture events. 7765ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 7775ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * @see #getSurfaceTextureListener() 778aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @see SurfaceTextureListener 779aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 780aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy public void setSurfaceTextureListener(SurfaceTextureListener listener) { 781aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy mListener = listener; 782aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 783aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 784c7282e57cd01f1576baac04356bf99bee34e4c18Jeff Brown private final SurfaceTexture.OnFrameAvailableListener mUpdateListener = 785c7282e57cd01f1576baac04356bf99bee34e4c18Jeff Brown new SurfaceTexture.OnFrameAvailableListener() { 786c7282e57cd01f1576baac04356bf99bee34e4c18Jeff Brown @Override 787c7282e57cd01f1576baac04356bf99bee34e4c18Jeff Brown public void onFrameAvailable(SurfaceTexture surfaceTexture) { 788c7282e57cd01f1576baac04356bf99bee34e4c18Jeff Brown updateLayer(); 789c7282e57cd01f1576baac04356bf99bee34e4c18Jeff Brown invalidate(); 790c7282e57cd01f1576baac04356bf99bee34e4c18Jeff Brown } 791c7282e57cd01f1576baac04356bf99bee34e4c18Jeff Brown }; 792c7282e57cd01f1576baac04356bf99bee34e4c18Jeff Brown 793aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 794aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * This listener can be used to be notified when the surface texture 795aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * associated with this texture view is available. 796aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 797aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy public static interface SurfaceTextureListener { 798aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 799aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Invoked when a {@link TextureView}'s SurfaceTexture is ready for use. 8005ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 801aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @param surface The surface returned by 802aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * {@link android.view.TextureView#getSurfaceTexture()} 803451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy * @param width The width of the surface 804451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy * @param height The height of the surface 805aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 806451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height); 8078f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 8088f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy /** 8098f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * Invoked when the {@link SurfaceTexture}'s buffers size changed. 8105ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 8118f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * @param surface The surface returned by 8128f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * {@link android.view.TextureView#getSurfaceTexture()} 8138f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * @param width The new width of the surface 8148f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * @param height The new height of the surface 8158f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy */ 8168f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height); 817451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy 818451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy /** 819451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy * Invoked when the specified {@link SurfaceTexture} is about to be destroyed. 820402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba * If returns true, no rendering should happen inside the surface texture after this method 821402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba * is invoked. If returns false, the client needs to call {@link SurfaceTexture#release()}. 82252b307ebc86e12e368694442eb8751e7e0de239eRomain Guy * Most applications should return true. 8235ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 824451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy * @param surface The surface about to be destroyed 825451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy */ 826402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba public boolean onSurfaceTextureDestroyed(SurfaceTexture surface); 827cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba 828cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba /** 829cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba * Invoked when the specified {@link SurfaceTexture} is updated through 830cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba * {@link SurfaceTexture#updateTexImage()}. 8315ba09488d600aa4914001ae1dd806fa63d1fec14John Reck * 832cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba * @param surface The surface just updated 833cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba */ 834cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba public void onSurfaceTextureUpdated(SurfaceTexture surface); 835aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 8368f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 8376be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy private native void nCreateNativeWindow(SurfaceTexture surface); 8386be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy private native void nDestroyNativeWindow(); 8396be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy 84036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat private static native boolean nLockCanvas(long nativeWindow, Canvas canvas, Rect dirty); 84136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat private static native void nUnlockCanvasAndPost(long nativeWindow, Canvas canvas); 842aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy} 843