Merge "Switch how destroyHardwareResources works"

This commit is contained in:
TreeHugger Robot
2017-01-30 23:08:31 +00:00
committed by Android (Google) Code Review
4 changed files with 114 additions and 14 deletions

View File

@@ -406,21 +406,13 @@ 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);
deleteDisplayList(observer, info);
}
setStagingDisplayList(nullptr);
ImmediateRemoved observer(info);
deleteDisplayList(observer, info);
}
void RenderNode::destroyLayers() {

View File

@@ -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++; }

View File

@@ -357,7 +357,10 @@ private:
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()) {

View File

@@ -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: