Overhaul RenderNode's DisplayList management

* Move mValid to native
* Have destroyHardwareResources destroy everything
* Remove flaky mParentCount checks in setStaging
* All tree updates have an internal observer to
  ensure onRemovedFromTree() is a reliable signal
* onRemovedFromTree() immediately releases resources
  to avoid displaylist "leaks"

Test: Unit tests for validity added & pass, manually
verified that b/34072929 doesn't repro

Bug: 34072929

Change-Id: I856534b4ed1b7f009fc4b7cd13209b97fa42a71c
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 1b3bf96..a53e5e0 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -146,21 +146,38 @@
         , mProfiler(mFrames)
         , mContentDrawBounds(0, 0, 0, 0)
         , mRenderPipeline(std::move(renderPipeline)) {
+    rootRenderNode->makeRoot();
     mRenderNodes.emplace_back(rootRenderNode);
     mRenderThread.renderState().registerCanvasContext(this);
     mProfiler.setDensity(mRenderThread.mainDisplayInfo().density);
 }
 
 CanvasContext::~CanvasContext() {
-    destroy(nullptr);
+    destroy();
     mRenderThread.renderState().unregisterCanvasContext(this);
+    for (auto& node : mRenderNodes) {
+        node->clearRoot();
+    }
+    mRenderNodes.clear();
 }
 
-void CanvasContext::destroy(TreeObserver* observer) {
+void CanvasContext::addRenderNode(RenderNode* node, bool placeFront) {
+    int pos = placeFront ? 0 : static_cast<int>(mRenderNodes.size());
+    node->makeRoot();
+    mRenderNodes.emplace(mRenderNodes.begin() + pos, node);
+}
+
+void CanvasContext::removeRenderNode(RenderNode* node) {
+    node->clearRoot();
+    mRenderNodes.erase(std::remove(mRenderNodes.begin(), mRenderNodes.end(), node),
+            mRenderNodes.end());
+}
+
+void CanvasContext::destroy() {
     stopDrawing();
     setSurface(nullptr);
-    freePrefetchedLayers(observer);
-    destroyHardwareResources(observer);
+    freePrefetchedLayers();
+    destroyHardwareResources();
     mAnimationContext->destroy();
 }
 
@@ -320,7 +337,7 @@
     mAnimationContext->runRemainingAnimations(info);
     GL_CHECKPOINT(MODERATE);
 
-    freePrefetchedLayers(info.observer);
+    freePrefetchedLayers();
     GL_CHECKPOINT(MODERATE);
 
     mIsDirty = true;
@@ -504,19 +521,19 @@
     }
 }
 
-void CanvasContext::freePrefetchedLayers(TreeObserver* observer) {
+void CanvasContext::freePrefetchedLayers() {
     if (mPrefetchedLayers.size()) {
         for (auto& node : mPrefetchedLayers) {
             ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...",
                     node->getName());
-            node->destroyHardwareResources(observer);
-            node->decStrong(observer);
+            node->destroyLayers();
+            node->decStrong(nullptr);
         }
         mPrefetchedLayers.clear();
     }
 }
 
-void CanvasContext::buildLayer(RenderNode* node, TreeObserver* observer) {
+void CanvasContext::buildLayer(RenderNode* node) {
     ATRACE_CALL();
     if (!mRenderPipeline->isContextReady()) return;
 
@@ -525,7 +542,6 @@
 
     TreeInfo info(TreeInfo::MODE_FULL, *this);
     info.damageAccumulator = &mDamageAccumulator;
-    info.observer = observer;
     info.layerUpdateQueue = &mLayerUpdateQueue;
     info.runAnimations = false;
     node->prepareTree(info);
@@ -545,12 +561,12 @@
     return mRenderPipeline->copyLayerInto(layer, bitmap);
 }
 
-void CanvasContext::destroyHardwareResources(TreeObserver* observer) {
+void CanvasContext::destroyHardwareResources() {
     stopDrawing();
     if (mRenderPipeline->isContextReady()) {
-        freePrefetchedLayers(observer);
+        freePrefetchedLayers();
         for (const sp<RenderNode>& node : mRenderNodes) {
-            node->destroyHardwareResources(observer);
+            node->destroyHardwareResources();
         }
         mRenderPipeline->onDestroyHardwareResources();
     }
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 0174b86..aa01caa 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -132,17 +132,17 @@
     void prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
             int64_t syncQueued, RenderNode* target);
     void draw();
-    void destroy(TreeObserver* observer);
+    void destroy();
 
     // IFrameCallback, Choreographer-driven frame callback entry point
     virtual void doFrame() override;
     void prepareAndDraw(RenderNode* node);
 
-    void buildLayer(RenderNode* node, TreeObserver* observer);
+    void buildLayer(RenderNode* node);
     bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
     void markLayerInUse(RenderNode* node);
 
-    void destroyHardwareResources(TreeObserver* observer);
+    void destroyHardwareResources();
     static void trimMemory(RenderThread& thread, int level);
 
     DeferredLayerUpdater* createTextureLayer();
@@ -160,15 +160,8 @@
 
     void serializeDisplayListTree();
 
-    void addRenderNode(RenderNode* node, bool placeFront) {
-        int pos = placeFront ? 0 : static_cast<int>(mRenderNodes.size());
-        mRenderNodes.emplace(mRenderNodes.begin() + pos, node);
-    }
-
-    void removeRenderNode(RenderNode* node) {
-        mRenderNodes.erase(std::remove(mRenderNodes.begin(), mRenderNodes.end(), node),
-                mRenderNodes.end());
-    }
+    void addRenderNode(RenderNode* node, bool placeFront);
+    void removeRenderNode(RenderNode* node);
 
     void setContentDrawBounds(int left, int top, int right, int bottom) {
         mContentDrawBounds.set(left, top, right, bottom);
@@ -213,7 +206,7 @@
 
     void setSurface(Surface* window);
 
-    void freePrefetchedLayers(TreeObserver* observer);
+    void freePrefetchedLayers();
 
     bool isSwapChainStuffed();
 
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 4ff54a5..7d641d3 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -65,12 +65,11 @@
     }
 }
 
-int DrawFrameTask::drawFrame(TreeObserver* observer) {
+int DrawFrameTask::drawFrame() {
     LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
 
     mSyncResult = SyncResult::OK;
     mSyncQueued = systemTime(CLOCK_MONOTONIC);
-    mObserver = observer;
     postAndWait();
 
     return mSyncResult;
@@ -89,7 +88,6 @@
     bool canDrawThisFrame;
     {
         TreeInfo info(TreeInfo::MODE_FULL, *mContext);
-        info.observer = mObserver;
         canUnblockUiThread = syncFrameState(info);
         canDrawThisFrame = info.out.canDrawThisFrame;
     }
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index c02d376..fb48062 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -65,7 +65,7 @@
     void pushLayerUpdate(DeferredLayerUpdater* layer);
     void removeLayerUpdate(DeferredLayerUpdater* layer);
 
-    int drawFrame(TreeObserver* observer);
+    int drawFrame();
 
     int64_t* frameInfo() { return mFrameInfo; }
 
@@ -90,7 +90,6 @@
 
     int mSyncResult;
     int64_t mSyncQueued;
-    TreeObserver* mObserver;
 
     int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE];
 };
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 022e871..fb79272 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -230,19 +230,18 @@
     return mDrawFrameTask.frameInfo();
 }
 
