From 46bfc4811094e5b1e3196246e457d4c6b58332ec Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Fri, 16 Aug 2013 18:38:29 -0700 Subject: [PATCH] Fix hardware layers lifecycle Bug #10075732 Hardware layers could survive across EGL terminate events. Change-Id: Ie8565d55cb29fe6625fa1584d695edfecd37ab5e --- core/java/android/app/ActivityThread.java | 2 +- .../android/gesture/GestureOverlayView.java | 1 + core/java/android/view/DisplayList.java | 22 +++++++++++-------- core/java/android/view/GLES20DisplayList.java | 1 + core/java/android/view/GLES20Layer.java | 3 +++ core/java/android/view/View.java | 14 +++++++----- core/java/android/view/ViewRootImpl.java | 13 +++-------- .../android/view/WindowManagerGlobal.java | 4 +--- core/java/android/widget/NumberPicker.java | 1 + libs/hwui/Caches.cpp | 2 ++ 10 files changed, 34 insertions(+), 29 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 2a28b76738f9a..e6960b36f6639 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3865,7 +3865,7 @@ public final class ActivityThread { } } - final void freeTextLayoutCachesIfNeeded(int configDiff) { + static void freeTextLayoutCachesIfNeeded(int configDiff) { if (configDiff != 0) { // Ask text layout engine to free its caches if there is a locale change boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); diff --git a/core/java/android/gesture/GestureOverlayView.java b/core/java/android/gesture/GestureOverlayView.java index b6c260fd3e023..2d47f289b38ef 100644 --- a/core/java/android/gesture/GestureOverlayView.java +++ b/core/java/android/gesture/GestureOverlayView.java @@ -486,6 +486,7 @@ public class GestureOverlayView extends FrameLayout { @Override protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); cancelClearAnimation(); } diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java index 2d24c1ea42fa6..43fd628980ff5 100644 --- a/core/java/android/view/DisplayList.java +++ b/core/java/android/view/DisplayList.java @@ -208,9 +208,22 @@ public abstract class DisplayList { * {@link #isValid()} will return false. * * @see #isValid() + * @see #reset() */ public abstract void clear(); + + /** + * Reset native resources. This is called when cleaning up the state of display lists + * during destruction of hardware resources, to ensure that we do not hold onto + * obsolete resources after related resources are gone. + * + * @see #clear() + * + * @hide + */ + public abstract void reset(); + /** * Sets the dirty flag. When a display list is dirty, {@link #clear()} should * be invoked whenever possible. @@ -670,13 +683,4 @@ public abstract class DisplayList { * @see View#offsetTopAndBottom(int) */ public abstract void offsetTopAndBottom(float offset); - - /** - * Reset native resources. This is called when cleaning up the state of display lists - * during destruction of hardware resources, to ensure that we do not hold onto - * obsolete resources after related resources are gone. - * - * @hide - */ - public abstract void reset(); } diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java index 8b2a2ef8b6e09..c652bac1f772c 100644 --- a/core/java/android/view/GLES20DisplayList.java +++ b/core/java/android/view/GLES20DisplayList.java @@ -94,6 +94,7 @@ class GLES20DisplayList extends DisplayList { if (hasNativeDisplayList()) { nReset(mFinalizer.mNativeDisplayList); } + clear(); } @Override diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java index 7ee628be263d4..0e3311c1c860c 100644 --- a/core/java/android/view/GLES20Layer.java +++ b/core/java/android/view/GLES20Layer.java @@ -59,6 +59,9 @@ abstract class GLES20Layer extends HardwareLayer { @Override public void destroy() { + if (mDisplayList != null) { + mDisplayList.reset(); + } if (mFinalizer != null) { mFinalizer.destroy(); mFinalizer = null; diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 747e8eae192b9..4a80b9345dc80 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -12144,7 +12144,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, removeSendViewScrolledAccessibilityEventCallback(); destroyDrawingCache(); - destroyLayer(false); cleanupDraw(); @@ -12162,7 +12161,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mAttachInfo.mViewRootImpl.cancelInvalidate(this); } else { // Should never happen - clearDisplayList(); + resetDisplayList(); } } @@ -12773,9 +12772,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mHardwareLayer.destroy(); mHardwareLayer = null; - if (mDisplayList != null) { - mDisplayList.reset(); - } invalidate(true); invalidateParentCaches(); } @@ -12796,7 +12792,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ protected void destroyHardwareResources() { - clearDisplayList(); + resetDisplayList(); destroyLayer(true); } @@ -13044,6 +13040,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } + private void resetDisplayList() { + if (mDisplayList != null) { + mDisplayList.reset(); + } + } + /** *

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 e90705c1ed538..f711e7a2c390d 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -614,15 +614,7 @@ public final class ViewRootImpl implements ViewParent, } void destroyHardwareResources() { - if (mAttachInfo.mHardwareRenderer != null) { - if (mAttachInfo.mHardwareRenderer.isEnabled()) { - mAttachInfo.mHardwareRenderer.destroyLayers(mView); - } - mAttachInfo.mHardwareRenderer.destroy(false); - } - } - - void terminateHardwareResources() { + invalidateDisplayLists(); if (mAttachInfo.mHardwareRenderer != null) { mAttachInfo.mHardwareRenderer.destroyHardwareResources(mView); mAttachInfo.mHardwareRenderer.destroy(false); @@ -636,6 +628,7 @@ public final class ViewRootImpl implements ViewParent, HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_MODERATE); } } else { + invalidateDisplayLists(); if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) { mAttachInfo.mHardwareRenderer.destroyLayers(mView); @@ -2554,7 +2547,7 @@ public final class ViewRootImpl implements ViewParent, for (int i = 0; i < count; i++) { final DisplayList displayList = displayLists.get(i); if (displayList.isDirty()) { - displayList.clear(); + displayList.reset(); } } diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index b183bb64edfc0..3dd96f57a8efd 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -21,7 +21,6 @@ import android.app.ActivityManager; import android.content.ComponentCallbacks2; import android.content.res.Configuration; import android.opengl.ManagedEGLContext; -import android.os.Debug; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; @@ -29,7 +28,6 @@ import android.os.SystemProperties; import android.util.AndroidRuntimeException; import android.util.ArraySet; import android.util.Log; -import android.util.Slog; import android.view.inputmethod.InputMethodManager; import com.android.internal.util.FastPrintWriter; @@ -385,7 +383,7 @@ public final class WindowManagerGlobal { // known windows synchronized (mLock) { for (int i = mRoots.size() - 1; i >= 0; --i) { - mRoots.get(i).terminateHardwareResources(); + mRoots.get(i).destroyHardwareResources(); } } // Force a full memory flush diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index 4a98f66c16964..19cc3c2ee2758 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -1425,6 +1425,7 @@ public class NumberPicker extends LinearLayout { @Override protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); removeAllCallbacks(); } diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index f9cf9a24fb1c9..c0b3bfccfab68 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -226,6 +226,8 @@ void Caches::terminate() { patchCache.clear(); + clearGarbage(); + mInitialized = false; }