From 38c2ece5ce4c59f30e5832779bf1d86d68b1c442 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Thu, 24 May 2012 14:20:56 -0700 Subject: [PATCH] Clear bitmap references from display lists as early as possible Bug #6555840 Apps like Google+ with large bitmaps displayed in listivews could run into memory issues because of these references. Change-Id: I39486bda13ce00c5a3b6481139ad54547506a8b4 --- core/java/android/view/DisplayList.java | 6 ++++++ core/java/android/view/GLES20DisplayList.java | 8 +++++++- core/java/android/view/View.java | 15 +++++++++++---- core/java/android/view/ViewRootImpl.java | 4 +++- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java index 3dab17489d250..da666b5ecadb8 100644 --- a/core/java/android/view/DisplayList.java +++ b/core/java/android/view/DisplayList.java @@ -82,6 +82,12 @@ public abstract class DisplayList { */ public abstract void invalidate(); + /** + * Clears additional resources held onto by this display list. You should + * only invoke this method after {@link #invalidate()}. + */ + public abstract void clear(); + /** * Returns whether the display list is currently usable. If this returns false, * the display list should be re-recorded prior to replaying it. diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java index 0154556dab40a..08a5831d03983 100644 --- a/core/java/android/view/GLES20DisplayList.java +++ b/core/java/android/view/GLES20DisplayList.java @@ -71,6 +71,13 @@ class GLES20DisplayList extends DisplayList { mValid = false; } + @Override + public void clear() { + if (!mValid) { + mBitmaps.clear(); + } + } + @Override public boolean isValid() { return mValid; @@ -343,7 +350,6 @@ class GLES20DisplayList extends DisplayList { private static native void nSetPivotX(int displayList, float pivotX); private static native void nSetCaching(int displayList, boolean caching); private static native void nSetClipChildren(int displayList, boolean clipChildren); - private static native void nSetApplicationScale(int displayList, float scale); private static native void nSetAlpha(int displayList, float alpha); private static native void nSetHasOverlappingRendering(int displayList, boolean hasOverlappingRendering); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 46982031fccf5..10b8ff58a4ceb 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -6800,6 +6800,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal */ public void dispatchStartTemporaryDetach() { clearAccessibilityFocus(); + clearDisplayList(); + onStartTemporaryDetach(); } @@ -11455,10 +11457,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } mAttachInfo.mViewRootImpl.cancelInvalidate(this); } else { - if (mDisplayList != null) { - // Should never happen - mDisplayList.invalidate(); - } + // Should never happen + clearDisplayList(); } mCurrentAnimation = null; @@ -12236,6 +12236,13 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal return mDisplayList; } + private void clearDisplayList() { + if (mDisplayList != null) { + mDisplayList.invalidate(); + mDisplayList.clear(); + } + } + /** *

Calling this method is equivalent to calling getDrawingCache(false).

* diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index c9a41adb8c558..551b6cc648c42 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2335,7 +2335,9 @@ public final class ViewRootImpl implements ViewParent, final int count = displayLists.size(); for (int i = 0; i < count; i++) { - displayLists.get(i).invalidate(); + final DisplayList displayList = displayLists.get(i); + displayList.invalidate(); + displayList.clear(); } displayLists.clear();