Reduce the number of UI events required to update a SurfaceTexture.
Change-Id: I9330c9646654fff57dcd6817c86e587a6490a9ad
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index ab4aed3..0c0cd76 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -78,7 +78,7 @@
* }
*
* public void onSurfaceTextureUpdated(SurfaceTexture surface) {
- * // Ignored
+ * // Invoked every time there's a new Camera preview frame
* }
* }
* </pre>
@@ -102,12 +102,9 @@
private boolean mOpaque = true;
- 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;
/**
@@ -170,7 +167,7 @@
public void setOpaque(boolean opaque) {
if (opaque != mOpaque) {
mOpaque = opaque;
- if (mLayer != null) updateLayer();
+ updateLayer();
}
}
@@ -243,6 +240,7 @@
*/
@Override
public final void draw(Canvas canvas) {
+ applyUpdate();
}
/**
@@ -268,11 +266,11 @@
@Override
HardwareLayer getHardwareLayer() {
- if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) {
- return null;
- }
-
if (mLayer == null) {
+ if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) {
+ return null;
+ }
+
mLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(mOpaque);
mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
@@ -282,7 +280,10 @@
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
// Per SurfaceTexture's documentation, the callback may be invoked
// from an arbitrary thread
- post(mUpdateLayerAction);
+ synchronized (mLock) {
+ mUpdateLayer = true;
+ }
+ postInvalidateDelayed(0);
}
};
mSurface.setOnFrameAvailableListener(mUpdateListener);
@@ -292,6 +293,8 @@
}
}
+ applyUpdate();
+
return mLayer;
}
@@ -313,17 +316,28 @@
}
private void updateLayer() {
- if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) {
+ mUpdateLayer = true;
+ invalidate();
+ }
+
+ private void applyUpdate() {
+ if (mLayer == null) {
return;
}
+ synchronized (mLock) {
+ if (mUpdateLayer) {
+ mUpdateLayer = false;
+ } else {
+ return;
+ }
+ }
+
mLayer.update(getWidth(), getHeight(), mOpaque);
if (mListener != null) {
mListener.onSurfaceTextureUpdated(mSurface);
}
-
- invalidate();
}
/**