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

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

Merge "Notify views when EGL resources are about to be destroyed Bug #5639899" into ics-mr1

parents fb0784da 31f2c2e9
Loading
Loading
Loading
Loading
+51 −22
Original line number Diff line number Diff line
@@ -162,12 +162,20 @@ public abstract class HardwareRenderer {
    abstract void updateSurface(SurfaceHolder holder) throws Surface.OutOfResourcesException;

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

    /**
     * Destroys all hardware rendering resources associated with the specified
     * view hierarchy.
     * 
     * @param view The root of the view hierarchy
     */
    abstract void destroyHardwareResources(View view);
    
    /**
     * This method should be invoked whenever the current hardware renderer
     * context should be reset.
@@ -347,15 +355,6 @@ public abstract class HardwareRenderer {
        Gl20Renderer.trimMemory(level);
    }

    /**
     * Invoke this method when the system needs to clean up all resources
     * associated with hardware rendering.
     */
    static void terminate() {
        Log.d(LOG_TAG, "Terminating hardware rendering");
        Gl20Renderer.terminate();
    }    
    
    /**
     * Indicates whether hardware acceleration is currently enabled.
     * 
@@ -412,8 +411,8 @@ public abstract class HardwareRenderer {
        static final Object[] sEglLock = new Object[0];
        int mWidth = -1, mHeight = -1;

        static final ThreadLocal<Gl20Renderer.MyEGLContext> sEglContextStorage
                = new ThreadLocal<Gl20Renderer.MyEGLContext>();
        static final ThreadLocal<Gl20Renderer.Gl20RendererEglContext> sEglContextStorage
                = new ThreadLocal<Gl20Renderer.Gl20RendererEglContext>();

        EGLContext mEglContext;
        Thread mEglThread;
@@ -565,13 +564,13 @@ public abstract class HardwareRenderer {
                }
            }

            Gl20Renderer.MyEGLContext managedContext = sEglContextStorage.get();
            Gl20Renderer.Gl20RendererEglContext managedContext = sEglContextStorage.get();
            mEglContext = managedContext != null ? managedContext.getContext() : null;
            mEglThread = Thread.currentThread();

            if (mEglContext == null) {
                mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
                sEglContextStorage.set(new Gl20Renderer.MyEGLContext(mEglContext));
                sEglContextStorage.set(new Gl20Renderer.Gl20RendererEglContext(mEglContext));
            }
        }

@@ -909,10 +908,10 @@ public abstract class HardwareRenderer {
        private static EGLSurface sPbuffer;
        private static final Object[] sPbufferLock = new Object[0];

        static class MyEGLContext extends ManagedEGLContext {
        static class Gl20RendererEglContext extends ManagedEGLContext {
            final Handler mHandler = new Handler();

            public MyEGLContext(EGLContext context) {
            public Gl20RendererEglContext(EGLContext context) {
                super(context);
            }

@@ -939,7 +938,8 @@ public abstract class HardwareRenderer {
                        sEglContextStorage.remove();

                        sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
                        sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
                        sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
                                EGL_NO_SURFACE, EGL_NO_CONTEXT);

                        sEgl.eglReleaseThread();
                        sEgl.eglTerminate(sEglDisplay);
@@ -1046,10 +1046,9 @@ public abstract class HardwareRenderer {
            }
        }

        private void destroyHardwareLayer(View view) {
            if (view.destroyLayer()) {
                view.invalidate(true);
            }
        private static void destroyHardwareLayer(View view) {
            view.destroyLayer();

            if (view instanceof ViewGroup) {
                ViewGroup group = (ViewGroup) view;

@@ -1060,6 +1059,36 @@ public abstract class HardwareRenderer {
            }
        }
        
        @Override
        void destroyHardwareResources(View view) {
            if (view != null) {
                boolean needsContext = true;
                if (isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) needsContext = false;

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

                destroyResources(view);
                GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
            }
        }
        
        private static void destroyResources(View view) {
            view.destroyHardwareResources();

            if (view instanceof ViewGroup) {
                ViewGroup group = (ViewGroup) view;

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

        static HardwareRenderer create(boolean translucent) {
            if (GLES20Canvas.isAvailable()) {
                return new Gl20Renderer(translucent);
@@ -1070,7 +1099,7 @@ public abstract class HardwareRenderer {
        static void trimMemory(int level) {
            if (sEgl == null || sEglConfig == null) return;

            Gl20Renderer.MyEGLContext managedContext = sEglContextStorage.get();
            Gl20RendererEglContext managedContext = sEglContextStorage.get();
            // We do not have OpenGL objects
            if (managedContext == null) {
                return;
+11 −0
Original line number Diff line number Diff line
@@ -203,7 +203,10 @@ public class TextureView extends View {
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        destroySurface();
    }

    private void destroySurface() {
        if (mLayer != null) {
            boolean shouldRelease = true;
            if (mListener != null) {
@@ -300,6 +303,14 @@ public class TextureView extends View {
        return false;
    }

    @Override
    protected void destroyHardwareResources() {
        super.destroyHardwareResources();
        destroySurface();
        invalidateParentCaches();
        invalidate(true);
    }

    @Override
    HardwareLayer getHardwareLayer() {
        if (mLayer == null) {
+20 −1
Original line number Diff line number Diff line
@@ -10073,7 +10073,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        switch (mLayerType) {
            case LAYER_TYPE_HARDWARE:
                destroyLayer();
                // fall through - unaccelerated views may use software layer mechanism instead
                // fall through - non-accelerated views may use software layer mechanism instead
            case LAYER_TYPE_SOFTWARE:
                destroyDrawingCache();
                break;
@@ -10235,11 +10235,30 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        if (mHardwareLayer != null) {
            mHardwareLayer.destroy();
            mHardwareLayer = null;
            invalidate(true);
            invalidateParentCaches();
            return true;
        }
        return false;
    }
    /**
     * Destroys all hardware rendering resources. This method is invoked
     * when the system needs to reclaim resources. Upon execution of this
     * method, you should free any OpenGL resources created by the view.
     * 
     * Note: you <strong>must</strong> call
     * <code>super.destroyHardwareResources()</code> when overriding
     * this method.
     * 
     * @hide
     */
    protected void destroyHardwareResources() {
        destroyLayer();
    }
    /**
     * <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
+7 −0
Original line number Diff line number Diff line
@@ -576,6 +576,13 @@ public final class ViewRootImpl extends Handler implements ViewParent,
        }
    }

    void terminateHardwareResources() {
        if (mAttachInfo.mHardwareRenderer != null) {
            mAttachInfo.mHardwareRenderer.destroyHardwareResources(mView);
            mAttachInfo.mHardwareRenderer.destroy(false);
        }
    }

    void destroyHardwareLayers() {
        if (mThread != Thread.currentThread()) {
            if (mAttachInfo.mHardwareRenderer != null &&
+1 −1
Original line number Diff line number Diff line
@@ -425,7 +425,7 @@ public class WindowManagerImpl implements WindowManager {
                            if (mViews == null) return;
                            int count = mViews.length;
                            for (int i = 0; i < count; i++) {
                                mRoots[i].destroyHardwareResources();
                                mRoots[i].terminateHardwareResources();
                            }
                        }
                        // Terminate the hardware renderer to free all resources
Loading