diff options
author | nyquist <nyquist@chromium.org> | 2015-12-16 19:42:58 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-17 03:44:03 +0000 |
commit | b0a49d0498aaf994d7beb16b9faea0abbf9686a1 (patch) | |
tree | 52df1988af6565dabeeb6a56bd708096fd3f3d70 /cc | |
parent | e49beb5919261844887da24ba54c4507f60c45ac (diff) | |
download | chromium_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.cc | 193 | ||||
-rw-r--r-- | cc/layers/layer.h | 6 | ||||
-rw-r--r-- | cc/layers/layer_proto_converter_unittest.cc | 44 | ||||
-rw-r--r-- | cc/layers/layer_unittest.cc | 343 | ||||
-rw-r--r-- | cc/proto/layer.proto | 71 |
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; } |