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

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

Merge "Terminate EGL when an app goes in the background" into ics-mr1

parents de62d9cb 8ff6b9eb
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -315,6 +315,27 @@ class GLES20Canvas extends HardwareCanvas {

    private static native void nFlushCaches(int level);

    /**
     * Release all resources associated with the underlying caches. This should
     * only be called after a full flushCaches().
     * 
     * @hide
     */
    public static void terminateCaches() {
        nTerminateCaches();
    }

    private static native void nTerminateCaches();

    /**
     * @hide
     */
    public static void initCaches() {
        nInitCaches();
    }

    private static native void nInitCaches();
    
    ///////////////////////////////////////////////////////////////////////////
    // Display list
    ///////////////////////////////////////////////////////////////////////////
+61 −10
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.opengl.GLUtils;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.Log;
import com.google.android.gles_jni.EGLImpl;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
@@ -343,6 +344,15 @@ 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.
     * 
@@ -652,6 +662,8 @@ public abstract class HardwareRenderer {
                        + GLUtils.getEGLErrorString(sEgl.eglGetError()));
            }
            
            initCaches();

            // If mDirtyRegions is set, this means we have an EGL configuration
            // with EGL_SWAP_BEHAVIOR_PRESERVED_BIT set
            if (sDirtyRegions) {
@@ -671,6 +683,8 @@ public abstract class HardwareRenderer {
            return mEglContext.getGL();
        }

        abstract void initCaches();

        EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
            int[] attribs = { EGL_CONTEXT_CLIENT_VERSION, mGlVersion, EGL_NONE };

@@ -915,6 +929,11 @@ public abstract class HardwareRenderer {
            };
        }
        
        @Override
        void initCaches() {
            GLES20Canvas.initCaches();
        }

        @Override
        boolean canDraw() {
            return super.canDraw() && mGlCanvas != null;
@@ -1006,6 +1025,22 @@ public abstract class HardwareRenderer {
            if (eglContext == null) {
                return;
            } else {
                usePbufferSurface(eglContext);
            }

            switch (level) {
                case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
                case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
                case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
                    GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
                    break;
                case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
                    GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
                    break;
            }
        }

        private static void usePbufferSurface(EGLContext eglContext) {
            synchronized (sPbufferLock) {
                // Create a temporary 1x1 pbuffer so we have a context
                // to clear our OpenGL objects
@@ -1018,15 +1053,31 @@ public abstract class HardwareRenderer {
            sEgl.eglMakeCurrent(sEglDisplay, sPbuffer, sPbuffer, eglContext);
        }

            switch (level) {
                case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
                case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
                case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
                    GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
                    break;
                case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
                    GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
                    break;
        static void terminate() {
            synchronized (sEglLock) {
                if (sEgl == null) return;
    
                if (EGLImpl.getInitCount(sEglDisplay) == 1) {
                    EGLContext eglContext = sEglContextStorage.get();
                    if (eglContext == null) return;

                    usePbufferSurface(eglContext);
                    GLES20Canvas.terminateCaches();

                    sEgl.eglDestroyContext(sEglDisplay, eglContext);
                    sEglContextStorage.remove();
        
                    sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
                    sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

                    sEgl.eglReleaseThread();
                    sEgl.eglTerminate(sEglDisplay);
                    
                    sEgl = null;
                    sEglDisplay = null;
                    sEglConfig = null;
                    sPbuffer = null;
                }
            }
        }
    }
+1 −3
Original line number Diff line number Diff line
@@ -567,7 +567,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
        }
    }

    private void destroyHardwareResources() {
    void destroyHardwareResources() {
        if (mAttachInfo.mHardwareRenderer != null) {
            if (mAttachInfo.mHardwareRenderer.isEnabled()) {
                mAttachInfo.mHardwareRenderer.destroyLayers(mView);
@@ -880,12 +880,10 @@ public final class ViewRootImpl extends Handler implements ViewParent,
                || mNewSurfaceNeeded;

        WindowManager.LayoutParams params = null;
        int windowAttributesChanges = 0;
        if (mWindowAttributesChanged) {
            mWindowAttributesChanged = false;
            surfaceChanged = true;
            params = lp;
            windowAttributesChanges = mWindowAttributesChangesFlag;
        }
        CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
        if (compatibilityInfo.supportsScreen() == mLastInCompatMode) {
+26 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.view;

import android.app.ActivityManager;
import android.content.ComponentCallbacks2;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
@@ -409,9 +411,32 @@ public class WindowManagerImpl implements WindowManager {
     */
    public void trimMemory(int level) {
        if (HardwareRenderer.isAvailable()) {
            switch (level) {
                case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
                case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
                    // On low and medium end gfx devices
                    if (!ActivityManager.isHighEndGfx(getDefaultDisplay())) {
                        // Force a full memory flush
                        HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
                        // Destroy all hardware surfaces and resources associated to
                        // known windows
                        synchronized (this) {
                            if (mViews == null) return;
                            int count = mViews.length;
                            for (int i = 0; i < count; i++) {
                                mRoots[i].destroyHardwareResources();
                            }
                        }
                        // Terminate the hardware renderer to free all resources
                        HardwareRenderer.terminate();                        
                        break;
                    }
                    // high end gfx devices fall through to next case
                default:
                    HardwareRenderer.trimMemory(level);
            }
        }
    }

    /**
     * @hide
+14 −0
Original line number Diff line number Diff line
@@ -134,6 +134,18 @@ static void android_view_GLES20Canvas_flushCaches(JNIEnv* env, jobject clazz,
    }
}

static void android_view_GLES20Canvas_initCaches(JNIEnv* env, jobject clazz) {
    if (Caches::hasInstance()) {
        Caches::getInstance().init();
    }
}

static void android_view_GLES20Canvas_terminateCaches(JNIEnv* env, jobject clazz) {
    if (Caches::hasInstance()) {
        Caches::getInstance().terminate();
    }
}

// ----------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------
@@ -756,6 +768,8 @@ static JNINativeMethod gMethods[] = {
    { "nPreserveBackBuffer",    "()Z",         (void*) android_view_GLES20Canvas_preserveBackBuffer },
    { "nDisableVsync",          "()V",         (void*) android_view_GLES20Canvas_disableVsync },
    { "nFlushCaches",           "(I)V",        (void*) android_view_GLES20Canvas_flushCaches },
    { "nInitCaches",            "()V",         (void*) android_view_GLES20Canvas_initCaches },
    { "nTerminateCaches",       "()V",         (void*) android_view_GLES20Canvas_terminateCaches },

    { "nCreateRenderer",    "()I",             (void*) android_view_GLES20Canvas_createRenderer },
    { "nDestroyRenderer",   "(I)V",            (void*) android_view_GLES20Canvas_destroyRenderer },
Loading