diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index 042120587dea5..2f598f46b756d 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -96,12 +96,9 @@ public class TextureView extends View { private SurfaceTexture mSurface; private SurfaceTextureListener mListener; - private final Runnable mUpdateLayerAction = new Runnable() { - @Override - public void run() { - updateLayer(); - } - }; + private final Object[] mLock = new Object[0]; + private boolean mUpdateLayer; + private SurfaceTexture.OnFrameAvailableListener mUpdateListener; /** @@ -232,6 +229,8 @@ public class TextureView extends View { protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (mSurface != null) { + // No need to synchronize here, we set update layer to false only on the UI thread + mUpdateLayer = true; nSetDefaultBufferSize(mSurface, getWidth(), getHeight()); if (mListener != null) { mListener.onSurfaceTextureSizeChanged(mSurface, getWidth(), getHeight()); @@ -255,7 +254,10 @@ public class TextureView extends View { public void onFrameAvailable(SurfaceTexture surfaceTexture) { // Per SurfaceTexture's documentation, the callback may be invoked // from an arbitrary thread - post(mUpdateLayerAction); + synchronized (mLock) { + mUpdateLayer = true; + postInvalidate(); + } } }; mSurface.setOnFrameAvailableListener(mUpdateListener); @@ -265,6 +267,13 @@ public class TextureView extends View { } } + synchronized (mLock) { + if (mUpdateLayer) { + mAttachInfo.mHardwareRenderer.updateTextureLayer(mLayer, getWidth(), getHeight()); + mUpdateLayer = false; + } + } + return mLayer; } @@ -278,23 +287,15 @@ public class TextureView extends View { // updates listener if (visibility == VISIBLE) { mSurface.setOnFrameAvailableListener(mUpdateListener); - updateLayer(); + // No need to synchronize here, we set update layer to false only on the UI thread + mUpdateLayer = true; + invalidate(); } else { mSurface.setOnFrameAvailableListener(null); } } } - private void updateLayer() { - if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) { - return; - } - - mAttachInfo.mHardwareRenderer.updateTextureLayer(mLayer, getWidth(), getHeight()); - - invalidate(); - } - /** *

Returns a {@link android.graphics.Bitmap} representation of the content * of the associated surface texture. If the surface texture is not available, diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 22d3c6f444941..16992997cbf5c 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -649,8 +649,9 @@ static void android_view_GLES20Canvas_updateTextureLayer(JNIEnv* env, jobject cl float transform[16]; sp surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface)); - while (surfaceTexture->getQueuedCount() > 0) + while (surfaceTexture->getQueuedCount() > 0) { surfaceTexture->updateTexImage(); + } surfaceTexture->getTransformMatrix(transform); GLenum renderTarget = surfaceTexture->getCurrentTextureTarget();