summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornyquist <nyquist@chromium.org>2016-02-18 16:19:15 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-19 00:21:17 +0000
commit34a0f41b40b9de9d0be0d161ead546f355f13102 (patch)
tree0486d0e07454c30ca8edebda328494db111a0585
parente9ef74ab7411ca08359015167b2c2bc1b566f95b (diff)
downloadchromium_src-34a0f41b40b9de9d0be0d161ead546f355f13102.zip
chromium_src-34a0f41b40b9de9d0be0d161ead546f355f13102.tar.gz
chromium_src-34a0f41b40b9de9d0be0d161ead546f355f13102.tar.bz2
Ensure LayerTreeHost is copied to children.
During deserialization of the hierarchy for new layers, the LTH pointer was not copied to children until after the child itself had been deserialized. If that child itself had children, those would not get the LTH set, since it had not been set yet. In addition, for PictureLayer, since SetLayerTreeHost(...) is not called during deserialization of new layers, we possibly need to create the recording source during property deserialization. Thirdly, this patch ensures that the code for deserializing the mask and replica layers act similarly to the other children. This also included removing the call to SetIsMask() since layers which care about that state (PictureLayer), already serializes that value as a property. BUG=538710 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1708753003 Cr-Commit-Position: refs/heads/master@{#376295}
-rw-r--r--cc/layers/layer.cc26
-rw-r--r--cc/layers/layer_unittest.cc67
-rw-r--r--cc/layers/picture_layer.cc6
3 files changed, 88 insertions, 11 deletions
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 24eed8d..c6949a1 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -1420,12 +1420,12 @@ void Layer::FromLayerNodeProto(const proto::LayerNode& proto,
DCHECK(child_proto.has_type());
scoped_refptr<Layer> child =
LayerProtoConverter::FindOrAllocateAndConstruct(child_proto, layer_map);
- child->FromLayerNodeProto(child_proto, layer_map);
- children_.push_back(child);
// The child must now refer to this layer as its parent, and must also have
- // the same LayerTreeHost.
+ // the same LayerTreeHost. This must be done before deserializing children.
child->parent_ = this;
child->layer_tree_host_ = layer_tree_host_;
+ child->FromLayerNodeProto(child_proto, layer_map);
+ children_.push_back(child);
}
// Remove now-unused children from the tree.
@@ -1441,26 +1441,30 @@ void Layer::FromLayerNodeProto(const proto::LayerNode& proto,
}
}
- if (mask_layer_)
- mask_layer_->RemoveFromParent();
+ if (mask_layer_) {
+ mask_layer_->parent_ = nullptr;
+ mask_layer_->layer_tree_host_ = nullptr;
+ }
if (proto.has_mask_layer()) {
mask_layer_ = LayerProtoConverter::FindOrAllocateAndConstruct(
proto.mask_layer(), layer_map);
+ mask_layer_->parent_ = this;
+ mask_layer_->layer_tree_host_ = layer_tree_host_;
mask_layer_->FromLayerNodeProto(proto.mask_layer(), layer_map);
- mask_layer_->SetParent(this);
- // SetIsMask() is only ever called with true, so no need to reset flag.
- mask_layer_->SetIsMask(true);
} else {
mask_layer_ = nullptr;
}
- if (replica_layer_)
- replica_layer_->RemoveFromParent();
+ if (replica_layer_) {
+ replica_layer_->parent_ = nullptr;
+ replica_layer_->layer_tree_host_ = nullptr;
+ }
if (proto.has_replica_layer()) {
replica_layer_ = LayerProtoConverter::FindOrAllocateAndConstruct(
proto.replica_layer(), layer_map);
+ replica_layer_->parent_ = this;
+ replica_layer_->layer_tree_host_ = layer_tree_host_;
replica_layer_->FromLayerNodeProto(proto.replica_layer(), layer_map);
- replica_layer_->SetParent(this);
} else {
replica_layer_ = nullptr;
}
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc
index 3ecf5ac..ce71b08 100644
--- a/cc/layers/layer_unittest.cc
+++ b/cc/layers/layer_unittest.cc
@@ -369,6 +369,69 @@ class LayerSerializationTest : public testing::Test {
VerifyBaseLayerPropertiesSerializationAndDeserialization(layer.get());
}
+ void RunHierarchyDeserializationWithLayerTreeHostTest() {
+ /* Testing serialization and deserialization of a tree that looks like this:
+ root
+ \
+ a
+ \
+ b
+ \
+ c
+ The root layer has a LayerTreeHost, and it should propagate to all the
+ children.
+ */
+ scoped_refptr<Layer> layer_src_root = Layer::Create(LayerSettings());
+ scoped_refptr<Layer> layer_src_a = Layer::Create(LayerSettings());
+ scoped_refptr<Layer> layer_src_b = Layer::Create(LayerSettings());
+ scoped_refptr<Layer> layer_src_c = Layer::Create(LayerSettings());
+ layer_src_root->AddChild(layer_src_a);
+ layer_src_a->AddChild(layer_src_b);
+ layer_src_b->AddChild(layer_src_c);
+
+ proto::LayerNode proto;
+ layer_src_root->ToLayerNodeProto(&proto);
+
+ Layer::LayerIdMap empty_dest_layer_map;
+ scoped_refptr<Layer> layer_dest_root = Layer::Create(LayerSettings());
+
+ // Forcefully set the layer tree host for the root layer, which should cause
+ // it to propagate to all the children.
+ layer_dest_root->layer_tree_host_ = layer_tree_host_.get();
+
+ layer_dest_root->FromLayerNodeProto(proto, empty_dest_layer_map);
+
+ EXPECT_EQ(layer_src_root->id(), layer_dest_root->id());
+ EXPECT_EQ(nullptr, layer_dest_root->parent());
+ ASSERT_EQ(1u, layer_dest_root->children().size());
+ EXPECT_EQ(layer_tree_host_.get(), layer_dest_root->layer_tree_host_);
+
+ scoped_refptr<Layer> layer_dest_a = layer_dest_root->children()[0];
+ EXPECT_EQ(layer_src_a->id(), layer_dest_a->id());
+ EXPECT_EQ(layer_src_root->id(), layer_dest_a->parent()->id());
+ EXPECT_EQ(1u, layer_dest_a->children().size());
+ EXPECT_EQ(layer_tree_host_.get(), layer_dest_a->layer_tree_host_);
+
+ scoped_refptr<Layer> layer_dest_b = layer_dest_a->children()[0];
+ EXPECT_EQ(layer_src_b->id(), layer_dest_b->id());
+ EXPECT_EQ(layer_src_a->id(), layer_dest_b->parent()->id());
+ ASSERT_EQ(1u, layer_dest_b->children().size());
+ EXPECT_EQ(layer_tree_host_.get(), layer_dest_b->layer_tree_host_);
+
+ scoped_refptr<Layer> layer_dest_c = layer_dest_b->children()[0];
+ EXPECT_EQ(layer_src_c->id(), layer_dest_c->id());
+ EXPECT_EQ(layer_src_b->id(), layer_dest_c->parent()->id());
+ EXPECT_EQ(0u, layer_dest_c->children().size());
+ EXPECT_EQ(layer_tree_host_.get(), layer_dest_c->layer_tree_host_);
+
+ // The layers have not been added to the LayerTreeHost layer map, so the
+ // LTH pointers must be cleared manually.
+ layer_dest_root->layer_tree_host_ = nullptr;
+ layer_dest_a->layer_tree_host_ = nullptr;
+ layer_dest_b->layer_tree_host_ = nullptr;
+ layer_dest_c->layer_tree_host_ = nullptr;
+ }
+
void RunNonDestructiveDeserializationBaseCaseTest() {
/* Testing serialization and deserialization of a tree that initially looks
like this:
@@ -2494,6 +2557,10 @@ TEST_F(LayerTest, DeleteMaskAndReplicaLayer) {
EXPECT_EQ(nullptr, layer_dest_root->replica_layer());
}
+TEST_F(LayerSerializationTest, HierarchyDeserializationWithLayerTreeHost) {
+ RunHierarchyDeserializationWithLayerTreeHostTest();
+}
+
TEST_F(LayerSerializationTest, NonDestructiveDeserializationBaseCase) {
RunNonDestructiveDeserializationBaseCaseTest();
}
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc
index 17c920f..0102db4 100644
--- a/cc/layers/picture_layer.cc
+++ b/cc/layers/picture_layer.cc
@@ -213,6 +213,12 @@ void PictureLayer::FromLayerSpecificPropertiesProto(
const proto::LayerProperties& proto) {
Layer::FromLayerSpecificPropertiesProto(proto);
const proto::PictureLayerProperties& picture = proto.picture();
+ // If this is a new layer, ensure it has a recording source. During layer
+ // hierarchy deserialization, ::SetLayerTreeHost(...) is not called, but
+ // instead the member is set directly, so it needs to be set here explicitly.
+ if (!recording_source_)
+ recording_source_.reset(new DisplayListRecordingSource);
+
recording_source_->FromProtobuf(
picture.recording_source(),
layer_tree_host()->image_serialization_processor());