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

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

Merge "Fix SurfaceTexture leak in TextureView Bug #6318631"

parents d4fed38d 1ac4765e
Loading
Loading
Loading
Loading
+39 −14
Original line number Diff line number Diff line
@@ -236,6 +236,17 @@ public abstract class HardwareRenderer {
     */
    abstract boolean validate();

    /**
     * This method ensures the hardware renderer is in a valid state
     * before executing the specified action.
     * 
     * This method will attempt to set a valid state even if the window
     * the renderer is attached to was destroyed.
     *
     * @return true if the action was run
     */
    abstract boolean safelyRun(Runnable action);

    /**
     * Setup the hardware renderer for drawing. This is called whenever the
     * size of the target surface changes or when the surface is first created.
@@ -1380,26 +1391,40 @@ public abstract class HardwareRenderer {
        }

        @Override
        void destroyHardwareResources(View view) {
            if (view != null) {
        boolean safelyRun(Runnable action) {
            boolean needsContext = true;
            if (isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) needsContext = false;

            if (needsContext) {
                Gl20RendererEglContext managedContext =
                        (Gl20RendererEglContext) sEglContextStorage.get();
                    if (managedContext == null) return;
                if (managedContext == null) return false;
                usePbufferSurface(managedContext.getContext());
            }

                destroyResources(view);
                GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);

            try {
                action.run();
            } finally {
                if (needsContext) {
                    sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
                            EGL_NO_SURFACE, EGL_NO_CONTEXT);
                }
            }

            return true;
        }

        @Override
        void destroyHardwareResources(final View view) {
            if (view != null) {
                safelyRun(new Runnable() {
                    @Override
                    public void run() {
                        destroyResources(view);
                        GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
                    }
                });
            }
        }

        private static void destroyResources(View view) {
+12 −1
Original line number Diff line number Diff line
@@ -204,8 +204,19 @@ public class TextureView extends View {
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mLayer != null && mAttachInfo != null && mAttachInfo.mHardwareRenderer != null) {
            boolean success = mAttachInfo.mHardwareRenderer.safelyRun(new Runnable() {
                @Override
                public void run() {
                    destroySurface();
                }
            });

            if (!success) {
                Log.w(LOG_TAG, "TextureView was not able to destroy its surface: " + this);
            }
        }
    }

    private void destroySurface() {
        if (mLayer != null) {