Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0e9e429 authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Add onSurfaceTextureDestroyed() callback."

parents 40b62b9e 451ce44a
Loading
Loading
Loading
Loading
+37 −10
Original line number Diff line number Diff line
@@ -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);
+32 −17
Original line number Diff line number Diff line
@@ -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,25 +112,22 @@ 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);
@@ -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);
+46 −19
Original line number Diff line number Diff line
@@ -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
    protected void onDestroy() {
        super.onDestroy();
            public void onClick(View v) {
                if (mAdded) {
                    mAnimatorSet.cancel();
                    mContent.removeView(mTextureView);
                } else {
                    mContent.addView(mTextureView);
                }
                mAdded = !mAdded;
            }
        });

        mCamera.stopPreview();
        mCamera.release();
        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
    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();
    }
}