Merge "Add onSurfaceTextureDestroyed() callback."
This commit is contained in:
@@ -56,14 +56,7 @@ import android.util.Log;
|
||||
* setContentView(mTextureView);
|
||||
* }
|
||||
*
|
||||
* protected void onDestroy() {
|
||||
* super.onDestroy();
|
||||
*
|
||||
* mCamera.stopPreview();
|
||||
* mCamera.release();
|
||||
* }
|
||||
*
|
||||
* public void onSurfaceTextureAvailable(SurfaceTexture surface) {
|
||||
* public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
||||
* mCamera = Camera.open();
|
||||
*
|
||||
* try {
|
||||
@@ -77,6 +70,11 @@ import android.util.Log;
|
||||
* public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
|
||||
* // Ignored, Camera does all the work for us
|
||||
* }
|
||||
*
|
||||
* public void onSurfaceTextureDestroyed(SurfaceTexture surface) {
|
||||
* mCamera.stopPreview();
|
||||
* mCamera.release();
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
@@ -155,6 +153,21 @@ public class TextureView extends View {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
|
||||
if (isHardwareAccelerated() && mLayer != null) {
|
||||
if (mListener != null) {
|
||||
mListener.onSurfaceTextureDestroyed(mSurface);
|
||||
}
|
||||
|
||||
mLayer.destroy();
|
||||
mSurface = null;
|
||||
mLayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The layer type of a TextureView is ignored since a TextureView is always
|
||||
* considered to act as a hardware layer. The optional paint supplied to this
|
||||
@@ -217,6 +230,9 @@ public class TextureView extends View {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (mSurface != null) {
|
||||
nSetDefaultBufferSize(mSurface.mSurfaceTexture, getWidth(), getHeight());
|
||||
if (mListener != null) {
|
||||
mListener.onSurfaceTextureSizeChanged(mSurface, getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +258,7 @@ public class TextureView extends View {
|
||||
mSurface.setOnFrameAvailableListener(mUpdateListener);
|
||||
|
||||
if (mListener != null) {
|
||||
mListener.onSurfaceTextureAvailable(mSurface);
|
||||
mListener.onSurfaceTextureAvailable(mSurface, getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,8 +332,10 @@ public class TextureView extends View {
|
||||
*
|
||||
* @param surface The surface returned by
|
||||
* {@link android.view.TextureView#getSurfaceTexture()}
|
||||
* @param width The width of the surface
|
||||
* @param height The height of the surface
|
||||
*/
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface);
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height);
|
||||
|
||||
/**
|
||||
* Invoked when the {@link SurfaceTexture}'s buffers size changed.
|
||||
@@ -328,6 +346,15 @@ public class TextureView extends View {
|
||||
* @param height The new height of the surface
|
||||
*/
|
||||
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height);
|
||||
|
||||
/**
|
||||
* Invoked when the specified {@link SurfaceTexture} is about to be destroyed.
|
||||
* After this method is invoked, no rendering should happen inside the surface
|
||||
* texture.
|
||||
*
|
||||
* @param surface The surface about to be destroyed
|
||||
*/
|
||||
public void onSurfaceTextureDestroyed(SurfaceTexture surface);
|
||||
}
|
||||
|
||||
private static native void nSetDefaultBufferSize(int surfaceTexture, int width, int height);
|
||||
|
||||
@@ -52,13 +52,7 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mRenderThread.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface) {
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
||||
mRenderThread = new RenderThread(surface);
|
||||
mRenderThread.start();
|
||||
|
||||
@@ -81,6 +75,16 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
|
||||
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureDestroyed(SurfaceTexture surface) {
|
||||
mRenderThread.finish();
|
||||
try {
|
||||
mRenderThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(RenderThread.LOG_TAG, "Could not wait for render thread");
|
||||
}
|
||||
}
|
||||
|
||||
private static class RenderThread extends Thread {
|
||||
private static final String LOG_TAG = "GLTextureView";
|
||||
|
||||
@@ -108,26 +112,23 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
|
||||
public void run() {
|
||||
initGL();
|
||||
|
||||
float red = 0.0f;
|
||||
float red = 1.0f;
|
||||
while (!mFinished) {
|
||||
checkCurrent();
|
||||
|
||||
Log.d(LOG_TAG, "Rendering frame");
|
||||
|
||||
GLES20.glClearColor(red, 0.0f, 0.0f, 1.0f);
|
||||
int error = GLES20.glGetError();
|
||||
if (error != GLES20.GL_NO_ERROR) {
|
||||
Log.w(LOG_TAG, "GL error = 0x" + Integer.toHexString(error));
|
||||
}
|
||||
checkGlError();
|
||||
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
||||
error = GLES20.glGetError();
|
||||
if (error != GLES20.GL_NO_ERROR) {
|
||||
Log.w(LOG_TAG, "GL error = 0x" + Integer.toHexString(error));
|
||||
}
|
||||
checkGlError();
|
||||
|
||||
if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
|
||||
throw new RuntimeException("Cannot swap buffers");
|
||||
}
|
||||
|
||||
checkEglError();
|
||||
|
||||
try {
|
||||
Thread.sleep(20);
|
||||
} catch (InterruptedException e) {
|
||||
@@ -141,6 +142,20 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
|
||||
finishGL();
|
||||
}
|
||||
|
||||
private void checkEglError() {
|
||||
int error = mEgl.eglGetError();
|
||||
if (error != EGL10.EGL_SUCCESS) {
|
||||
Log.w(LOG_TAG, "EGL error = 0x" + Integer.toHexString(error));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkGlError() {
|
||||
int error = GLES20.glGetError();
|
||||
if (error != GLES20.GL_NO_ERROR) {
|
||||
Log.w(LOG_TAG, "GL error = 0x" + Integer.toHexString(error));
|
||||
}
|
||||
}
|
||||
|
||||
private void finishGL() {
|
||||
mEgl.eglDestroyContext(mEglDisplay, mEglContext);
|
||||
mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.test.hwui;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.Activity;
|
||||
@@ -25,6 +26,7 @@ import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.TextureView;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -33,27 +35,44 @@ import java.io.IOException;
|
||||
public class TextureViewActivity extends Activity implements TextureView.SurfaceTextureListener {
|
||||
private Camera mCamera;
|
||||
private TextureView mTextureView;
|
||||
private FrameLayout mContent;
|
||||
private AnimatorSet mAnimatorSet;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mContent = new FrameLayout(this);
|
||||
|
||||
mTextureView = new TextureView(this);
|
||||
mTextureView.setSurfaceTextureListener(this);
|
||||
|
||||
setContentView(mTextureView, new FrameLayout.LayoutParams(500, 400, Gravity.CENTER));
|
||||
Button button = new Button(this);
|
||||
button.setText("Remove/Add");
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
private boolean mAdded = true;
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mAdded) {
|
||||
mAnimatorSet.cancel();
|
||||
mContent.removeView(mTextureView);
|
||||
} else {
|
||||
mContent.addView(mTextureView);
|
||||
}
|
||||
mAdded = !mAdded;
|
||||
}
|
||||
});
|
||||
|
||||
mContent.addView(mTextureView, new FrameLayout.LayoutParams(500, 400, Gravity.CENTER));
|
||||
mContent.addView(button, new FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||
Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM));
|
||||
setContentView(mContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
mCamera.stopPreview();
|
||||
mCamera.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface) {
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
||||
mCamera = Camera.open();
|
||||
|
||||
try {
|
||||
@@ -66,27 +85,35 @@ public class TextureViewActivity extends Activity implements TextureView.Surface
|
||||
|
||||
mTextureView.setCameraDistance(5000);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofFloat(mTextureView, "rotationY", 0.0f, 360.0f);
|
||||
animator.setRepeatMode(ObjectAnimator.REVERSE);
|
||||
animator.setRepeatCount(ObjectAnimator.INFINITE);
|
||||
animator.setDuration(4000);
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
ObjectAnimator rotationY = ObjectAnimator.ofFloat(mTextureView, "rotationY", 0.0f, 360.0f);
|
||||
rotationY.setRepeatMode(ObjectAnimator.REVERSE);
|
||||
rotationY.setRepeatCount(ObjectAnimator.INFINITE);
|
||||
rotationY.setDuration(4000);
|
||||
rotationY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
((View) mTextureView.getParent()).invalidate();
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
|
||||
animator = ObjectAnimator.ofFloat(mTextureView, "alpha", 1.0f, 0.0f);
|
||||
animator.setRepeatMode(ObjectAnimator.REVERSE);
|
||||
animator.setRepeatCount(ObjectAnimator.INFINITE);
|
||||
animator.setDuration(4000);
|
||||
animator.start();
|
||||
ObjectAnimator alpha = ObjectAnimator.ofFloat(mTextureView, "alpha", 1.0f, 0.0f);
|
||||
alpha.setRepeatMode(ObjectAnimator.REVERSE);
|
||||
alpha.setRepeatCount(ObjectAnimator.INFINITE);
|
||||
alpha.setDuration(4000);
|
||||
|
||||
mAnimatorSet = new AnimatorSet();
|
||||
mAnimatorSet.play(alpha).with(rotationY);
|
||||
mAnimatorSet.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
|
||||
// Ignored, the Camera does all the work for us
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureDestroyed(SurfaceTexture surface) {
|
||||
mCamera.stopPreview();
|
||||
mCamera.release();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user