OSDN Git Service

Destroy DisplayLists on time
authorJohn Reck <jreck@google.com>
Fri, 20 Jan 2017 03:54:18 +0000 (19:54 -0800)
committerJohn Reck <jreck@google.com>
Fri, 20 Jan 2017 17:56:38 +0000 (09:56 -0800)
Change-Id: I32a97d1234545075e9423c352c772e09ca954741
Fixes: 34072929
Test: Manual, see b/34072929#comment36

core/java/android/view/ThreadedRenderer.java
core/java/android/view/View.java
core/java/android/view/ViewGroup.java
core/jni/android_view_RenderNode.cpp

index f3ebcb4..b0826a8 100644 (file)
@@ -360,6 +360,7 @@ public final class ThreadedRenderer {
     void destroy() {
         mInitialized = false;
         updateEnabledState(null);
+        mRootNode.discardDisplayList();
         nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
     }
 
@@ -491,20 +492,12 @@ public final class ThreadedRenderer {
      */
     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));
-            }
-        }
     }
 
     /**
index 9d1af50..623b9ce 100644 (file)
@@ -16642,6 +16642,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
         // 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();
+        }
     }
 
     /**
@@ -16812,11 +16818,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     }
 
     private void resetDisplayList() {
-        if (mRenderNode.isValid()) {
-            mRenderNode.discardDisplayList();
-        }
+        mRenderNode.discardDisplayList();
 
-        if (mBackgroundRenderNode != null && mBackgroundRenderNode.isValid()) {
+        if (mBackgroundRenderNode != null) {
             mBackgroundRenderNode.discardDisplayList();
         }
     }
index 1b42a90..269dd77 100644 (file)
@@ -3449,6 +3449,16 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
         super.dispatchDetachedFromWindow();
     }
 
+    /** @hide */
+    @Override
+    protected void destroyHardwareResources() {
+        super.destroyHardwareResources();
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            getChildAt(i).destroyHardwareResources();
+        }
+    }
+
     /**
      * @hide
      */
index d75d5c1..3eccc42 100644 (file)
@@ -88,6 +88,7 @@ void onRenderNodeRemoved(JNIEnv* env, RenderNode* node) {
         return;
     }
 
+    node->setStagingDisplayList(nullptr, nullptr);
     // Update the valid field, since native has already removed
     // the staging DisplayList
     env->SetBooleanField(jnode, gRenderNode_validFieldID, false);