From aa29a97f6db94f97555d00486dd453e912d970c6 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Fri, 17 May 2013 17:07:47 -0700 Subject: [PATCH] Clear display lists when a View becomes GONE/INVISIBLE We force an invalidate whenever a View becomes VISIBLE so there is no need to keep the display list object while the view is either GONE or INVISIBLE. In particular this clears the lists of references kept by GLES20DisplayList, which helps the GC free large objects such as Bitmaps. Change-Id: Ifde0cb40baa1f35e5e6439d3bf8eab3c4c1270f0 --- core/java/android/view/View.java | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 4dc26829f7367..d62671d9e2bc7 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -8581,7 +8581,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - if ((flags & VISIBILITY_MASK) == VISIBLE) { + final int newVisibility = flags & VISIBILITY_MASK; + if (newVisibility == VISIBLE) { if ((changed & VISIBILITY_MASK) != 0) { /* * If this view is becoming visible, invalidate it in case it changed while @@ -8647,14 +8648,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } if ((changed & VISIBILITY_MASK) != 0) { + // If the view is invisible, cleanup its display list to free up resources + if (newVisibility != VISIBLE) { + cleanupDraw(); + } + if (mParent instanceof ViewGroup) { ((ViewGroup) mParent).onChildVisibilityChanged(this, - (changed & VISIBILITY_MASK), (flags & VISIBILITY_MASK)); + (changed & VISIBILITY_MASK), newVisibility); ((View) mParent).invalidate(true); } else if (mParent != null) { mParent.invalidateChild(this, null); } - dispatchVisibilityChanged(this, (flags & VISIBILITY_MASK)); + dispatchVisibilityChanged(this, newVisibility); } if ((changed & WILL_NOT_CACHE_DRAWING) != 0) { @@ -12034,6 +12040,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, destroyLayer(false); + cleanupDraw(); + + mCurrentAnimation = null; + mCurrentScene = null; + + resetAccessibilityStateChanged(); + } + + private void cleanupDraw() { if (mAttachInfo != null) { if (mDisplayList != null) { mDisplayList.markDirty(); @@ -12044,12 +12059,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Should never happen clearDisplayList(); } - - mCurrentAnimation = null; - - mCurrentScene = null; - - resetAccessibilityStateChanged(); } void invalidateInheritedLayoutMode(int layoutModeOfRoot) {