Merge "Switch how destroyHardwareResources works"
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 7d8f046..f1c8232 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -406,21 +406,13 @@
}
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);
- deleteDisplayList(observer, info);
- }
+ setStagingDisplayList(nullptr);
+
+ ImmediateRemoved observer(info);
+ deleteDisplayList(observer, info);
}
void RenderNode::destroyLayers() {
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 14a664c..a971e83 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -262,7 +262,6 @@
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++; }
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 16bc6f7..0c7bb60 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -357,7 +357,10 @@
static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) {
MarkAndSweepRemoved observer(nullptr);
node->syncProperties();
- node->syncDisplayList(observer, nullptr);
+ if (node->mNeedsDisplayListSync) {
+ node->mNeedsDisplayListSync = false;
+ node->syncDisplayList(observer, nullptr);
+ }
auto displayList = node->getDisplayList();
if (displayList) {
for (auto&& childOp : displayList->getChildren()) {
diff --git a/libs/hwui/tests/unit/RenderNodeTests.cpp b/libs/hwui/tests/unit/RenderNodeTests.cpp
index 8af4bbe..2925243 100644
--- a/libs/hwui/tests/unit/RenderNodeTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeTests.cpp
@@ -130,6 +130,112 @@
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: