Loading core/java/android/view/GLES20Canvas.java +21 −0 Original line number Diff line number Diff line Loading @@ -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 /////////////////////////////////////////////////////////////////////////// Loading core/java/android/view/HardwareRenderer.java +61 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. * Loading Loading @@ -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) { Loading @@ -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 }; Loading Loading @@ -915,6 +929,11 @@ public abstract class HardwareRenderer { }; } @Override void initCaches() { GLES20Canvas.initCaches(); } @Override boolean canDraw() { return super.canDraw() && mGlCanvas != null; Loading Loading @@ -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 Loading @@ -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; } } } } Loading core/java/android/view/ViewRootImpl.java +1 −3 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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) { Loading core/java/android/view/WindowManagerImpl.java +26 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading core/jni/android_view_GLES20Canvas.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -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 // ---------------------------------------------------------------------------- Loading Loading @@ -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 Loading
core/java/android/view/GLES20Canvas.java +21 −0 Original line number Diff line number Diff line Loading @@ -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 /////////////////////////////////////////////////////////////////////////// Loading
core/java/android/view/HardwareRenderer.java +61 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. * Loading Loading @@ -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) { Loading @@ -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 }; Loading Loading @@ -915,6 +929,11 @@ public abstract class HardwareRenderer { }; } @Override void initCaches() { GLES20Canvas.initCaches(); } @Override boolean canDraw() { return super.canDraw() && mGlCanvas != null; Loading Loading @@ -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 Loading @@ -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; } } } } Loading
core/java/android/view/ViewRootImpl.java +1 −3 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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) { Loading
core/java/android/view/WindowManagerImpl.java +26 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading
core/jni/android_view_GLES20Canvas.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -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 // ---------------------------------------------------------------------------- Loading Loading @@ -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