| Index: cc/blimp/layer_tree_host_unittest_serialization.cc
|
| diff --git a/cc/blimp/layer_tree_host_unittest_serialization.cc b/cc/blimp/layer_tree_host_unittest_serialization.cc
|
| index b40c042862557c3a8e6c71d7a34b139a1865f4db..aa0e1c65fc53317f11367b9bf07e292b5e09f68c 100644
|
| --- a/cc/blimp/layer_tree_host_unittest_serialization.cc
|
| +++ b/cc/blimp/layer_tree_host_unittest_serialization.cc
|
| @@ -9,8 +9,8 @@
|
| #include "cc/animation/animation_host.h"
|
| #include "cc/blimp/layer_tree_host_remote.h"
|
| #include "cc/layers/empty_content_layer_client.h"
|
| -#include "cc/layers/heads_up_display_layer.h"
|
| #include "cc/layers/layer.h"
|
| +#include "cc/layers/solid_color_scrollbar_layer.h"
|
| #include "cc/proto/layer.pb.h"
|
| #include "cc/proto/layer_tree_host.pb.h"
|
| #include "cc/test/fake_image_serialization_processor.h"
|
| @@ -21,7 +21,6 @@
|
| #include "cc/test/remote_client_layer_factory.h"
|
| #include "cc/test/remote_compositor_test.h"
|
| #include "cc/test/serialization_test_utils.h"
|
| -#include "cc/test/skia_common.h"
|
| #include "cc/trees/layer_tree.h"
|
| #include "cc/trees/layer_tree_host_common.h"
|
| #include "cc/trees/layer_tree_settings.h"
|
| @@ -32,10 +31,20 @@
|
|
|
| namespace cc {
|
|
|
| +#define EXPECT_CLIENT_LAYER_DIRTY(engine_layer) \
|
| + do { \
|
| + Layer* client_layer = compositor_state_deserializer_->GetLayerForEngineId( \
|
| + engine_layer->id()); \
|
| + LayerTree* client_tree = client_layer->GetLayerTree(); \
|
| + EXPECT_TRUE( \
|
| + client_tree->LayerNeedsPushPropertiesForTesting(client_layer)); \
|
| + } while (false)
|
| +
|
| class LayerTreeHostSerializationTest : public RemoteCompositorTest {
|
| protected:
|
| void VerifySerializationAndDeserialization() {
|
| // Synchronize state.
|
| + CHECK(HasPendingUpdate());
|
| base::RunLoop().RunUntilIdle();
|
| VerifySerializedTreesAreIdentical(
|
| layer_tree_host_remote_->GetLayerTree(),
|
| @@ -128,6 +137,221 @@ TEST_F(LayerTreeHostSerializationTest, AddAndRemoveNodeFromLayerTree) {
|
| VerifySerializationAndDeserialization();
|
| }
|
|
|
| +TEST_F(LayerTreeHostSerializationTest, TestNoExistingRoot) {
|
| + /* Test deserialization of a tree that looks like:
|
| + root
|
| + / \
|
| + a b
|
| + \
|
| + c
|
| + There is no existing root node before serialization.
|
| + */
|
| + scoped_refptr<Layer> old_root_layer = Layer::Create();
|
| + scoped_refptr<Layer> layer_a = Layer::Create();
|
| + scoped_refptr<Layer> layer_b = Layer::Create();
|
| + scoped_refptr<Layer> layer_c = Layer::Create();
|
| + old_root_layer->AddChild(layer_a);
|
| + old_root_layer->AddChild(layer_b);
|
| + layer_b->AddChild(layer_c);
|
| + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(old_root_layer);
|
| + VerifySerializationAndDeserialization();
|
| +
|
| + // Swap the root node.
|
| + scoped_refptr<Layer> new_root_layer = Layer::Create();
|
| + new_root_layer->AddChild(layer_a);
|
| + new_root_layer->AddChild(layer_b);
|
| + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(old_root_layer);
|
| + VerifySerializationAndDeserialization();
|
| +}
|
| +
|
| +TEST_F(LayerTreeHostSerializationTest, RecursivePropertiesSerialization) {
|
| + /* Testing serialization of properties for a tree that looks like this:
|
| + root+
|
| + / \
|
| + a* b+[mask:*]
|
| + / \
|
| + c d
|
| + Layers marked with * have changed properties.
|
| + Layers marked with + have descendants with changed properties.
|
| + Layer b also has a mask layer.
|
| + */
|
| + scoped_refptr<Layer> layer_src_root = Layer::Create();
|
| + scoped_refptr<Layer> layer_src_a = Layer::Create();
|
| + scoped_refptr<Layer> layer_src_b = Layer::Create();
|
| + scoped_refptr<Layer> layer_src_b_mask = Layer::Create();
|
| + scoped_refptr<Layer> layer_src_c = Layer::Create();
|
| + scoped_refptr<Layer> layer_src_d = Layer::Create();
|
| +
|
| + layer_src_root->AddChild(layer_src_a);
|
| + layer_src_root->AddChild(layer_src_b);
|
| + layer_src_a->AddChild(layer_src_c);
|
| + layer_src_b->AddChild(layer_src_d);
|
| + layer_src_b->SetMaskLayer(layer_src_b_mask.get());
|
| +
|
| + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(layer_src_root);
|
| + VerifySerializationAndDeserialization();
|
| + EXPECT_EQ(layer_tree_host_remote_->GetLayerTree()
|
| + ->LayersThatShouldPushProperties()
|
| + .size(),
|
| + 0u);
|
| + EXPECT_EQ(layer_tree_host_in_process_->GetLayerTree()
|
| + ->LayersThatShouldPushProperties()
|
| + .size(),
|
| + 6u);
|
| +}
|
| +
|
| +TEST_F(LayerTreeHostSerializationTest, ChildrenOrderChange) {
|
| + /* Testing serialization and deserialization of a tree that initially looks
|
| + like this:
|
| + root
|
| + / \
|
| + a b
|
| + The children are then re-ordered and changed to:
|
| + root
|
| + / \
|
| + b a
|
| + \
|
| + c
|
| + */
|
| + scoped_refptr<Layer> layer_src_root = Layer::Create();
|
| + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(layer_src_root);
|
| + scoped_refptr<Layer> layer_src_a = Layer::Create();
|
| + scoped_refptr<Layer> layer_src_b = Layer::Create();
|
| +
|
| + layer_src_root->AddChild(layer_src_b);
|
| + layer_src_root->AddChild(layer_src_a);
|
| + VerifySerializationAndDeserialization();
|
| +
|
| + Layer* client_root =
|
| + compositor_state_deserializer_->GetLayerForEngineId(layer_src_root->id());
|
| + Layer* client_a =
|
| + compositor_state_deserializer_->GetLayerForEngineId(layer_src_a->id());
|
| + Layer* client_b =
|
| + compositor_state_deserializer_->GetLayerForEngineId(layer_src_b->id());
|
| +
|
| + // Swap the children.
|
| + layer_src_root->RemoveAllChildren();
|
| + layer_src_root->AddChild(layer_src_a);
|
| + layer_src_root->AddChild(layer_src_b);
|
| + layer_src_a->AddChild(Layer::Create());
|
| + VerifySerializationAndDeserialization();
|
| +
|
| + // Verify all old layers are re-used.
|
| + Layer* new_client_root =
|
| + compositor_state_deserializer_->GetLayerForEngineId(layer_src_root->id());
|
| + Layer* new_client_a =
|
| + compositor_state_deserializer_->GetLayerForEngineId(layer_src_a->id());
|
| + Layer* new_client_b =
|
| + compositor_state_deserializer_->GetLayerForEngineId(layer_src_b->id());
|
| + EXPECT_EQ(client_root, new_client_root);
|
| + EXPECT_EQ(client_a, new_client_a);
|
| + EXPECT_EQ(client_b, new_client_b);
|
| +}
|
| +
|
| +TEST_F(LayerTreeHostSerializationTest, DeletingLayers) {
|
| + /* Testing serialization and deserialization of a tree that initially
|
| + looks like this:
|
| + root
|
| + / \
|
| + a b
|
| + \
|
| + c+[mask:*]
|
| + First the mask layer is deleted.
|
| + Then the subtree from node |b| is deleted in the next update.
|
| + */
|
| + scoped_refptr<Layer> layer_src_root = Layer::Create();
|
| + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(layer_src_root);
|
| +
|
| + scoped_refptr<Layer> layer_src_a = Layer::Create();
|
| + scoped_refptr<Layer> layer_src_b = Layer::Create();
|
| + scoped_refptr<Layer> layer_src_c = Layer::Create();
|
| + scoped_refptr<Layer> layer_src_c_mask = Layer::Create();
|
| + layer_src_root->AddChild(layer_src_a);
|
| + layer_src_root->AddChild(layer_src_b);
|
| + layer_src_b->AddChild(layer_src_c);
|
| + layer_src_c->SetMaskLayer(layer_src_c_mask.get());
|
| + VerifySerializationAndDeserialization();
|
| +
|
| + // Delete the mask layer.
|
| + layer_src_c->SetMaskLayer(nullptr);
|
| + VerifySerializationAndDeserialization();
|
| +
|
| + // Remove child b.
|
| + layer_src_b->RemoveFromParent();
|
| + VerifySerializationAndDeserialization();
|
| +}
|
| +
|
| +TEST_F(LayerTreeHostSerializationTest, LayerDataSerialization) {
|
| + scoped_refptr<Layer> layer = Layer::Create();
|
| + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(layer);
|
| + VerifySerializationAndDeserialization();
|
| +
|
| + // Change all the fields.
|
| + layer->SetTransformOrigin(gfx::Point3F(3.0f, 1.0f, 4.0f));
|
| + layer->SetBackgroundColor(SK_ColorRED);
|
| + layer->SetBounds(gfx::Size(3, 14));
|
| + layer->SetDoubleSided(!layer->double_sided());
|
| + layer->SetHideLayerAndSubtree(!layer->hide_layer_and_subtree());
|
| + layer->SetMasksToBounds(!layer->masks_to_bounds());
|
| + layer->AddMainThreadScrollingReasons(
|
| + MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
|
| + layer->SetNonFastScrollableRegion(Region(gfx::Rect(5, 1, 14, 3)));
|
| + layer->SetNonFastScrollableRegion(Region(gfx::Rect(3, 14, 1, 5)));
|
| + layer->SetContentsOpaque(!layer->contents_opaque());
|
| + layer->SetOpacity(0.4f);
|
| + layer->SetBlendMode(SkXfermode::kOverlay_Mode);
|
| + layer->SetIsRootForIsolatedGroup(!layer->is_root_for_isolated_group());
|
| + layer->SetPosition(gfx::PointF(3.14f, 6.28f));
|
| + layer->SetIsContainerForFixedPositionLayers(
|
| + !layer->IsContainerForFixedPositionLayers());
|
| + LayerPositionConstraint pos_con;
|
| + pos_con.set_is_fixed_to_bottom_edge(true);
|
| + layer->SetPositionConstraint(pos_con);
|
| + layer->SetShouldFlattenTransform(!layer->should_flatten_transform());
|
| + layer->SetUseParentBackfaceVisibility(
|
| + !layer->use_parent_backface_visibility());
|
| + gfx::Transform transform;
|
| + transform.Rotate(90);
|
| + layer->SetTransform(transform);
|
| + layer->Set3dSortingContextId(42);
|
| + layer->SetUserScrollable(layer->user_scrollable_horizontal(),
|
| + layer->user_scrollable_vertical());
|
| + layer->SetScrollOffset(gfx::ScrollOffset(3, 14));
|
| + gfx::Rect update_rect(14, 15);
|
| + layer->SetNeedsDisplayRect(update_rect);
|
| +
|
| + VerifySerializationAndDeserialization();
|
| + Layer* client_layer =
|
| + compositor_state_deserializer_->GetLayerForEngineId(layer->id());
|
| + EXPECT_EQ(update_rect, client_layer->update_rect());
|
| +}
|
| +
|
| +TEST_F(LayerTreeHostSerializationTest, SolidColorScrollbarLayer) {
|
| + scoped_refptr<Layer> root_layer = Layer::Create();
|
| + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(root_layer);
|
| + scoped_refptr<Layer> child_layer = Layer::Create();
|
| + root_layer->AddChild(child_layer);
|
| +
|
| + std::vector<scoped_refptr<SolidColorScrollbarLayer>> scrollbar_layers;
|
| + scrollbar_layers.push_back(SolidColorScrollbarLayer::Create(
|
| + ScrollbarOrientation::HORIZONTAL, 20, 5, true, root_layer->id()));
|
| + scrollbar_layers.push_back(SolidColorScrollbarLayer::Create(
|
| + ScrollbarOrientation::VERTICAL, 20, 5, false, child_layer->id()));
|
| + scrollbar_layers.push_back(SolidColorScrollbarLayer::Create(
|
| + ScrollbarOrientation::HORIZONTAL, 0, 0, true, root_layer->id()));
|
| + scrollbar_layers.push_back(SolidColorScrollbarLayer::Create(
|
| + ScrollbarOrientation::VERTICAL, 10, 35, true, child_layer->id()));
|
| + for (const auto& layer : scrollbar_layers) {
|
| + root_layer->AddChild(layer);
|
| + }
|
| +
|
| + VerifySerializationAndDeserialization();
|
| + for (const auto& engine_layer : scrollbar_layers) {
|
| + VerifySerializedScrollbarLayersAreIdentical(
|
| + engine_layer.get(), compositor_state_deserializer_.get());
|
| + }
|
| +}
|
| +
|
| TEST_F(LayerTreeHostSerializationTest, PictureLayerSerialization) {
|
| // Override the layer factor to create FakePictureLayers in the deserializer.
|
| compositor_state_deserializer_->SetLayerFactoryForTesting(
|
| @@ -149,26 +373,40 @@ TEST_F(LayerTreeHostSerializationTest, PictureLayerSerialization) {
|
| FakePictureLayer::Create(&content_client);
|
|
|
| root_layer_src->AddChild(picture_layer_src);
|
| + picture_layer_src->SetNearestNeighbor(!picture_layer_src->nearest_neighbor());
|
| picture_layer_src->SetNeedsDisplay();
|
| VerifySerializationAndDeserialization();
|
| -
|
| layer_tree_host_in_process_->UpdateLayers();
|
| - PictureLayer* picture_layer_dst = reinterpret_cast<PictureLayer*>(
|
| - compositor_state_deserializer_->GetLayerForEngineId(
|
| - picture_layer_src->id()));
|
| - EXPECT_TRUE(AreDisplayListDrawingResultsSame(
|
| - gfx::Rect(gfx::Rect(picture_layer_src->bounds())),
|
| - picture_layer_src->GetDisplayItemList(),
|
| - picture_layer_dst->GetDisplayItemList()));
|
| + VerifySerializedPictureLayersAreIdentical(
|
| + picture_layer_src.get(), compositor_state_deserializer_.get());
|
|
|
| // Another round.
|
| picture_layer_src->SetNeedsDisplay();
|
| + SkPaint new_paint;
|
| + new_paint.setColor(SkColorSetARGB(255, 12, 32, 44));
|
| + content_client.add_draw_rect(gfx::Rect(bounds), new_paint);
|
| + VerifySerializationAndDeserialization();
|
| + layer_tree_host_in_process_->UpdateLayers();
|
| + VerifySerializedPictureLayersAreIdentical(
|
| + picture_layer_src.get(), compositor_state_deserializer_.get());
|
| +}
|
| +
|
| +TEST_F(LayerTreeHostSerializationTest, EmptyPictureLayerSerialization) {
|
| + // Override the layer factor to create FakePictureLayers in the deserializer.
|
| + compositor_state_deserializer_->SetLayerFactoryForTesting(
|
| + base::MakeUnique<RemoteClientLayerFactory>());
|
| +
|
| + LayerTree* engine_layer_tree = layer_tree_host_remote_->GetLayerTree();
|
| + scoped_refptr<Layer> root_layer_src = Layer::Create();
|
| + engine_layer_tree->SetRootLayer(root_layer_src);
|
| + scoped_refptr<FakePictureLayer> picture_layer_src =
|
| + FakePictureLayer::Create(EmptyContentLayerClient::GetInstance());
|
| + root_layer_src->AddChild(picture_layer_src);
|
| + picture_layer_src->SetNeedsDisplay();
|
| VerifySerializationAndDeserialization();
|
| layer_tree_host_in_process_->UpdateLayers();
|
| - EXPECT_TRUE(AreDisplayListDrawingResultsSame(
|
| - gfx::Rect(gfx::Rect(picture_layer_src->bounds())),
|
| - picture_layer_src->GetDisplayItemList(),
|
| - picture_layer_dst->GetDisplayItemList()));
|
| + VerifySerializedPictureLayersAreIdentical(
|
| + picture_layer_src.get(), compositor_state_deserializer_.get());
|
| }
|
|
|
| } // namespace cc
|
|
|