summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authornyquist <nyquist@chromium.org>2015-12-16 19:42:58 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-17 03:44:03 +0000
commitb0a49d0498aaf994d7beb16b9faea0abbf9686a1 (patch)
tree52df1988af6565dabeeb6a56bd708096fd3f3d70 /cc
parente49beb5919261844887da24ba54c4507f60c45ac (diff)
downloadchromium_src-b0a49d0498aaf994d7beb16b9faea0abbf9686a1.zip
chromium_src-b0a49d0498aaf994d7beb16b9faea0abbf9686a1.tar.gz
chromium_src-b0a49d0498aaf994d7beb16b9faea0abbf9686a1.tar.bz2
Add support for (de)serializing base Layer properties
This CL adds support for serializing and deserializing the properties of the cc::Layer class that are important for passing from Layer->LayerImpl. It more or less copies the functionality of Layer::PushPropertiesTo(LayerImpl*), but instead of writing the data to LayerImpl, it writes the data to the LayerProperties proto. There are a few properties that are not serialized yet, but TODOs are added for these to ensure we will get to them later when the basic framework is working. BUG=538710 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1461543002 Cr-Commit-Position: refs/heads/master@{#365718}
Diffstat (limited to 'cc')
-rw-r--r--cc/layers/layer.cc193
-rw-r--r--cc/layers/layer.h6
-rw-r--r--cc/layers/layer_proto_converter_unittest.cc44
-rw-r--r--cc/layers/layer_unittest.cc343
-rw-r--r--cc/proto/layer.proto71
5 files changed, 644 insertions, 13 deletions
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 41fdd00..a3a79b4 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -27,7 +27,10 @@
#include "cc/layers/scrollbar_layer_interface.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
+#include "cc/proto/cc_conversions.h"
+#include "cc/proto/gfx_conversions.h"
#include "cc/proto/layer.pb.h"
+#include "cc/proto/skia_conversions.h"
#include "cc/trees/draw_property_utils.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_impl.h"
@@ -1463,15 +1466,197 @@ void Layer::FromLayerPropertiesProto(const proto::LayerProperties& proto) {
}
void Layer::LayerSpecificPropertiesToProto(proto::LayerProperties* proto) {
- // TODO(nyquist): Write all required properties to |proto|.
- // Create an empty proto::LayerProperties::base message.
- proto->mutable_base();
+ proto::BaseLayerProperties* base = proto->mutable_base();
+
+ bool use_paint_properties = layer_tree_host_ &&
+ paint_properties_.source_frame_number ==
+ layer_tree_host_->source_frame_number();
+
+ Point3FToProto(transform_origin_, base->mutable_transform_origin());
+ base->set_background_color(background_color_);
+ SizeToProto(use_paint_properties ? paint_properties_.bounds : bounds_,
+ base->mutable_bounds());
+
+ // TODO(nyquist): Figure out what to do with debug info. See crbug.com/570372.
+
+ base->set_transform_free_index(transform_tree_index_);
+ base->set_effect_tree_index(effect_tree_index_);
+ base->set_clip_tree_index(clip_tree_index_);
+ Vector2dFToProto(offset_to_transform_parent_,
+ base->mutable_offset_to_transform_parent());
+ base->set_double_sided(double_sided_);
+ base->set_draws_content(draws_content_);
+ base->set_hide_layer_and_subtree(hide_layer_and_subtree_);
+ base->set_has_render_surface(has_render_surface_);
+
+ // TODO(nyquist): Add support for serializing FilterOperations for
+ // |filters_| and |background_filters_|. See crbug.com/541321.
+
+ base->set_masks_to_bounds(masks_to_bounds_);
+ base->set_should_scroll_on_main_thread(should_scroll_on_main_thread_);
+ base->set_have_wheel_event_handlers(have_wheel_event_handlers_);
+ base->set_have_scroll_event_handlers(have_scroll_event_handlers_);
+ RegionToProto(non_fast_scrollable_region_,
+ base->mutable_non_fast_scrollable_region());
+ RegionToProto(touch_event_handler_region_,
+ base->mutable_touch_event_handler_region());
+ base->set_scroll_blocks_on(scroll_blocks_on_);
+ base->set_contents_opaque(contents_opaque_);
+ base->set_opacity(opacity_);
+ base->set_blend_mode(SkXfermodeModeToProto(blend_mode_));
+ base->set_is_root_for_isolated_group(is_root_for_isolated_group_);
+ PointFToProto(position_, base->mutable_position());
+ base->set_is_container_for_fixed_position_layers(
+ is_container_for_fixed_position_layers_);
+ position_constraint_.ToProtobuf(base->mutable_position_constraint());
+ base->set_should_flatten_transform(should_flatten_transform_);
+ base->set_should_flatten_transform_from_property_tree(
+ should_flatten_transform_from_property_tree_);
+ base->set_num_layer_or_descendants_with_copy_request(
+ num_layer_or_descendants_with_copy_request_);
+ base->set_draw_blend_mode(SkXfermodeModeToProto(draw_blend_mode_));
+ base->set_use_parent_backface_visibility(use_parent_backface_visibility_);
+ TransformToProto(transform_, base->mutable_transform());
+ base->set_transform_is_invertible(transform_is_invertible_);
+ base->set_sorting_context_id(sorting_context_id_);
+ base->set_num_descendants_that_draw_content(
+ num_descendants_that_draw_content_);
+
+ base->set_scroll_clip_layer_id(scroll_clip_layer_id_);
+ base->set_user_scrollable_horizontal(user_scrollable_horizontal_);
+ base->set_user_scrollable_vertical(user_scrollable_vertical_);
+
+ int scroll_parent_id = scroll_parent_ ? scroll_parent_->id() : INVALID_ID;
+ base->set_scroll_parent_id(scroll_parent_id);
+
+ if (scroll_children_) {
+ for (auto* child : *scroll_children_)
+ base->add_scroll_children_ids(child->id());
+ }
+
+ int clip_parent_id = clip_parent_ ? clip_parent_->id() : INVALID_ID;
+ base->set_clip_parent_id(clip_parent_id);
+
+ if (clip_children_) {
+ for (auto* child : *clip_children_)
+ base->add_clip_children_ids(child->id());
+ }
+
+ ScrollOffsetToProto(scroll_offset_, base->mutable_scroll_offset());
+ Vector2dFToProto(scroll_compensation_adjustment_,
+ base->mutable_scroll_compensation_adjustment());
+
+ // TODO(nyquist): Figure out what to do with CopyRequests.
+ // See crbug.com/570374.
+
+ RectToProto(update_rect_, base->mutable_update_rect());
+ base->set_stacking_order_changed(stacking_order_changed_);
+
+ // TODO(nyquist): Figure out what to do with LayerAnimationController.
+ // See crbug.com/570376.
+ // TODO(nyquist): Figure out what to do with FrameTimingRequests. See
+ // crbug.com/570377.
+
+ stacking_order_changed_ = false;
+ update_rect_ = gfx::Rect();
}
void Layer::FromLayerSpecificPropertiesProto(
const proto::LayerProperties& proto) {
DCHECK(proto.has_base());
- // TODO(nyquist): Read all required properties from |proto|.
+ DCHECK(layer_tree_host_);
+ const proto::BaseLayerProperties& base = proto.base();
+
+ transform_origin_ = ProtoToPoint3F(base.transform_origin());
+ background_color_ = base.background_color();
+ bounds_ = ProtoToSize(base.bounds());
+
+ transform_tree_index_ = base.transform_free_index();
+ effect_tree_index_ = base.effect_tree_index();
+ clip_tree_index_ = base.clip_tree_index();
+ offset_to_transform_parent_ =
+ ProtoToVector2dF(base.offset_to_transform_parent());
+ double_sided_ = base.double_sided();
+ draws_content_ = base.draws_content();
+ hide_layer_and_subtree_ = base.hide_layer_and_subtree();
+ has_render_surface_ = base.has_render_surface();
+ masks_to_bounds_ = base.masks_to_bounds();
+ should_scroll_on_main_thread_ = base.should_scroll_on_main_thread();
+ have_wheel_event_handlers_ = base.have_wheel_event_handlers();
+ have_scroll_event_handlers_ = base.have_scroll_event_handlers();
+ non_fast_scrollable_region_ =
+ RegionFromProto(base.non_fast_scrollable_region());
+ touch_event_handler_region_ =
+ RegionFromProto(base.touch_event_handler_region());
+ scroll_blocks_on_ = (ScrollBlocksOn)base.scroll_blocks_on();
+ contents_opaque_ = base.contents_opaque();
+ opacity_ = base.opacity();
+ blend_mode_ = SkXfermodeModeFromProto(base.blend_mode());
+ is_root_for_isolated_group_ = base.is_root_for_isolated_group();
+ position_ = ProtoToPointF(base.position());
+ is_container_for_fixed_position_layers_ =
+ base.is_container_for_fixed_position_layers();
+ position_constraint_.FromProtobuf(base.position_constraint());
+ should_flatten_transform_ = base.should_flatten_transform();
+ should_flatten_transform_from_property_tree_ =
+ base.should_flatten_transform_from_property_tree();
+ num_layer_or_descendants_with_copy_request_ =
+ base.num_layer_or_descendants_with_copy_request();
+ draw_blend_mode_ = SkXfermodeModeFromProto(base.draw_blend_mode());
+ use_parent_backface_visibility_ = base.use_parent_backface_visibility();
+ transform_ = ProtoToTransform(base.transform());
+ transform_is_invertible_ = base.transform_is_invertible();
+ sorting_context_id_ = base.sorting_context_id();
+ num_descendants_that_draw_content_ = base.num_descendants_that_draw_content();
+
+ scroll_clip_layer_id_ = base.scroll_clip_layer_id();
+ user_scrollable_horizontal_ = base.user_scrollable_horizontal();
+ user_scrollable_vertical_ = base.user_scrollable_vertical();
+
+ scroll_parent_ = base.scroll_parent_id() == INVALID_ID
+ ? nullptr
+ : layer_tree_host_->LayerById(base.scroll_parent_id());
+
+ // If there have been scroll children entries in previous deserializations,
+ // clear out the set. If there have been none, initialize the set of children.
+ // After this, the set is in the correct state to only add the new children.
+ // If the set of children has not changed, for now this code still rebuilds
+ // the set.
+ if (scroll_children_)
+ scroll_children_->clear();
+ else if (base.scroll_children_ids_size() > 0)
+ scroll_children_.reset(new std::set<Layer*>);
+ for (int i = 0; i < base.scroll_children_ids_size(); ++i) {
+ int child_id = base.scroll_children_ids(i);
+ scoped_refptr<Layer> child = layer_tree_host_->LayerById(child_id);
+ scroll_children_->insert(child.get());
+ }
+
+ clip_parent_ = base.clip_parent_id() == INVALID_ID
+ ? nullptr
+ : layer_tree_host_->LayerById(base.clip_parent_id());
+
+ // If there have been clip children entries in previous deserializations,
+ // clear out the set. If there have been none, initialize the set of children.
+ // After this, the set is in the correct state to only add the new children.
+ // If the set of children has not changed, for now this code still rebuilds
+ // the set.
+ if (clip_children_)
+ clip_children_->clear();
+ else if (base.clip_children_ids_size() > 0)
+ clip_children_.reset(new std::set<Layer*>);
+ for (int i = 0; i < base.clip_children_ids_size(); ++i) {
+ int child_id = base.clip_children_ids(i);
+ scoped_refptr<Layer> child = layer_tree_host_->LayerById(child_id);
+ clip_children_->insert(child.get());
+ }
+
+ scroll_offset_ = ProtoToScrollOffset(base.scroll_offset());
+ scroll_compensation_adjustment_ =
+ ProtoToVector2dF(base.scroll_compensation_adjustment());
+
+ update_rect_.Union(ProtoToRect(base.update_rect()));
+ stacking_order_changed_ = base.stacking_order_changed();
}
scoped_ptr<LayerImpl> Layer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index f87d18d..06669d3 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -623,7 +623,9 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
// |needs_push_properties_| or |num_dependents_need_push_properties_| as they
// are dealt with at a higher level. This is only called if
// |needs_push_properties_| is set. For descendants of Layer, implementations
- // must first call their parent class.
+ // must first call their parent class. This method is not marked as const
+ // as some implementations need reset member fields, similarly to
+ // PushPropertiesTo().
virtual void LayerSpecificPropertiesToProto(proto::LayerProperties* proto);
// Deserialize all the necessary properties from proto::LayerProperties into
@@ -669,7 +671,9 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
private:
friend class base::RefCounted<Layer>;
+ friend class LayerSerializationTest;
friend class LayerTreeHostCommon;
+
void SetParent(Layer* layer);
bool DescendantIsFixedToContainerLayer() const;
diff --git a/cc/layers/layer_proto_converter_unittest.cc b/cc/layers/layer_proto_converter_unittest.cc
index 1e5fa40..0a85b44 100644
--- a/cc/layers/layer_proto_converter_unittest.cc
+++ b/cc/layers/layer_proto_converter_unittest.cc
@@ -7,12 +7,36 @@
#include "cc/layers/layer.h"
#include "cc/layers/layer_settings.h"
#include "cc/proto/layer.pb.h"
+#include "cc/test/fake_layer_tree_host.h"
+#include "cc/test/fake_layer_tree_host_client.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_settings.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
-
-TEST(LayerProtoConverterTest, TestKeepingRoot) {
+namespace {
+class LayerProtoConverterTest : public testing::Test {
+ public:
+ LayerProtoConverterTest()
+ : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {}
+
+ protected:
+ void SetUp() override {
+ layer_tree_host_ =
+ FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
+ }
+
+ void TearDown() override {
+ layer_tree_host_->SetRootLayer(nullptr);
+ layer_tree_host_ = nullptr;
+ }
+
+ TestTaskGraphRunner task_graph_runner_;
+ FakeLayerTreeHostClient fake_client_;
+ scoped_ptr<FakeLayerTreeHost> layer_tree_host_;
+};
+
+TEST_F(LayerProtoConverterTest, TestKeepingRoot) {
/* Test deserialization of a tree that looks like:
root
/ \
@@ -60,7 +84,7 @@ TEST(LayerProtoConverterTest, TestKeepingRoot) {
EXPECT_EQ(child_c_node->id(), child_c->id());
}
-TEST(LayerProtoConverterTest, TestSwappingRoot) {
+TEST_F(LayerProtoConverterTest, TestSwappingRoot) {
/* Test deserialization of a tree that looks like:
root
/ \
@@ -108,7 +132,7 @@ TEST(LayerProtoConverterTest, TestSwappingRoot) {
EXPECT_EQ(child_c_node->id(), child_c->id());
}
-TEST(LayerProtoConverterTest, RecursivePropertiesSerialization) {
+TEST_F(LayerProtoConverterTest, RecursivePropertiesSerialization) {
/* Testing serialization of properties for a tree that looks like this:
root+
/ \
@@ -193,7 +217,7 @@ TEST(LayerProtoConverterTest, RecursivePropertiesSerialization) {
EXPECT_TRUE(dest_b_mask.has_base());
}
-TEST(LayerProtoConverterTest, RecursivePropertiesSerializationSingleChild) {
+TEST_F(LayerProtoConverterTest, RecursivePropertiesSerializationSingleChild) {
/* Testing serialization of properties for a tree that looks like this:
root+
\
@@ -252,7 +276,7 @@ TEST(LayerProtoConverterTest, RecursivePropertiesSerializationSingleChild) {
EXPECT_TRUE(dest_b_mask.has_base());
}
-TEST(LayerProtoConverterTest, DeserializeLayerProperties) {
+TEST_F(LayerProtoConverterTest, DeserializeLayerProperties) {
/* Testing deserialization of properties for a tree that looks like this:
root*+
/ \
@@ -265,6 +289,7 @@ TEST(LayerProtoConverterTest, DeserializeLayerProperties) {
proto::LayerUpdate updates;
scoped_refptr<Layer> root = Layer::Create(LayerSettings());
+ root->SetLayerTreeHost(layer_tree_host_.get());
proto::LayerProperties* root_props = updates.add_layers();
root_props->set_id(root->id());
root_props->set_needs_push_properties(true);
@@ -272,6 +297,7 @@ TEST(LayerProtoConverterTest, DeserializeLayerProperties) {
root_props->mutable_base();
scoped_refptr<Layer> a = Layer::Create(LayerSettings());
+ a->SetLayerTreeHost(layer_tree_host_.get());
proto::LayerProperties* a_props = updates.add_layers();
a_props->set_id(a->id());
a_props->set_needs_push_properties(false);
@@ -279,6 +305,7 @@ TEST(LayerProtoConverterTest, DeserializeLayerProperties) {
root->AddChild(a);
scoped_refptr<Layer> b = Layer::Create(LayerSettings());
+ b->SetLayerTreeHost(layer_tree_host_.get());
proto::LayerProperties* b_props = updates.add_layers();
b_props->set_id(b->id());
b_props->set_needs_push_properties(false);
@@ -286,6 +313,7 @@ TEST(LayerProtoConverterTest, DeserializeLayerProperties) {
root->AddChild(b);
scoped_refptr<Layer> c = Layer::Create(LayerSettings());
+ c->SetLayerTreeHost(layer_tree_host_.get());
proto::LayerProperties* c_props = updates.add_layers();
c_props->set_id(c->id());
c_props->set_needs_push_properties(true);
@@ -306,6 +334,10 @@ TEST(LayerProtoConverterTest, DeserializeLayerProperties) {
EXPECT_TRUE(c->needs_push_properties());
EXPECT_FALSE(c->descendant_needs_push_properties());
+
+ // Recursively clear out LayerTreeHost.
+ root->SetLayerTreeHost(nullptr);
}
+} // namespace
} // namespace cc
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc
index 856dabf..789152a 100644
--- a/cc/layers/layer_unittest.cc
+++ b/cc/layers/layer_unittest.cc
@@ -15,6 +15,7 @@
#include "cc/proto/layer.pb.h"
#include "cc/test/animation_test_common.h"
#include "cc/test/fake_impl_task_runner_provider.h"
+#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/geometry_test_utils.h"
@@ -26,6 +27,12 @@
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/geometry/point3_f.h"
+#include "ui/gfx/geometry/point_f.h"
+#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/transform.h"
using ::testing::AnyNumber;
@@ -42,6 +49,321 @@ using ::testing::_;
} while (false)
namespace cc {
+
+// This class is a friend of Layer, and is used as a wrapper for all the tests
+// related to proto serialization. This is done so that it is unnecessary to
+// add FRIEND_TEST_ALL_PREFIXES in //cc/layers/layer.h for all the tests.
+// It is in the cc namespace so that it can be a friend of Layer.
+// The tests still have helpful names, and a test with the name FooBar would
+// have a wrapper method in this class called RunFooBarTest.
+class LayerSerializationTest : public testing::Test {
+ public:
+ LayerSerializationTest() : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {}
+
+ protected:
+ void SetUp() override {
+ layer_tree_host_ =
+ FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
+ }
+
+ void TearDown() override {
+ layer_tree_host_->SetRootLayer(nullptr);
+ layer_tree_host_ = nullptr;
+ }
+
+ // Serializes |src| to proto and back again to a Layer, then verifies that
+ // the two Layers are equal for serialization purposes.
+ void VerifyBaseLayerPropertiesSerializationAndDeserialization(Layer* src) {
+ // This is required to ensure that properties are serialized.
+ src->SetNeedsPushProperties();
+ src->SetLayerTreeHost(layer_tree_host_.get());
+
+ // The following two members are reset during serialization, so
+ // store the original values.
+ bool stacking_order_changed = src->stacking_order_changed_;
+ gfx::Rect update_rect = src->update_rect_;
+
+ // Serialize |src| to protobuf and read the first entry in the
+ // LayerUpdate. There are no descendants, so the serialization
+ // of |src| is the only entry.
+ proto::LayerUpdate layer_update;
+ EXPECT_FALSE(src->ToLayerPropertiesProto(&layer_update));
+ ASSERT_EQ(1, layer_update.layers_size());
+ proto::LayerProperties props = layer_update.layers(0);
+
+ // The |dest| layer needs to be able to lookup the scroll and clip parents.
+ if (src->scroll_parent_)
+ layer_tree_host_->RegisterLayer(src->scroll_parent_);
+ if (src->scroll_children_) {
+ for (auto* child : *(src->scroll_children_))
+ layer_tree_host_->RegisterLayer(child);
+ }
+ if (src->clip_parent_)
+ layer_tree_host_->RegisterLayer(src->clip_parent_);
+ if (src->clip_children_) {
+ for (auto* child : *(src->clip_children_))
+ layer_tree_host_->RegisterLayer(child);
+ }
+ // Reset the LayerTreeHost registration for the |src| layer so
+ // it can be re-used for the |dest| layer.
+ src->SetLayerTreeHost(nullptr);
+
+ scoped_refptr<Layer> dest = Layer::Create(LayerSettings());
+ dest->layer_id_ = src->layer_id_;
+ dest->SetLayerTreeHost(layer_tree_host_.get());
+ dest->FromLayerPropertiesProto(props);
+
+ // Verify that both layers are equal.
+ EXPECT_EQ(src->transform_origin_, dest->transform_origin_);
+ EXPECT_EQ(src->background_color_, dest->background_color_);
+ EXPECT_EQ(src->bounds_, dest->bounds_);
+ EXPECT_EQ(src->transform_tree_index_, dest->transform_tree_index_);
+ EXPECT_EQ(src->effect_tree_index_, dest->effect_tree_index_);
+ EXPECT_EQ(src->clip_tree_index_, dest->clip_tree_index_);
+ EXPECT_EQ(src->offset_to_transform_parent_,
+ dest->offset_to_transform_parent_);
+ EXPECT_EQ(src->double_sided_, dest->double_sided_);
+ EXPECT_EQ(src->draws_content_, dest->draws_content_);
+ EXPECT_EQ(src->hide_layer_and_subtree_, dest->hide_layer_and_subtree_);
+ EXPECT_EQ(src->has_render_surface_, dest->has_render_surface_);
+ EXPECT_EQ(src->masks_to_bounds_, dest->masks_to_bounds_);
+ EXPECT_EQ(src->should_scroll_on_main_thread_,
+ dest->should_scroll_on_main_thread_);
+ EXPECT_EQ(src->have_wheel_event_handlers_,
+ dest->have_wheel_event_handlers_);
+ EXPECT_EQ(src->have_scroll_event_handlers_,
+ dest->have_scroll_event_handlers_);
+ EXPECT_EQ(src->non_fast_scrollable_region_,
+ dest->non_fast_scrollable_region_);
+ EXPECT_EQ(src->touch_event_handler_region_,
+ dest->touch_event_handler_region_);
+ EXPECT_EQ(src->scroll_blocks_on_, dest->scroll_blocks_on_);
+ EXPECT_EQ(src->contents_opaque_, dest->contents_opaque_);
+ EXPECT_EQ(src->opacity_, dest->opacity_);
+ EXPECT_EQ(src->blend_mode_, dest->blend_mode_);
+ EXPECT_EQ(src->is_root_for_isolated_group_,
+ dest->is_root_for_isolated_group_);
+ EXPECT_EQ(src->position_, dest->position_);
+ EXPECT_EQ(src->is_container_for_fixed_position_layers_,
+ dest->is_container_for_fixed_position_layers_);
+ EXPECT_EQ(src->position_constraint_, dest->position_constraint_);
+ EXPECT_EQ(src->should_flatten_transform_, dest->should_flatten_transform_);
+ EXPECT_EQ(src->should_flatten_transform_from_property_tree_,
+ dest->should_flatten_transform_from_property_tree_);
+ EXPECT_EQ(src->num_layer_or_descendants_with_copy_request_,
+ dest->num_layer_or_descendants_with_copy_request_);
+ EXPECT_EQ(src->draw_blend_mode_, dest->draw_blend_mode_);
+ EXPECT_EQ(src->use_parent_backface_visibility_,
+ dest->use_parent_backface_visibility_);
+ EXPECT_EQ(src->transform_, dest->transform_);
+ EXPECT_EQ(src->transform_is_invertible_, dest->transform_is_invertible_);
+ EXPECT_EQ(src->sorting_context_id_, dest->sorting_context_id_);
+ EXPECT_EQ(src->num_descendants_that_draw_content_,
+ dest->num_descendants_that_draw_content_);
+ EXPECT_EQ(src->scroll_clip_layer_id_, dest->scroll_clip_layer_id_);
+ EXPECT_EQ(src->user_scrollable_horizontal_,
+ dest->user_scrollable_horizontal_);
+ EXPECT_EQ(src->user_scrollable_vertical_, dest->user_scrollable_vertical_);
+ EXPECT_EQ(src->scroll_offset_, dest->scroll_offset_);
+ EXPECT_EQ(src->scroll_compensation_adjustment_,
+ dest->scroll_compensation_adjustment_);
+ EXPECT_EQ(update_rect, dest->update_rect_);
+ EXPECT_EQ(stacking_order_changed, dest->stacking_order_changed_);
+
+ if (src->scroll_parent_) {
+ ASSERT_TRUE(dest->scroll_parent_);
+ EXPECT_EQ(src->scroll_parent_->id(), dest->scroll_parent_->id());
+ } else {
+ EXPECT_FALSE(dest->scroll_parent_);
+ }
+ if (src->scroll_children_) {
+ ASSERT_TRUE(dest->scroll_children_);
+ EXPECT_EQ(*(src->scroll_children_), *(dest->scroll_children_));
+ } else {
+ EXPECT_FALSE(dest->scroll_children_);
+ }
+
+ if (src->clip_parent_) {
+ ASSERT_TRUE(dest->clip_parent_);
+ EXPECT_EQ(src->clip_parent_->id(), dest->clip_parent_->id());
+ } else {
+ ASSERT_FALSE(dest->clip_parent_);
+ }
+ if (src->clip_children_) {
+ ASSERT_TRUE(dest->clip_children_);
+ EXPECT_EQ(*(src->clip_children_), *(dest->clip_children_));
+ } else {
+ EXPECT_FALSE(dest->clip_children_);
+ }
+
+ // The following two members should have been reset during serialization.
+ EXPECT_FALSE(src->stacking_order_changed_);
+ EXPECT_EQ(gfx::Rect(), src->update_rect_);
+
+ // Before deleting |dest|, the LayerTreeHost must be unset.
+ dest->SetLayerTreeHost(nullptr);
+
+ // Cleanup scroll tree.
+ if (src->scroll_parent_)
+ layer_tree_host_->UnregisterLayer(src->scroll_parent_);
+ src->scroll_parent_ = nullptr;
+ dest->scroll_parent_ = nullptr;
+ if (src->scroll_children_) {
+ for (auto* child : *(src->scroll_children_))
+ layer_tree_host_->UnregisterLayer(child);
+ src->scroll_children_.reset();
+ dest->scroll_children_.reset();
+ }
+
+ // Cleanup clip tree.
+ if (src->clip_parent_)
+ layer_tree_host_->UnregisterLayer(src->clip_parent_);
+ src->clip_parent_ = nullptr;
+ dest->clip_parent_ = nullptr;
+ if (src->clip_children_) {
+ for (auto* child : *(src->clip_children_))
+ layer_tree_host_->UnregisterLayer(child);
+ src->clip_children_.reset();
+ dest->clip_children_.reset();
+ }
+ }
+
+ void RunNoMembersChangedTest() {
+ scoped_refptr<Layer> layer = Layer::Create(LayerSettings());
+ VerifyBaseLayerPropertiesSerializationAndDeserialization(layer.get());
+ }
+
+ void RunArbitraryMembersChangedTest() {
+ scoped_refptr<Layer> layer = Layer::Create(LayerSettings());
+ layer->transform_origin_ = gfx::Point3F(3.0f, 1.0f, 4.0f);
+ layer->background_color_ = SK_ColorRED;
+ layer->bounds_ = gfx::Size(3, 14);
+ layer->transform_tree_index_ = -1;
+ layer->effect_tree_index_ = -1;
+ layer->clip_tree_index_ = 71;
+ layer->offset_to_transform_parent_ = gfx::Vector2dF(3.14f, 1.618f);
+ layer->double_sided_ = true;
+ layer->draws_content_ = true;
+ layer->hide_layer_and_subtree_ = false;
+ layer->has_render_surface_ = false;
+ layer->masks_to_bounds_ = true;
+ layer->should_scroll_on_main_thread_ = false;
+ layer->have_wheel_event_handlers_ = true;
+ layer->have_scroll_event_handlers_ = false;
+ layer->non_fast_scrollable_region_ = Region(gfx::Rect(5, 1, 14, 3));
+ layer->touch_event_handler_region_ = Region(gfx::Rect(3, 14, 1, 5));
+ layer->scroll_blocks_on_ = SCROLL_BLOCKS_ON_NONE;
+ layer->contents_opaque_ = true;
+ layer->opacity_ = 1.f;
+ layer->blend_mode_ = SkXfermode::kSrcOver_Mode;
+ layer->is_root_for_isolated_group_ = true;
+ layer->position_ = gfx::PointF(3.14f, 6.28f);
+ layer->is_container_for_fixed_position_layers_ = true;
+ LayerPositionConstraint pos_con;
+ pos_con.set_is_fixed_to_bottom_edge(true);
+ layer->position_constraint_ = pos_con;
+ layer->should_flatten_transform_ = true;
+ layer->should_flatten_transform_from_property_tree_ = true;
+ layer->num_layer_or_descendants_with_copy_request_ = 19;
+ layer->draw_blend_mode_ = SkXfermode::kSrcOut_Mode;
+ layer->use_parent_backface_visibility_ = true;
+ gfx::Transform transform;
+ transform.Rotate(90);
+ layer->transform_ = transform;
+ layer->transform_is_invertible_ = true;
+ layer->sorting_context_id_ = 0;
+ layer->num_descendants_that_draw_content_ = 5;
+ layer->scroll_clip_layer_id_ = Layer::INVALID_ID;
+ layer->user_scrollable_horizontal_ = false;
+ layer->user_scrollable_vertical_ = true;
+ layer->scroll_offset_ = gfx::ScrollOffset(3, 14);
+ layer->scroll_compensation_adjustment_ = gfx::Vector2dF(6.28f, 3.14f);
+ layer->update_rect_ = gfx::Rect(14, 15);
+ layer->stacking_order_changed_ = true;
+
+ VerifyBaseLayerPropertiesSerializationAndDeserialization(layer.get());
+ }
+
+ void RunAllMembersChangedTest() {
+ scoped_refptr<Layer> layer = Layer::Create(LayerSettings());
+ layer->transform_origin_ = gfx::Point3F(3.0f, 1.0f, 4.0f);
+ layer->background_color_ = SK_ColorRED;
+ layer->bounds_ = gfx::Size(3, 14);
+ layer->transform_tree_index_ = 39;
+ layer->effect_tree_index_ = 17;
+ layer->clip_tree_index_ = 71;
+ layer->offset_to_transform_parent_ = gfx::Vector2dF(3.14f, 1.618f);
+ layer->double_sided_ = !layer->double_sided_;
+ layer->draws_content_ = !layer->draws_content_;
+ layer->hide_layer_and_subtree_ = !layer->hide_layer_and_subtree_;
+ layer->has_render_surface_ = !layer->has_render_surface_;
+ layer->masks_to_bounds_ = !layer->masks_to_bounds_;
+ layer->should_scroll_on_main_thread_ =
+ !layer->should_scroll_on_main_thread_;
+ layer->have_wheel_event_handlers_ = !layer->have_wheel_event_handlers_;
+ layer->have_scroll_event_handlers_ = !layer->have_scroll_event_handlers_;
+ layer->non_fast_scrollable_region_ = Region(gfx::Rect(5, 1, 14, 3));
+ layer->touch_event_handler_region_ = Region(gfx::Rect(3, 14, 1, 5));
+ layer->scroll_blocks_on_ = SCROLL_BLOCKS_ON_WHEEL_EVENT;
+ layer->contents_opaque_ = !layer->contents_opaque_;
+ layer->opacity_ = 3.14f;
+ layer->blend_mode_ = SkXfermode::kSrcIn_Mode;
+ layer->is_root_for_isolated_group_ = !layer->is_root_for_isolated_group_;
+ layer->position_ = gfx::PointF(3.14f, 6.28f);
+ layer->is_container_for_fixed_position_layers_ =
+ !layer->is_container_for_fixed_position_layers_;
+ LayerPositionConstraint pos_con;
+ pos_con.set_is_fixed_to_bottom_edge(true);
+ layer->position_constraint_ = pos_con;
+ layer->should_flatten_transform_ = !layer->should_flatten_transform_;
+ layer->should_flatten_transform_from_property_tree_ =
+ !layer->should_flatten_transform_from_property_tree_;
+ layer->num_layer_or_descendants_with_copy_request_ = 19;
+ layer->draw_blend_mode_ = SkXfermode::kSrcOut_Mode;
+ layer->use_parent_backface_visibility_ =
+ !layer->use_parent_backface_visibility_;
+ gfx::Transform transform;
+ transform.Rotate(90);
+ layer->transform_ = transform;
+ layer->transform_is_invertible_ = !layer->transform_is_invertible_;
+ layer->sorting_context_id_ = 42;
+ layer->num_descendants_that_draw_content_ = 5;
+ layer->scroll_clip_layer_id_ = 17;
+ layer->user_scrollable_horizontal_ = !layer->user_scrollable_horizontal_;
+ layer->user_scrollable_vertical_ = !layer->user_scrollable_vertical_;
+ layer->scroll_offset_ = gfx::ScrollOffset(3, 14);
+ layer->scroll_compensation_adjustment_ = gfx::Vector2dF(6.28f, 3.14f);
+ layer->update_rect_ = gfx::Rect(14, 15);
+ layer->stacking_order_changed_ = !layer->stacking_order_changed_;
+
+ VerifyBaseLayerPropertiesSerializationAndDeserialization(layer.get());
+ }
+
+ void RunScrollAndClipLayersTest() {
+ scoped_refptr<Layer> layer = Layer::Create(LayerSettings());
+
+ scoped_refptr<Layer> scroll_parent = Layer::Create(LayerSettings());
+ layer->scroll_parent_ = scroll_parent.get();
+ scoped_refptr<Layer> scroll_child = Layer::Create(LayerSettings());
+ layer->scroll_children_.reset(new std::set<Layer*>);
+ layer->scroll_children_->insert(scroll_child.get());
+
+ scoped_refptr<Layer> clip_parent = Layer::Create(LayerSettings());
+ layer->clip_parent_ = clip_parent.get();
+ layer->clip_children_.reset(new std::set<Layer*>);
+ scoped_refptr<Layer> clip_child1 = Layer::Create(LayerSettings());
+ layer->clip_children_->insert(clip_child1.get());
+ scoped_refptr<Layer> clip_child2 = Layer::Create(LayerSettings());
+ layer->clip_children_->insert(clip_child2.get());
+
+ VerifyBaseLayerPropertiesSerializationAndDeserialization(layer.get());
+ }
+
+ TestTaskGraphRunner task_graph_runner_;
+ FakeLayerTreeHostClient fake_client_;
+ scoped_ptr<FakeLayerTreeHost> layer_tree_host_;
+};
+
namespace {
class MockLayerTreeHost : public LayerTreeHost {
@@ -1678,8 +2000,9 @@ TEST_F(LayerTest, SimplePropertiesSerialization) {
EXPECT_TRUE(dest_b_mask.has_base());
}
-TEST_F(LayerTest, SimplePropertiesDeserialization) {
+TEST_F(LayerSerializationTest, SimplePropertiesDeserialization) {
scoped_refptr<Layer> layer = Layer::Create(LayerSettings());
+ layer->SetLayerTreeHost(layer_tree_host_.get());
proto::LayerProperties properties;
properties.set_id(layer->id());
@@ -1706,6 +2029,24 @@ TEST_F(LayerTest, SimplePropertiesDeserialization) {
layer->FromLayerPropertiesProto(properties);
EXPECT_TRUE(layer->needs_push_properties());
EXPECT_FALSE(layer->descendant_needs_push_properties());
+
+ layer->SetLayerTreeHost(nullptr);
+}
+
+TEST_F(LayerSerializationTest, NoMembersChanged) {
+ RunNoMembersChangedTest();
+}
+
+TEST_F(LayerSerializationTest, ArbitraryMembersChanged) {
+ RunArbitraryMembersChangedTest();
+}
+
+TEST_F(LayerSerializationTest, AllMembersChanged) {
+ RunAllMembersChangedTest();
+}
+
+TEST_F(LayerSerializationTest, ScrollAndClipLayers) {
+ RunScrollAndClipLayersTest();
}
TEST_F(LayerTest, ElementIdAndMutablePropertiesArePushed) {
diff --git a/cc/proto/layer.proto b/cc/proto/layer.proto
index 914ff8a..d7b3ce3 100644
--- a/cc/proto/layer.proto
+++ b/cc/proto/layer.proto
@@ -4,6 +4,17 @@
syntax = "proto2";
+import "layer_position_constraint.proto";
+import "point3f.proto";
+import "pointf.proto";
+import "region.proto";
+import "rect.proto";
+import "scroll_offset.proto";
+import "size.proto";
+import "skxfermode.proto";
+import "transform.proto";
+import "vector2df.proto";
+
package cc.proto;
option optimize_for = LITE_RUNTIME;
@@ -50,5 +61,63 @@ message LayerProperties {
}
message BaseLayerProperties {
- // TODO(nyquist): Add all the required properties below. Huzzah!
+ optional Point3F transform_origin = 1;
+ optional uint32 background_color = 2;
+ optional Size bounds = 3;
+ optional int64 transform_free_index = 4;
+ optional int64 effect_tree_index = 5;
+ optional int64 clip_tree_index = 6;
+ optional Vector2dF offset_to_transform_parent = 7;
+ optional bool double_sided = 8;
+ optional bool draws_content = 9;
+ optional bool hide_layer_and_subtree = 10;
+ optional bool has_render_surface = 11;
+ // TODO(nyquist): Add support for FilterOperation. See crbug.com/541321.
+ // repeated FilterOperation filters = 12;
+ // repeated FilterOperation background_filters = 13;
+ optional bool masks_to_bounds = 14;
+ optional bool should_scroll_on_main_thread = 15;
+ optional bool have_wheel_event_handlers = 16;
+ optional bool have_scroll_event_handlers = 17;
+ optional Region non_fast_scrollable_region = 18;
+ optional Region touch_event_handler_region = 19;
+ optional int32 scroll_blocks_on = 20;
+ optional bool contents_opaque = 21;
+ optional float opacity = 22;
+ optional SkXfermode.Mode blend_mode = 23;
+ optional bool is_root_for_isolated_group = 24;
+ optional PointF position = 25;
+ optional bool is_container_for_fixed_position_layers = 26;
+ optional LayerPositionConstraint position_constraint = 27;
+ optional bool should_flatten_transform = 28;
+ optional bool should_flatten_transform_from_property_tree = 29;
+ optional int32 num_layer_or_descendants_with_copy_request = 30;
+ optional SkXfermode.Mode draw_blend_mode = 31;
+ optional bool use_parent_backface_visibility = 32;
+ optional Transform transform = 33;
+ optional bool transform_is_invertible = 34;
+ optional int32 sorting_context_id = 35;
+ optional int32 num_descendants_that_draw_content = 36;
+
+ optional int32 scroll_clip_layer_id = 37;
+ optional bool user_scrollable_horizontal = 38;
+ optional bool user_scrollable_vertical = 39;
+
+ optional int32 scroll_parent_id = 40;
+ repeated int32 scroll_children_ids = 41;
+
+ optional int32 clip_parent_id = 42;
+ repeated int32 clip_children_ids = 43;
+
+ optional ScrollOffset scroll_offset = 44;
+ optional Vector2dF scroll_compensation_adjustment = 45;
+
+ optional Rect update_rect = 46;
+ optional bool stacking_order_changed = 47;
+
+ // TODO(nyquist): Figure out what to do with LayerAnimationController.
+ // optional LayerAnimationController layer_animation_controller = 48;
+
+ // TODO(nyquist): Figure out what to do with FrameTimingRequests.
+ // repeated FrameTimingRequest frame_timing_requests = 49;
}