Fix hardware layers lifecycle
Bug #10075732
Hardware layers could survive across EGL terminate events.
Change-Id: Ie8565d55cb29fe6625fa1584d695edfecd37ab5e
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 2a28b76..e6960b3 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3865,7 +3865,7 @@
}
}
- 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 b6c260f..2d47f28 100644
--- a/core/java/android/gesture/GestureOverlayView.java
+++ b/core/java/android/gesture/GestureOverlayView.java
@@ -486,6 +486,7 @@
@Override
protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
cancelClearAnimation();
}
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index 2d24c1e..43fd628 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -208,9 +208,22 @@
* {@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 @@
* @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 8b2a2ef..c652bac 100644
--- a/core/java/android/view/GLES20DisplayList.java
+++ b/core/java/android/view/GLES20DisplayList.java
@@ -94,6 +94,7 @@
if (hasNativeDisplayList()) {
nReset(mFinalizer.mNativeDisplayList);
}
+ clear();
}
@Override
diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java
index 7ee628b..0e3311c 100644
--- a/core/java/android/view/GLES20Layer.java
+++ b/core/java/android/view/GLES20Layer.java
@@ -59,6 +59,9 @@
@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 747e8ea..4a80b93 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12144,7 +12144,6 @@
removeSendViewScrolledAccessibilityEventCallback();
destroyDrawingCache();
-
destroyLayer(false);
cleanupDraw();
@@ -12162,7 +12161,7 @@
mAttachInfo.mViewRootImpl.cancelInvalidate(this);
} else {
// Should never happen
- clearDisplayList();
+ resetDisplayList();
}
}
@@ -12773,9 +12772,6 @@
mHardwareLayer.destroy();
mHardwareLayer = null;
- if (mDisplayList != null) {
- mDisplayList.reset();
- }
invalidate(true);
invalidateParentCaches();
}
@@ -12796,7 +12792,7 @@
* @hide
*/
protected void destroyHardwareResources() {
- clearDisplayList();
+ resetDisplayList();
destroyLayer(true);
}
@@ -13044,6 +13040,12 @@
}
}
+ private void resetDisplayList() {
+ if (mDisplayList != null) {
+ mDisplayList.reset();
+ }
+ }
+
/**
* <p>Calling this method is equivalent to calling <code>getDrawingCache(false)</code>.</p>
*
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e90705c..f711e7a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -614,15 +614,7 @@
}
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 @@
HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_MODERATE);
}
} else {
+ invalidateDisplayLists();
if (mAttachInfo.mHardwareRenderer != null &&
mAttachInfo.mHardwareRenderer.isEnabled()) {
mAttachInfo.mHardwareRenderer.destroyLayers(mView);
@@ -2554,7 +2547,7 @@
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 b183bb6..3dd96f5 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -21,7 +21,6 @@
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.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 @@
// 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 4a98f66..19cc3c2 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -1425,6 +1425,7 @@
@Override
protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
removeAllCallbacks();
}
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index f9cf9a2..c0b3bfc 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -226,6 +226,8 @@
patchCache.clear();
+ clearGarbage();
+
mInitialized = false;
}