-int RenderProxy::syncAndDrawFrame(TreeObserver* observer) {
-    return mDrawFrameTask.drawFrame(observer);
+int RenderProxy::syncAndDrawFrame() {
+    return mDrawFrameTask.drawFrame();
 }
 
-CREATE_BRIDGE2(destroy, CanvasContext* context, TreeObserver* observer) {
-    args->context->destroy(args->observer);
+CREATE_BRIDGE1(destroy, CanvasContext* context) {
+    args->context->destroy();
     return nullptr;
 }
 
-void RenderProxy::destroy(TreeObserver* observer) {
+void RenderProxy::destroy() {
     SETUP_TASK(destroy);
     args->context = mContext;
-    args->observer = observer;
     // destroyCanvasAndSurface() needs a fence as when it returns the
     // underlying BufferQueue is going to be released from under
     // the render thread.
@@ -282,16 +281,15 @@
     return layer;
 }
 
-CREATE_BRIDGE3(buildLayer, CanvasContext* context, RenderNode* node, TreeObserver* observer) {
-    args->context->buildLayer(args->node, args->observer);
+CREATE_BRIDGE2(buildLayer, CanvasContext* context, RenderNode* node) {
+    args->context->buildLayer(args->node);
     return nullptr;
 }
 
-void RenderProxy::buildLayer(RenderNode* node, TreeObserver* observer) {
+void RenderProxy::buildLayer(RenderNode* node) {
     SETUP_TASK(buildLayer);
     args->context = mContext;
     args->node = node;
-    args->observer = observer;
     postAndWait(task);
 }
 
@@ -328,15 +326,14 @@
     postAndWait(task);
 }
 
-CREATE_BRIDGE2(destroyHardwareResources, CanvasContext* context, TreeObserver* observer) {
-    args->context->destroyHardwareResources(args->observer);
+CREATE_BRIDGE1(destroyHardwareResources, CanvasContext* context) {
+    args->context->destroyHardwareResources();
     return nullptr;
 }
 
-void RenderProxy::destroyHardwareResources(TreeObserver* observer) {
+void RenderProxy::destroyHardwareResources() {
     SETUP_TASK(destroyHardwareResources);
     args->context = mContext;
-    args->observer = observer;
     postAndWait(task);
 }
 
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 44a5a14..1629090 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -44,7 +44,6 @@
 class DisplayList;
 class Layer;
 class Rect;
-class TreeObserver;
 
 namespace renderthread {
 
@@ -87,19 +86,19 @@
     ANDROID_API void setLightCenter(const Vector3& lightCenter);
     ANDROID_API void setOpaque(bool opaque);
     ANDROID_API int64_t* frameInfo();
-    ANDROID_API int syncAndDrawFrame(TreeObserver* observer);
-    ANDROID_API void destroy(TreeObserver* observer);
+    ANDROID_API int syncAndDrawFrame();
+    ANDROID_API void destroy();
 
     ANDROID_API static void invokeFunctor(Functor* functor, bool waitForCompletion);
 
     ANDROID_API DeferredLayerUpdater* createTextureLayer();
-    ANDROID_API void buildLayer(RenderNode* node, TreeObserver* observer);
+    ANDROID_API void buildLayer(RenderNode* node);
     ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap);
     ANDROID_API void pushLayerUpdate(DeferredLayerUpdater* layer);
     ANDROID_API void cancelLayerUpdate(DeferredLayerUpdater* layer);
     ANDROID_API void detachSurfaceTexture(DeferredLayerUpdater* layer);
 
-    ANDROID_API void destroyHardwareResources(TreeObserver* observer);
+    ANDROID_API void destroyHardwareResources();
     ANDROID_API static void trimMemory(int level);
     ANDROID_API static void overrideProperty(const char* name, const char* value);