Destroy DisplayLists on time

Change-Id: I32a97d1234545075e9423c352c772e09ca954741
Fixes: 34072929
Test: Manual, see b/34072929#comment36
(cherry picked from commit 2874daa4d38bddd3a5f0edb3774d5e5884dd9554)
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index f3ebcb4..b0826a8 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -360,6 +360,7 @@
     void destroy() {
         mInitialized = false;
         updateEnabledState(null);
+        mRootNode.discardDisplayList();
         nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
     }
 
@@ -491,20 +492,12 @@
      */
     void destroyHardwareResources(View view) {
         destroyResources(view);
+        mRootNode.discardDisplayList();
         nDestroyHardwareResources(mNativeProxy);
     }
 
     private static void destroyResources(View view) {
         view.destroyHardwareResources();
-
-        if (view instanceof ViewGroup) {
-            ViewGroup group = (ViewGroup) view;
-
-            int count = group.getChildCount();
-            for (int i = 0; i < count; i++) {
-                destroyResources(group.getChildAt(i));
-            }
-        }
     }
 
     /**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 37dfdb9..fc298c6e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16641,6 +16641,12 @@
         // safe to free its copy of the display list as it knows that we will
         // push an updated DisplayList if we try to draw again
         resetDisplayList();
+        if (mOverlay != null) {
+            mOverlay.getOverlayView().destroyHardwareResources();
+        }
+        if (mGhostView != null) {
+            mGhostView.destroyHardwareResources();
+        }
     }
 
     /**
@@ -16811,11 +16817,9 @@
     }
 
     private void resetDisplayList() {
-        if (mRenderNode.isValid()) {
-            mRenderNode.discardDisplayList();
-        }
+        mRenderNode.discardDisplayList();
 
-        if (mBackgroundRenderNode != null && mBackgroundRenderNode.isValid()) {
+        if (mBackgroundRenderNode != null) {
             mBackgroundRenderNode.discardDisplayList();
         }
     }
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index a479bb3..d252d75 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3450,6 +3450,16 @@
         super.dispatchDetachedFromWindow();
     }
 
+    /** @hide */
+    @Override
+    protected void destroyHardwareResources() {
+        super.destroyHardwareResources();
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            getChildAt(i).destroyHardwareResources();
+        }
+    }
+
     /**
      * @hide
      */
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index d75d5c1..3eccc42 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -88,6 +88,7 @@
         return;
     }
 
+    node->setStagingDisplayList(nullptr, nullptr);
     // Update the valid field, since native has already removed
     // the staging DisplayList
     env->SetBooleanField(jnode, gRenderNode_validFieldID, false);