Loading libs/hwui/RenderNode.cpp +4 −12 Original line number Diff line number Diff line Loading @@ -406,22 +406,14 @@ void RenderNode::deleteDisplayList(TreeObserver& observer, TreeInfo* info) { } void RenderNode::destroyHardwareResources(TreeInfo* info) { ImmediateRemoved observer(info); destroyHardwareResourcesImpl(observer, info); } void RenderNode::destroyHardwareResourcesImpl(TreeObserver& observer, TreeInfo* info) { if (hasLayer()) { renderthread::CanvasContext::destroyLayer(this); } if (mDisplayList) { mDisplayList->updateChildren([&observer, info](RenderNode* child) { child->destroyHardwareResourcesImpl(observer, info); }); setStagingDisplayList(nullptr); ImmediateRemoved observer(info); deleteDisplayList(observer, info); } } void RenderNode::destroyLayers() { if (hasLayer()) { Loading libs/hwui/RenderNode.h +0 −1 Original line number Diff line number Diff line Loading @@ -262,7 +262,6 @@ private: void prepareLayer(TreeInfo& info, uint32_t dirtyMask); void pushLayerUpdate(TreeInfo& info); void deleteDisplayList(TreeObserver& observer, TreeInfo* info = nullptr); void destroyHardwareResourcesImpl(TreeObserver& observer, TreeInfo* info = nullptr); void damageSelf(TreeInfo& info); void incParentRefCount() { mParentCount++; } Loading libs/hwui/tests/common/TestUtils.h +4 −1 Original line number Diff line number Diff line Loading @@ -357,7 +357,10 @@ private: static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) { MarkAndSweepRemoved observer(nullptr); node->syncProperties(); if (node->mNeedsDisplayListSync) { node->mNeedsDisplayListSync = false; node->syncDisplayList(observer, nullptr); } auto displayList = node->getDisplayList(); if (displayList) { for (auto&& childOp : displayList->getChildren()) { Loading libs/hwui/tests/unit/RenderNodeTests.cpp +106 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,112 @@ TEST(RenderNode, validity) { EXPECT_TRUE(parent->nothingToDraw()); } TEST(RenderNode, multiTreeValidity) { auto child = TestUtils::createNode(0, 0, 200, 400, [](RenderProperties& props, Canvas& canvas) { canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver); }); auto parent1 = TestUtils::createNode(0, 0, 200, 400, [&child](RenderProperties& props, Canvas& canvas) { canvas.drawRenderNode(child.get()); }); auto parent2 = TestUtils::createNode(0, 0, 200, 400, [&child](RenderProperties& props, Canvas& canvas) { canvas.drawRenderNode(child.get()); }); EXPECT_TRUE(child->isValid()); EXPECT_TRUE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_TRUE(child->nothingToDraw()); EXPECT_TRUE(parent1->nothingToDraw()); EXPECT_TRUE(parent2->nothingToDraw()); TestUtils::syncHierarchyPropertiesAndDisplayList(parent1); EXPECT_TRUE(child->isValid()); EXPECT_TRUE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_FALSE(child->nothingToDraw()); EXPECT_FALSE(parent1->nothingToDraw()); EXPECT_TRUE(parent2->nothingToDraw()); TestUtils::syncHierarchyPropertiesAndDisplayList(parent2); EXPECT_TRUE(child->isValid()); EXPECT_TRUE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_FALSE(child->nothingToDraw()); EXPECT_FALSE(parent1->nothingToDraw()); EXPECT_FALSE(parent2->nothingToDraw()); TestUtils::recordNode(*parent1, [](Canvas& canvas) { canvas.drawColor(Color::Amber_500, SkBlendMode::kSrcOver); }); TestUtils::syncHierarchyPropertiesAndDisplayList(parent1); EXPECT_TRUE(child->isValid()); EXPECT_TRUE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_FALSE(child->nothingToDraw()); EXPECT_FALSE(parent1->nothingToDraw()); EXPECT_FALSE(parent2->nothingToDraw()); TestUtils::recordNode(*parent2, [](Canvas& canvas) { canvas.drawColor(Color::Amber_500, SkBlendMode::kSrcOver); }); TestUtils::syncHierarchyPropertiesAndDisplayList(parent2); EXPECT_FALSE(child->isValid()); EXPECT_TRUE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_TRUE(child->nothingToDraw()); EXPECT_FALSE(parent1->nothingToDraw()); EXPECT_FALSE(parent2->nothingToDraw()); TestUtils::recordNode(*child, [](Canvas& canvas) { canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver); }); TestUtils::syncHierarchyPropertiesAndDisplayList(child); TestUtils::recordNode(*parent1, [&child](Canvas& canvas) { canvas.drawRenderNode(child.get()); }); TestUtils::syncHierarchyPropertiesAndDisplayList(parent1); TestUtils::recordNode(*parent2, [&child](Canvas& canvas) { canvas.drawRenderNode(child.get()); }); TestUtils::syncHierarchyPropertiesAndDisplayList(parent2); EXPECT_TRUE(child->isValid()); EXPECT_TRUE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_FALSE(child->nothingToDraw()); EXPECT_FALSE(parent1->nothingToDraw()); EXPECT_FALSE(parent2->nothingToDraw()); parent1->destroyHardwareResources(); EXPECT_TRUE(child->isValid()); EXPECT_FALSE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_FALSE(child->nothingToDraw()); EXPECT_TRUE(parent1->nothingToDraw()); EXPECT_FALSE(parent2->nothingToDraw()); parent2->destroyHardwareResources(); EXPECT_FALSE(child->isValid()); EXPECT_FALSE(parent1->isValid()); EXPECT_FALSE(parent2->isValid()); EXPECT_TRUE(child->nothingToDraw()); EXPECT_TRUE(parent1->nothingToDraw()); EXPECT_TRUE(parent2->nothingToDraw()); } TEST(RenderNode, releasedCallback) { class DecRefOnReleased : public GlFunctorLifecycleListener { public: Loading Loading
libs/hwui/RenderNode.cpp +4 −12 Original line number Diff line number Diff line Loading @@ -406,22 +406,14 @@ void RenderNode::deleteDisplayList(TreeObserver& observer, TreeInfo* info) { } void RenderNode::destroyHardwareResources(TreeInfo* info) { ImmediateRemoved observer(info); destroyHardwareResourcesImpl(observer, info); } void RenderNode::destroyHardwareResourcesImpl(TreeObserver& observer, TreeInfo* info) { if (hasLayer()) { renderthread::CanvasContext::destroyLayer(this); } if (mDisplayList) { mDisplayList->updateChildren([&observer, info](RenderNode* child) { child->destroyHardwareResourcesImpl(observer, info); }); setStagingDisplayList(nullptr); ImmediateRemoved observer(info); deleteDisplayList(observer, info); } } void RenderNode::destroyLayers() { if (hasLayer()) { Loading
libs/hwui/RenderNode.h +0 −1 Original line number Diff line number Diff line Loading @@ -262,7 +262,6 @@ private: void prepareLayer(TreeInfo& info, uint32_t dirtyMask); void pushLayerUpdate(TreeInfo& info); void deleteDisplayList(TreeObserver& observer, TreeInfo* info = nullptr); void destroyHardwareResourcesImpl(TreeObserver& observer, TreeInfo* info = nullptr); void damageSelf(TreeInfo& info); void incParentRefCount() { mParentCount++; } Loading
libs/hwui/tests/common/TestUtils.h +4 −1 Original line number Diff line number Diff line Loading @@ -357,7 +357,10 @@ private: static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) { MarkAndSweepRemoved observer(nullptr); node->syncProperties(); if (node->mNeedsDisplayListSync) { node->mNeedsDisplayListSync = false; node->syncDisplayList(observer, nullptr); } auto displayList = node->getDisplayList(); if (displayList) { for (auto&& childOp : displayList->getChildren()) { Loading
libs/hwui/tests/unit/RenderNodeTests.cpp +106 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,112 @@ TEST(RenderNode, validity) { EXPECT_TRUE(parent->nothingToDraw()); } TEST(RenderNode, multiTreeValidity) { auto child = TestUtils::createNode(0, 0, 200, 400, [](RenderProperties& props, Canvas& canvas) { canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver); }); auto parent1 = TestUtils::createNode(0, 0, 200, 400, [&child](RenderProperties& props, Canvas& canvas) { canvas.drawRenderNode(child.get()); }); auto parent2 = TestUtils::createNode(0, 0, 200, 400, [&child](RenderProperties& props, Canvas& canvas) { canvas.drawRenderNode(child.get()); }); EXPECT_TRUE(child->isValid()); EXPECT_TRUE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_TRUE(child->nothingToDraw()); EXPECT_TRUE(parent1->nothingToDraw()); EXPECT_TRUE(parent2->nothingToDraw()); TestUtils::syncHierarchyPropertiesAndDisplayList(parent1); EXPECT_TRUE(child->isValid()); EXPECT_TRUE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_FALSE(child->nothingToDraw()); EXPECT_FALSE(parent1->nothingToDraw()); EXPECT_TRUE(parent2->nothingToDraw()); TestUtils::syncHierarchyPropertiesAndDisplayList(parent2); EXPECT_TRUE(child->isValid()); EXPECT_TRUE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_FALSE(child->nothingToDraw()); EXPECT_FALSE(parent1->nothingToDraw()); EXPECT_FALSE(parent2->nothingToDraw()); TestUtils::recordNode(*parent1, [](Canvas& canvas) { canvas.drawColor(Color::Amber_500, SkBlendMode::kSrcOver); }); TestUtils::syncHierarchyPropertiesAndDisplayList(parent1); EXPECT_TRUE(child->isValid()); EXPECT_TRUE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_FALSE(child->nothingToDraw()); EXPECT_FALSE(parent1->nothingToDraw()); EXPECT_FALSE(parent2->nothingToDraw()); TestUtils::recordNode(*parent2, [](Canvas& canvas) { canvas.drawColor(Color::Amber_500, SkBlendMode::kSrcOver); }); TestUtils::syncHierarchyPropertiesAndDisplayList(parent2); EXPECT_FALSE(child->isValid()); EXPECT_TRUE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_TRUE(child->nothingToDraw()); EXPECT_FALSE(parent1->nothingToDraw()); EXPECT_FALSE(parent2->nothingToDraw()); TestUtils::recordNode(*child, [](Canvas& canvas) { canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver); }); TestUtils::syncHierarchyPropertiesAndDisplayList(child); TestUtils::recordNode(*parent1, [&child](Canvas& canvas) { canvas.drawRenderNode(child.get()); }); TestUtils::syncHierarchyPropertiesAndDisplayList(parent1); TestUtils::recordNode(*parent2, [&child](Canvas& canvas) { canvas.drawRenderNode(child.get()); }); TestUtils::syncHierarchyPropertiesAndDisplayList(parent2); EXPECT_TRUE(child->isValid()); EXPECT_TRUE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_FALSE(child->nothingToDraw()); EXPECT_FALSE(parent1->nothingToDraw()); EXPECT_FALSE(parent2->nothingToDraw()); parent1->destroyHardwareResources(); EXPECT_TRUE(child->isValid()); EXPECT_FALSE(parent1->isValid()); EXPECT_TRUE(parent2->isValid()); EXPECT_FALSE(child->nothingToDraw()); EXPECT_TRUE(parent1->nothingToDraw()); EXPECT_FALSE(parent2->nothingToDraw()); parent2->destroyHardwareResources(); EXPECT_FALSE(child->isValid()); EXPECT_FALSE(parent1->isValid()); EXPECT_FALSE(parent2->isValid()); EXPECT_TRUE(child->nothingToDraw()); EXPECT_TRUE(parent1->nothingToDraw()); EXPECT_TRUE(parent2->nothingToDraw()); } TEST(RenderNode, releasedCallback) { class DecRefOnReleased : public GlFunctorLifecycleListener { public: Loading