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

Commit 6d7475d6 authored by Romain Guy's avatar Romain Guy
Browse files

Destroy layers and flush layers cache when a window is destroyed.

Change-Id: I3fa1bc3ff50fb99e3d2e490925bd6b0a0f809fff
parent eea60692
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -277,14 +277,25 @@ class GLES20Canvas extends HardwareCanvas {
    ///////////////////////////////////////////////////////////////////////////

    /**
     * Must match Caches::FlushMode values
     * 
     * @see #flushCaches(int) 
     */
    public static final int FLUSH_CACHES_MODERATE = 0;
    public static final int FLUSH_CACHES_LAYERS = 0;
    
    /**
     * Must match Caches::FlushMode values
     * 
     * @see #flushCaches(int) 
     */
    public static final int FLUSH_CACHES_MODERATE = 1;

    /**
     * Must match Caches::FlushMode values
     * 
     * @see #flushCaches(int) 
     */
    public static final int FLUSH_CACHES_FULL = 1;
    public static final int FLUSH_CACHES_FULL = 2;

    /**
     * Flush caches to reclaim as much memory as possible. The amount of memory
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ import android.util.Pools;
class GLES20RecordingCanvas extends GLES20Canvas implements Poolable<GLES20RecordingCanvas> {
    // The recording canvas pool should be large enough to handle a deeply nested
    // view hierarchy because display lists are generated recursively.
    private static final int POOL_LIMIT = 50;
    private static final int POOL_LIMIT = 25;

    private static final Pool<GLES20RecordingCanvas> sPool = Pools.synchronizedPool(
            Pools.finitePool(new PoolableManager<GLES20RecordingCanvas>() {
+46 −22
Original line number Diff line number Diff line
@@ -139,6 +139,13 @@ public abstract class HardwareRenderer {
     */
    abstract void updateSurface(SurfaceHolder holder) throws Surface.OutOfResourcesException;

    /**
     * Destoys the layers used by the specified view hierarchy.
     * 
     * @param view The root of the view hierarchy
     */
    abstract void destroyLayers(View view);

    /**
     * This method should be invoked whenever the current hardware renderer
     * context should be reset. 
@@ -622,18 +629,8 @@ public abstract class HardwareRenderer {
                        + "from multiple threads");
            }

            /*
             *  The window size has changed, so we need to create a new
             *  surface.
             */
            if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
                /*
                 * Unbind and destroy the old EGL surface, if
                 * there is one.
                 */
                sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
                sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
            }
            // In case we need to destroy an existing surface
            destroySurface();

            // Create an EGL surface we can render into.
            mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, holder, null);
@@ -693,15 +690,21 @@ public abstract class HardwareRenderer {

            mDestroyed = true;

            sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
            sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
            destroySurface();

            mEglSurface = null;
            mGl = null;

            setEnabled(false);
        }

        void destroySurface() {
            if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
                sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
                sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
                mEglSurface = null;
            }
        }

        @Override
        void invalidate() {
            // Cancels any existing buffer to ensure we'll get a buffer
@@ -921,6 +924,34 @@ public abstract class HardwareRenderer {
            return ((GLES20TextureLayer) layer).getSurfaceTexture();
        }

        @Override
        void destroyLayers(View view) {
            if (view != null && isEnabled()) {
                checkCurrent();
                destroyHardwareLayer(view);
                GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
            }
        }

        private void destroyHardwareLayer(View view) {
            view.destroyLayer();
            if (view instanceof ViewGroup) {
                ViewGroup group = (ViewGroup) view;

                int count = group.getChildCount();
                for (int i = 0; i < count; i++) {
                    destroyHardwareLayer(group.getChildAt(i));
                }
            }
        }

        static HardwareRenderer create(boolean translucent) {
            if (GLES20Canvas.isAvailable()) {
                return new Gl20Renderer(translucent);
            }
            return null;
        }

        static void trimMemory(int level) {
            if (sEgl == null || sEglConfig == null) return;

@@ -950,12 +981,5 @@ public abstract class HardwareRenderer {
                    break;
            }
        }

        static HardwareRenderer create(boolean translucent) {
            if (GLES20Canvas.isAvailable()) {
                return new Gl20Renderer(translucent);
            }
            return null;
        }
    }
}
+10 −17
Original line number Diff line number Diff line
@@ -9226,10 +9226,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit

        destroyDrawingCache();

        if (mHardwareLayer != null) {
            mHardwareLayer.destroy();
            mHardwareLayer = null;
        }
        destroyLayer();

        if (mDisplayList != null) {
            mDisplayList.invalidate();
@@ -9601,21 +9598,10 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
        // Destroy any previous software drawing cache if needed
        switch (mLayerType) {
            case LAYER_TYPE_HARDWARE:
                if (mHardwareLayer != null) {
                    mHardwareLayer.destroy();
                    mHardwareLayer = null;
                }
                destroyLayer();
                // fall through - unaccelerated views may use software layer mechanism instead
            case LAYER_TYPE_SOFTWARE:
                if (mDrawingCache != null) {
                    mDrawingCache.recycle();
                    mDrawingCache = null;
                }

                if (mUnscaledDrawingCache != null) {
                    mUnscaledDrawingCache.recycle();
                    mUnscaledDrawingCache = null;
                }
                destroyDrawingCache();
                break;
            default:
                break;
@@ -9741,6 +9727,13 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
        return mHardwareLayer;
    }

    void destroyLayer() {
        if (mHardwareLayer != null) {
            mHardwareLayer.destroy();
            mHardwareLayer = null;
        }
    }

    /**
     * <p>Enables or disables the drawing cache. When the drawing cache is enabled, the next call
     * to {@link #getDrawingCache()} or {@link #buildDrawingCache()} will draw the view in a
+8 −1
Original line number Diff line number Diff line
@@ -541,6 +541,13 @@ public final class ViewRootImpl extends Handler implements ViewParent,
        }
    }

    private void destroyHardwareResources() {
        if (mAttachInfo.mHardwareRenderer.isEnabled()) {
            mAttachInfo.mHardwareRenderer.destroyLayers(mView);
        }
        mAttachInfo.mHardwareRenderer.destroy(false);
    }

    private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
        mAttachInfo.mHardwareAccelerated = false;
        mAttachInfo.mHardwareAccelerationRequested = false;
@@ -870,7 +877,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
            host.dispatchWindowVisibilityChanged(viewVisibility);
            if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) {
                if (mAttachInfo.mHardwareRenderer != null) {
                    mAttachInfo.mHardwareRenderer.destroy(false);
                    destroyHardwareResources();
                }                
            }
            if (viewVisibility == View.GONE) {
Loading