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

Commit 048b6990 authored by Romain Guy's avatar Romain Guy Committed by Android Git Automerger
Browse files

am 50a66f0e: Merge "Terminate EGL when an app goes in the background" into ics-mr1

* commit '50a66f0e':
  Terminate EGL when an app goes in the background
parents 350e437f 50a66f0e
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