summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authornyquist <nyquist@chromium.org>2016-01-14 09:40:36 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-14 17:42:27 +0000
commit4f5e8afdadf36c01a01467abb441be357db6d142 (patch)
tree22707f5ed1e788415b2991d52f0878edd0d4f73f /cc
parent4f2151064444e40f0550f0cc312268550f25aa4b (diff)
downloadchromium_src-4f5e8afdadf36c01a01467abb441be357db6d142.zip
chromium_src-4f5e8afdadf36c01a01467abb441be357db6d142.tar.gz
chromium_src-4f5e8afdadf36c01a01467abb441be357db6d142.tar.bz2
Add support for (de)serializing LayerTreeHost.
As part of the cc commit flow, we need to be able to serialize the LayerTreeHost. Not all state is necessary to serialize to be able to do a commit on the client side, so only some members are included in the proto. BUG=561210 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1519293002 Cr-Commit-Position: refs/heads/master@{#369450}
Diffstat (limited to 'cc')
-rw-r--r--cc/BUILD.gn1
-rw-r--r--cc/cc.gyp1
-rw-r--r--cc/cc_tests.gyp1
-rw-r--r--cc/proto/BUILD.gn1
-rw-r--r--cc/proto/layer_tree_host.proto56
-rw-r--r--cc/trees/layer_tree_host.cc163
-rw-r--r--cc/trees/layer_tree_host.h16
-rw-r--r--cc/trees/layer_tree_host_unittest_serialization.cc313
8 files changed, 552 insertions, 0 deletions
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 48b5106..fa11da8 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -891,6 +891,7 @@ test("cc_unittests") {
"trees/layer_tree_host_unittest_proxy.cc",
"trees/layer_tree_host_unittest_record_gpu_histogram.cc",
"trees/layer_tree_host_unittest_scroll.cc",
+ "trees/layer_tree_host_unittest_serialization.cc",
"trees/layer_tree_host_unittest_video.cc",
"trees/layer_tree_impl_unittest.cc",
"trees/layer_tree_settings_unittest.cc",
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 061ccdc..19762e1 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -610,6 +610,7 @@
'proto/layer.proto',
'proto/layer_position_constraint.proto',
'proto/layer_tree_debug_state.proto',
+ 'proto/layer_tree_host.proto',
'proto/layer_tree_settings.proto',
'proto/layer_selection_bound.proto',
'proto/managed_memory_policy.proto',
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index ecffd21..ff16a5a 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -144,6 +144,7 @@
'trees/layer_tree_host_unittest_proxy.cc',
'trees/layer_tree_host_unittest_record_gpu_histogram.cc',
'trees/layer_tree_host_unittest_scroll.cc',
+ 'trees/layer_tree_host_unittest_serialization.cc',
'trees/layer_tree_host_unittest_video.cc',
'trees/layer_tree_impl_unittest.cc',
'trees/layer_tree_settings_unittest.cc',
diff --git a/cc/proto/BUILD.gn b/cc/proto/BUILD.gn
index 2548e59..0817160 100644
--- a/cc/proto/BUILD.gn
+++ b/cc/proto/BUILD.gn
@@ -36,6 +36,7 @@ proto_library("proto_internal") {
"layer_position_constraint.proto",
"layer_selection_bound.proto",
"layer_tree_debug_state.proto",
+ "layer_tree_host.proto",
"layer_tree_settings.proto",
"managed_memory_policy.proto",
"memory_allocation.proto",
diff --git a/cc/proto/layer_tree_host.proto b/cc/proto/layer_tree_host.proto
new file mode 100644
index 0000000..432c1f6
--- /dev/null
+++ b/cc/proto/layer_tree_host.proto
@@ -0,0 +1,56 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto2";
+
+import "layer.proto";
+import "layer_selection_bound.proto";
+import "layer_tree_settings.proto";
+import "layer_tree_debug_state.proto";
+import "property_tree.proto";
+import "size.proto";
+import "vector2df.proto";
+
+package cc.proto;
+
+option optimize_for = LITE_RUNTIME;
+
+message LayerTreeHost {
+ // Not all members of LayerTreeHost are serialized, as they are not helpful
+ // for remote usage. See implementation of
+ // cc::LayerTreeHost::ToProtobufForCommit for details.
+ optional bool needs_full_tree_sync = 1;
+ optional bool needs_meta_info_recomputation = 2;
+ optional int32 source_frame_number = 3;
+ optional int32 meta_information_sequence_number = 4;
+ optional LayerNode root_layer = 5;
+ optional LayerUpdate layer_updates = 6;
+ optional int32 hud_layer_id = 7;
+ optional LayerTreeDebugState debug_state = 8;
+ optional Size device_viewport_size = 9;
+ optional bool top_controls_shrink_blink_size = 10;
+ optional float top_controls_height = 11;
+ optional float top_controls_shown_ratio = 12;
+ optional float device_scale_factor = 13;
+ optional float painted_device_scale_factor = 14;
+ optional float page_scale_factor = 15;
+ optional float min_page_scale_factor = 16;
+ optional float max_page_scale_factor = 17;
+ optional Vector2dF elastic_overscroll = 18;
+ optional bool has_gpu_rasterization_trigger = 19;
+ optional bool content_is_suitable_for_gpu_rasterization = 20;
+ optional uint32 background_color = 21; /* SkColor */
+ optional bool has_transparent_background = 22;
+ optional bool in_paint_layer_contents = 23;
+ optional int32 id = 24;
+ optional bool next_commit_forces_redraw = 25;
+ optional int32 overscroll_elasticity_layer_id = 26;
+ optional int32 page_scale_layer_id = 27;
+ optional int32 inner_viewport_scroll_layer_id = 28;
+ optional int32 outer_viewport_scroll_layer_id = 29;
+ optional LayerSelection selection = 30;
+ optional PropertyTrees property_trees = 31;
+ optional uint32 surface_id_namespace = 32;
+ optional uint32 next_surface_sequence = 33;
+}
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 7074093..686057e 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -36,8 +36,11 @@
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_iterator.h"
+#include "cc/layers/layer_proto_converter.h"
#include "cc/layers/layer_settings.h"
#include "cc/layers/painted_scrollbar_layer.h"
+#include "cc/proto/gfx_conversions.h"
+#include "cc/proto/layer_tree_host.pb.h"
#include "cc/resources/ui_resource_request.h"
#include "cc/scheduler/begin_frame_source.h"
#include "cc/trees/draw_property_utils.h"
@@ -56,6 +59,27 @@ static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number;
}
namespace cc {
+namespace {
+
+Layer* UpdateAndGetLayer(Layer* current_layer,
+ int layer_id,
+ const base::hash_map<int, Layer*>& layer_id_map) {
+ if (layer_id == Layer::INVALID_ID) {
+ if (current_layer)
+ current_layer->SetLayerTreeHost(nullptr);
+
+ return nullptr;
+ }
+
+ auto layer_it = layer_id_map.find(layer_id);
+ DCHECK(layer_it != layer_id_map.end());
+ if (current_layer && current_layer != layer_it->second)
+ current_layer->SetLayerTreeHost(nullptr);
+
+ return layer_it->second;
+}
+
+} // namespace
LayerTreeHost::InitParams::InitParams() {
}
@@ -1276,4 +1300,143 @@ bool LayerTreeHost::IsThreaded() const {
return compositor_mode_ == CompositorMode::Threaded;
}
+void LayerTreeHost::ToProtobufForCommit(proto::LayerTreeHost* proto) const {
+ // Not all fields are serialized, as they are eiher not needed for a commit,
+ // or implementation isn't ready yet.
+ // Unsupported items:
+ // - animations
+ // - UI resources
+ // - instrumentation of stats
+ // - histograms
+ // Skipped items:
+ // - SwapPromise as they are mostly used for perf measurements.
+ // - The bitmap and GPU memory related items.
+ // Other notes:
+ // - The output surfaces are only valid on the client-side so they are
+ // therefore not serialized.
+ // - LayerTreeSettings are needed only during construction of the
+ // LayerTreeHost, so they are serialized outside of the LayerTreeHost
+ // serialization.
+ // - The |visible_| flag will be controlled from the client separately and
+ // will need special handling outside of the serialization of the
+ // LayerTreeHost.
+ // TODO(nyquist): Figure out how to support animations. See crbug.com/570376.
+ proto->set_needs_full_tree_sync(needs_full_tree_sync_);
+ proto->set_needs_meta_info_recomputation(needs_meta_info_recomputation_);
+ proto->set_source_frame_number(source_frame_number_);
+ proto->set_meta_information_sequence_number(
+ meta_information_sequence_number_);
+ LayerProtoConverter::SerializeLayerHierarchy(root_layer_,
+ proto->mutable_root_layer());
+ LayerProtoConverter::SerializeLayerProperties(root_layer_.get(),
+ proto->mutable_layer_updates());
+ proto->set_hud_layer_id(hud_layer_ ? hud_layer_->id() : Layer::INVALID_ID);
+ debug_state_.ToProtobuf(proto->mutable_debug_state());
+ SizeToProto(device_viewport_size_, proto->mutable_device_viewport_size());
+ proto->set_top_controls_shrink_blink_size(top_controls_shrink_blink_size_);
+ proto->set_top_controls_height(top_controls_height_);
+ proto->set_top_controls_shown_ratio(top_controls_shown_ratio_);
+ proto->set_device_scale_factor(device_scale_factor_);
+ proto->set_painted_device_scale_factor(painted_device_scale_factor_);
+ proto->set_page_scale_factor(page_scale_factor_);
+ proto->set_min_page_scale_factor(min_page_scale_factor_);
+ proto->set_max_page_scale_factor(max_page_scale_factor_);
+ Vector2dFToProto(elastic_overscroll_, proto->mutable_elastic_overscroll());
+ proto->set_has_gpu_rasterization_trigger(has_gpu_rasterization_trigger_);
+ proto->set_content_is_suitable_for_gpu_rasterization(
+ content_is_suitable_for_gpu_rasterization_);
+ proto->set_background_color(background_color_);
+ proto->set_has_transparent_background(has_transparent_background_);
+ proto->set_in_paint_layer_contents(in_paint_layer_contents_);
+ proto->set_id(id_);
+ proto->set_next_commit_forces_redraw(next_commit_forces_redraw_);
+
+ // Viewport layers.
+ proto->set_overscroll_elasticity_layer_id(
+ overscroll_elasticity_layer_ ? overscroll_elasticity_layer_->id()
+ : Layer::INVALID_ID);
+ proto->set_page_scale_layer_id(page_scale_layer_ ? page_scale_layer_->id()
+ : Layer::INVALID_ID);
+ proto->set_inner_viewport_scroll_layer_id(
+ inner_viewport_scroll_layer_ ? inner_viewport_scroll_layer_->id()
+ : Layer::INVALID_ID);
+ proto->set_outer_viewport_scroll_layer_id(
+ outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
+ : Layer::INVALID_ID);
+
+ LayerSelectionToProtobuf(selection_, proto->mutable_selection());
+ property_trees_.ToProtobuf(proto->mutable_property_trees());
+ proto->set_surface_id_namespace(surface_id_namespace_);
+ proto->set_next_surface_sequence(next_surface_sequence_);
+}
+
+void LayerTreeHost::FromProtobufForCommit(const proto::LayerTreeHost& proto) {
+ needs_full_tree_sync_ = proto.needs_full_tree_sync();
+ needs_meta_info_recomputation_ = proto.needs_meta_info_recomputation();
+ source_frame_number_ = proto.source_frame_number();
+ meta_information_sequence_number_ = proto.meta_information_sequence_number();
+
+ // Layer hierarchy.
+ scoped_refptr<Layer> new_root_layer =
+ LayerProtoConverter::DeserializeLayerHierarchy(root_layer_,
+ proto.root_layer());
+ if (root_layer_ != new_root_layer) {
+ root_layer_->SetLayerTreeHost(nullptr);
+ root_layer_ = new_root_layer;
+ root_layer_->SetLayerTreeHost(this);
+ }
+
+ // Populate layer_id_map_ with the new layers.
+ layer_id_map_.clear();
+ LayerTreeHostCommon::CallFunctionForSubtree(
+ root_layer(),
+ [this](Layer* layer) { layer_id_map_[layer->id()] = layer; });
+
+ LayerProtoConverter::DeserializeLayerProperties(root_layer_.get(),
+ proto.layer_updates());
+
+ debug_state_.FromProtobuf(proto.debug_state());
+ device_viewport_size_ = ProtoToSize(proto.device_viewport_size());
+ top_controls_shrink_blink_size_ = proto.top_controls_shrink_blink_size();
+ top_controls_height_ = proto.top_controls_height();
+ top_controls_shown_ratio_ = proto.top_controls_shown_ratio();
+ device_scale_factor_ = proto.device_scale_factor();
+ painted_device_scale_factor_ = proto.painted_device_scale_factor();
+ page_scale_factor_ = proto.page_scale_factor();
+ min_page_scale_factor_ = proto.min_page_scale_factor();
+ max_page_scale_factor_ = proto.max_page_scale_factor();
+ elastic_overscroll_ = ProtoToVector2dF(proto.elastic_overscroll());
+ has_gpu_rasterization_trigger_ = proto.has_gpu_rasterization_trigger();
+ content_is_suitable_for_gpu_rasterization_ =
+ proto.content_is_suitable_for_gpu_rasterization();
+ background_color_ = proto.background_color();
+ has_transparent_background_ = proto.has_transparent_background();
+ in_paint_layer_contents_ = proto.in_paint_layer_contents();
+ id_ = proto.id();
+ next_commit_forces_redraw_ = proto.next_commit_forces_redraw();
+
+ hud_layer_ = static_cast<HeadsUpDisplayLayer*>(
+ UpdateAndGetLayer(hud_layer_.get(), proto.hud_layer_id(), layer_id_map_));
+ overscroll_elasticity_layer_ =
+ UpdateAndGetLayer(overscroll_elasticity_layer_.get(),
+ proto.overscroll_elasticity_layer_id(), layer_id_map_);
+ page_scale_layer_ = UpdateAndGetLayer(
+ page_scale_layer_.get(), proto.page_scale_layer_id(), layer_id_map_);
+ inner_viewport_scroll_layer_ =
+ UpdateAndGetLayer(inner_viewport_scroll_layer_.get(),
+ proto.inner_viewport_scroll_layer_id(), layer_id_map_);
+ outer_viewport_scroll_layer_ =
+ UpdateAndGetLayer(outer_viewport_scroll_layer_.get(),
+ proto.outer_viewport_scroll_layer_id(), layer_id_map_);
+
+ LayerSelectionFromProtobuf(&selection_, proto.selection());
+
+ // It is required to create new PropertyTrees before deserializing it.
+ property_trees_ = PropertyTrees();
+ property_trees_.FromProtobuf(proto.property_trees());
+
+ surface_id_namespace_ = proto.surface_id_namespace();
+ next_surface_sequence_ = proto.next_surface_sequence();
+}
+
} // namespace cc
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index f7bd43368..9d196e1 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -72,6 +72,10 @@ struct PendingPageScaleAnimation;
struct RenderingStats;
struct ScrollAndScaleSet;
+namespace proto {
+class LayerTreeHost;
+}
+
class CC_EXPORT LayerTreeHost : public MutatorHostClient {
public:
// TODO(sad): InitParams should be a movable type so that it can be
@@ -366,6 +370,16 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
bool HasAnyAnimation(const Layer* layer) const;
bool HasActiveAnimation(const Layer* layer) const;
+ // Serializes the parts of this LayerTreeHost that is needed for a commit to a
+ // protobuf message. Not all members are serialized as they are not helpful
+ // for remote usage.
+ void ToProtobufForCommit(proto::LayerTreeHost* proto) const;
+
+ // Deserializes the protobuf into this LayerTreeHost before a commit. The
+ // expected input is a serialized remote LayerTreeHost. After deserializing
+ // the protobuf, the normal commit-flow should continue.
+ void FromProtobufForCommit(const proto::LayerTreeHost& proto);
+
protected:
LayerTreeHost(InitParams* params, CompositorMode mode);
void InitializeThreaded(
@@ -404,6 +418,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void RecordGpuRasterizationHistogram();
private:
+ friend class LayerTreeHostSerializationTest;
+
void InitializeProxy(
scoped_ptr<Proxy> proxy,
scoped_ptr<BeginFrameSource> external_begin_frame_source);
diff --git a/cc/trees/layer_tree_host_unittest_serialization.cc b/cc/trees/layer_tree_host_unittest_serialization.cc
new file mode 100644
index 0000000..2f662b6
--- /dev/null
+++ b/cc/trees/layer_tree_host_unittest_serialization.cc
@@ -0,0 +1,313 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/layer_tree_host.h"
+
+#include "cc/layers/heads_up_display_layer.h"
+#include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
+#include "cc/proto/layer.pb.h"
+#include "cc/proto/layer_tree_host.pb.h"
+#include "cc/test/fake_layer_tree_host.h"
+#include "cc/test/fake_layer_tree_host_client.h"
+#include "cc/test/layer_tree_test.h"
+#include "cc/test/test_task_graph_runner.h"
+#include "cc/trees/layer_tree_settings.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/vector2d_f.h"
+
+namespace cc {
+
+class LayerTreeHostSerializationTest : public testing::Test {
+ public:
+ LayerTreeHostSerializationTest()
+ : client_src_(FakeLayerTreeHostClient::DIRECT_3D),
+ client_dst_(FakeLayerTreeHostClient::DIRECT_3D) {}
+
+ protected:
+ void SetUp() override {
+ layer_tree_host_src_ =
+ FakeLayerTreeHost::Create(&client_src_, &task_graph_runner_src_);
+ layer_tree_host_dst_ =
+ FakeLayerTreeHost::Create(&client_dst_, &task_graph_runner_dst_);
+ }
+
+ void TearDown() override {
+ // Need to reset |in_paint_layer_contents_| to tear down.
+ layer_tree_host_src_->in_paint_layer_contents_ = false;
+ layer_tree_host_dst_->in_paint_layer_contents_ = false;
+
+ // Need to reset root layer and LayerTreeHost pointers before tear down.
+ layer_tree_host_src_->SetRootLayer(nullptr);
+ layer_tree_host_src_ = nullptr;
+ layer_tree_host_dst_->SetRootLayer(nullptr);
+ layer_tree_host_dst_ = nullptr;
+ }
+
+ void VerifySerializationAndDeserialization() {
+ proto::LayerTreeHost proto;
+ layer_tree_host_src_->ToProtobufForCommit(&proto);
+ layer_tree_host_dst_->FromProtobufForCommit(proto);
+
+ EXPECT_EQ(layer_tree_host_src_->needs_full_tree_sync_,
+ layer_tree_host_dst_->needs_full_tree_sync_);
+ EXPECT_EQ(layer_tree_host_src_->needs_meta_info_recomputation_,
+ layer_tree_host_dst_->needs_meta_info_recomputation_);
+ EXPECT_EQ(layer_tree_host_src_->source_frame_number_,
+ layer_tree_host_dst_->source_frame_number_);
+ EXPECT_EQ(layer_tree_host_src_->meta_information_sequence_number_,
+ layer_tree_host_dst_->meta_information_sequence_number_);
+ EXPECT_EQ(layer_tree_host_src_->root_layer()->id(),
+ layer_tree_host_dst_->root_layer()->id());
+ EXPECT_EQ(layer_tree_host_dst_.get(),
+ layer_tree_host_dst_->root_layer_->layer_tree_host());
+ EXPECT_EQ(layer_tree_host_src_->root_layer_->double_sided(),
+ layer_tree_host_dst_->root_layer_->double_sided());
+ EXPECT_EQ(
+ layer_tree_host_src_->debug_state_.show_replica_screen_space_rects,
+ layer_tree_host_dst_->debug_state_.show_replica_screen_space_rects);
+ EXPECT_EQ(layer_tree_host_src_->device_viewport_size_,
+ layer_tree_host_dst_->device_viewport_size_);
+ EXPECT_EQ(layer_tree_host_src_->top_controls_shrink_blink_size_,
+ layer_tree_host_dst_->top_controls_shrink_blink_size_);
+ EXPECT_EQ(layer_tree_host_src_->top_controls_height_,
+ layer_tree_host_dst_->top_controls_height_);
+ EXPECT_EQ(layer_tree_host_src_->top_controls_shown_ratio_,
+ layer_tree_host_dst_->top_controls_shown_ratio_);
+ EXPECT_EQ(layer_tree_host_src_->device_scale_factor_,
+ layer_tree_host_dst_->device_scale_factor_);
+ EXPECT_EQ(layer_tree_host_src_->painted_device_scale_factor_,
+ layer_tree_host_dst_->painted_device_scale_factor_);
+ EXPECT_EQ(layer_tree_host_src_->page_scale_factor_,
+ layer_tree_host_dst_->page_scale_factor_);
+ EXPECT_EQ(layer_tree_host_src_->min_page_scale_factor_,
+ layer_tree_host_dst_->min_page_scale_factor_);
+ EXPECT_EQ(layer_tree_host_src_->max_page_scale_factor_,
+ layer_tree_host_dst_->max_page_scale_factor_);
+ EXPECT_EQ(layer_tree_host_src_->elastic_overscroll_,
+ layer_tree_host_dst_->elastic_overscroll_);
+ EXPECT_EQ(layer_tree_host_src_->has_gpu_rasterization_trigger_,
+ layer_tree_host_dst_->has_gpu_rasterization_trigger_);
+ EXPECT_EQ(layer_tree_host_src_->content_is_suitable_for_gpu_rasterization_,
+ layer_tree_host_dst_->content_is_suitable_for_gpu_rasterization_);
+ EXPECT_EQ(layer_tree_host_src_->background_color_,
+ layer_tree_host_dst_->background_color_);
+ EXPECT_EQ(layer_tree_host_src_->has_transparent_background_,
+ layer_tree_host_dst_->has_transparent_background_);
+ EXPECT_EQ(layer_tree_host_src_->in_paint_layer_contents_,
+ layer_tree_host_dst_->in_paint_layer_contents_);
+ EXPECT_EQ(layer_tree_host_src_->id_, layer_tree_host_dst_->id_);
+ EXPECT_EQ(layer_tree_host_src_->next_commit_forces_redraw_,
+ layer_tree_host_dst_->next_commit_forces_redraw_);
+
+ if (layer_tree_host_src_->hud_layer_) {
+ EXPECT_EQ(layer_tree_host_src_->hud_layer_->id(),
+ layer_tree_host_dst_->hud_layer_->id());
+ } else {
+ EXPECT_EQ(nullptr, layer_tree_host_dst_->hud_layer_);
+ }
+ if (layer_tree_host_src_->overscroll_elasticity_layer_) {
+ EXPECT_EQ(layer_tree_host_src_->overscroll_elasticity_layer_->id(),
+ layer_tree_host_dst_->overscroll_elasticity_layer_->id());
+ } else {
+ EXPECT_EQ(nullptr, layer_tree_host_dst_->overscroll_elasticity_layer_);
+ }
+ if (layer_tree_host_src_->page_scale_layer_) {
+ EXPECT_EQ(layer_tree_host_src_->page_scale_layer_->id(),
+ layer_tree_host_dst_->page_scale_layer_->id());
+ } else {
+ EXPECT_EQ(nullptr, layer_tree_host_dst_->page_scale_layer_);
+ }
+ if (layer_tree_host_src_->inner_viewport_scroll_layer_) {
+ EXPECT_EQ(layer_tree_host_src_->inner_viewport_scroll_layer_->id(),
+ layer_tree_host_dst_->inner_viewport_scroll_layer_->id());
+ } else {
+ EXPECT_EQ(nullptr, layer_tree_host_dst_->inner_viewport_scroll_layer_);
+ }
+ if (layer_tree_host_src_->outer_viewport_scroll_layer_) {
+ EXPECT_EQ(layer_tree_host_src_->outer_viewport_scroll_layer_->id(),
+ layer_tree_host_dst_->outer_viewport_scroll_layer_->id());
+ } else {
+ EXPECT_EQ(nullptr, layer_tree_host_dst_->outer_viewport_scroll_layer_);
+ }
+ EXPECT_EQ(layer_tree_host_src_->selection_,
+ layer_tree_host_dst_->selection_);
+ EXPECT_EQ(layer_tree_host_src_->property_trees_,
+ layer_tree_host_dst_->property_trees_);
+ EXPECT_EQ(layer_tree_host_src_->surface_id_namespace_,
+ layer_tree_host_dst_->surface_id_namespace_);
+ EXPECT_EQ(layer_tree_host_src_->next_surface_sequence_,
+ layer_tree_host_dst_->next_surface_sequence_);
+ }
+
+ void RunAllMembersChangedTest() {
+ layer_tree_host_src_->needs_full_tree_sync_ =
+ !layer_tree_host_src_->needs_full_tree_sync_;
+ layer_tree_host_src_->needs_meta_info_recomputation_ =
+ !layer_tree_host_src_->needs_meta_info_recomputation_;
+ layer_tree_host_src_->source_frame_number_ *= 3;
+ layer_tree_host_src_->meta_information_sequence_number_ *= 3;
+
+ // Just fake setup a layer for both source and dest.
+ scoped_refptr<Layer> root_layer_src = Layer::Create(LayerSettings());
+ layer_tree_host_src_->SetRootLayer(root_layer_src);
+ layer_tree_host_dst_->SetRootLayer(Layer::Create(LayerSettings()));
+ root_layer_src->SetDoubleSided(!root_layer_src->double_sided());
+
+ layer_tree_host_src_->debug_state_.show_replica_screen_space_rects =
+ !layer_tree_host_src_->debug_state_.show_replica_screen_space_rects;
+ layer_tree_host_src_->device_viewport_size_ = gfx::Size(3, 14);
+ layer_tree_host_src_->top_controls_shrink_blink_size_ =
+ !layer_tree_host_src_->top_controls_shrink_blink_size_;
+ layer_tree_host_src_->top_controls_height_ =
+ layer_tree_host_src_->top_controls_height_ * 3 + 1;
+ layer_tree_host_src_->top_controls_shown_ratio_ =
+ layer_tree_host_src_->top_controls_shown_ratio_ * 3 + 1;
+ layer_tree_host_src_->device_scale_factor_ =
+ layer_tree_host_src_->device_scale_factor_ * 3 + 1;
+ layer_tree_host_src_->painted_device_scale_factor_ =
+ layer_tree_host_src_->painted_device_scale_factor_ * 3 + 1;
+ layer_tree_host_src_->page_scale_factor_ =
+ layer_tree_host_src_->page_scale_factor_ * 3 + 1;
+ layer_tree_host_src_->min_page_scale_factor_ =
+ layer_tree_host_src_->min_page_scale_factor_ * 3 + 1;
+ layer_tree_host_src_->max_page_scale_factor_ =
+ layer_tree_host_src_->max_page_scale_factor_ * 3 + 1;
+ layer_tree_host_src_->elastic_overscroll_ = gfx::Vector2dF(3, 14);
+ layer_tree_host_src_->has_gpu_rasterization_trigger_ =
+ !layer_tree_host_src_->has_gpu_rasterization_trigger_;
+ layer_tree_host_src_->content_is_suitable_for_gpu_rasterization_ =
+ !layer_tree_host_src_->content_is_suitable_for_gpu_rasterization_;
+ layer_tree_host_src_->background_color_ = SK_ColorMAGENTA;
+ layer_tree_host_src_->has_transparent_background_ =
+ !layer_tree_host_src_->has_transparent_background_;
+ layer_tree_host_src_->id_ = layer_tree_host_src_->id_ * 3 + 1;
+ layer_tree_host_src_->next_commit_forces_redraw_ =
+ !layer_tree_host_src_->next_commit_forces_redraw_;
+
+ layer_tree_host_src_->hud_layer_ =
+ HeadsUpDisplayLayer::Create(LayerSettings());
+ root_layer_src->AddChild(layer_tree_host_src_->hud_layer_);
+ layer_tree_host_src_->overscroll_elasticity_layer_ =
+ Layer::Create(LayerSettings());
+ root_layer_src->AddChild(
+ layer_tree_host_src_->overscroll_elasticity_layer_);
+ layer_tree_host_src_->page_scale_layer_ = Layer::Create(LayerSettings());
+ root_layer_src->AddChild(layer_tree_host_src_->page_scale_layer_);
+ layer_tree_host_src_->inner_viewport_scroll_layer_ =
+ Layer::Create(LayerSettings());
+ root_layer_src->AddChild(
+ layer_tree_host_src_->inner_viewport_scroll_layer_);
+ layer_tree_host_src_->outer_viewport_scroll_layer_ =
+ Layer::Create(LayerSettings());
+ root_layer_src->AddChild(
+ layer_tree_host_src_->outer_viewport_scroll_layer_);
+
+ // Set in_paint_layer_contents_ only after all calls to AddChild() have
+ // finished to ensure it's allowed to do so at that time.
+ layer_tree_host_src_->in_paint_layer_contents_ =
+ !layer_tree_host_src_->in_paint_layer_contents_;
+
+ LayerSelectionBound sel_bound;
+ sel_bound.edge_top = gfx::Point(14, 3);
+ LayerSelection selection;
+ selection.start = sel_bound;
+ layer_tree_host_src_->selection_ = selection;
+
+ layer_tree_host_src_->property_trees_.sequence_number =
+ layer_tree_host_src_->property_trees_.sequence_number * 3 + 1;
+
+ layer_tree_host_src_->surface_id_namespace_ =
+ layer_tree_host_src_->surface_id_namespace_ * 3 + 1;
+ layer_tree_host_src_->next_surface_sequence_ =
+ layer_tree_host_src_->next_surface_sequence_ * 3 + 1;
+
+ VerifySerializationAndDeserialization();
+ }
+
+ void RunLayersChangedTest() {
+ // Just fake setup a layer for both source and dest.
+ scoped_refptr<Layer> root_layer_src = Layer::Create(LayerSettings());
+ layer_tree_host_src_->SetRootLayer(root_layer_src);
+ layer_tree_host_dst_->SetRootLayer(Layer::Create(LayerSettings()));
+ root_layer_src->SetDoubleSided(!root_layer_src->double_sided());
+
+ // No HUD layer or |overscroll_elasticity_layer_|, or the inner/outer
+ // viewport scroll layers.
+ layer_tree_host_src_->overscroll_elasticity_layer_ =
+ Layer::Create(LayerSettings());
+ root_layer_src->AddChild(
+ layer_tree_host_src_->overscroll_elasticity_layer_);
+
+ VerifySerializationAndDeserialization();
+ }
+
+ void LayersChangedMultipleSerializations() {
+ // Just fake setup a layer for both source and dest.
+ scoped_refptr<Layer> root_layer_src = Layer::Create(LayerSettings());
+ layer_tree_host_src_->SetRootLayer(root_layer_src);
+ layer_tree_host_dst_->SetRootLayer(Layer::Create(LayerSettings()));
+ root_layer_src->SetDoubleSided(!root_layer_src->double_sided());
+
+ // Ensure that all the layers work correctly for multiple rounds of
+ // serialization and deserialization.
+ layer_tree_host_src_->hud_layer_ =
+ HeadsUpDisplayLayer::Create(LayerSettings());
+ root_layer_src->AddChild(layer_tree_host_src_->hud_layer_);
+ layer_tree_host_src_->overscroll_elasticity_layer_ =
+ Layer::Create(LayerSettings());
+ root_layer_src->AddChild(
+ layer_tree_host_src_->overscroll_elasticity_layer_);
+ layer_tree_host_src_->page_scale_layer_ = Layer::Create(LayerSettings());
+ root_layer_src->AddChild(layer_tree_host_src_->page_scale_layer_);
+ layer_tree_host_src_->inner_viewport_scroll_layer_ =
+ Layer::Create(LayerSettings());
+ root_layer_src->AddChild(
+ layer_tree_host_src_->inner_viewport_scroll_layer_);
+ layer_tree_host_src_->outer_viewport_scroll_layer_ =
+ Layer::Create(LayerSettings());
+ root_layer_src->AddChild(
+ layer_tree_host_src_->outer_viewport_scroll_layer_);
+
+ VerifySerializationAndDeserialization();
+ VerifySerializationAndDeserialization();
+
+ layer_tree_host_src_->hud_layer_ = nullptr;
+ VerifySerializationAndDeserialization();
+ layer_tree_host_src_->overscroll_elasticity_layer_ = nullptr;
+ VerifySerializationAndDeserialization();
+ layer_tree_host_src_->page_scale_layer_ = nullptr;
+ VerifySerializationAndDeserialization();
+ layer_tree_host_src_->inner_viewport_scroll_layer_ = nullptr;
+ VerifySerializationAndDeserialization();
+ layer_tree_host_src_->outer_viewport_scroll_layer_ = nullptr;
+ VerifySerializationAndDeserialization();
+ }
+
+ private:
+ TestTaskGraphRunner task_graph_runner_src_;
+ FakeLayerTreeHostClient client_src_;
+ scoped_ptr<LayerTreeHost> layer_tree_host_src_;
+
+ TestTaskGraphRunner task_graph_runner_dst_;
+ FakeLayerTreeHostClient client_dst_;
+ scoped_ptr<LayerTreeHost> layer_tree_host_dst_;
+};
+
+TEST_F(LayerTreeHostSerializationTest, AllMembersChanged) {
+ RunAllMembersChangedTest();
+}
+
+TEST_F(LayerTreeHostSerializationTest, LayersChanged) {
+ RunLayersChangedTest();
+}
+
+TEST_F(LayerTreeHostSerializationTest, LayersChangedMultipleSerializations) {
+ LayersChangedMultipleSerializations();
+}
+
+} // namespace cc