| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <memory> | 5 #include <memory> |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/run_loop.h" | 8 #include "base/run_loop.h" |
| 9 #include "cc/animation/animation_host.h" | 9 #include "cc/animation/animation_host.h" |
| 10 #include "cc/blimp/layer_tree_host_remote.h" | 10 #include "cc/blimp/layer_tree_host_remote.h" |
| 11 #include "cc/layers/empty_content_layer_client.h" | 11 #include "cc/layers/empty_content_layer_client.h" |
| 12 #include "cc/layers/heads_up_display_layer.h" | |
| 13 #include "cc/layers/layer.h" | 12 #include "cc/layers/layer.h" |
| 13 #include "cc/layers/solid_color_scrollbar_layer.h" |
| 14 #include "cc/proto/layer.pb.h" | 14 #include "cc/proto/layer.pb.h" |
| 15 #include "cc/proto/layer_tree_host.pb.h" | 15 #include "cc/proto/layer_tree_host.pb.h" |
| 16 #include "cc/test/fake_image_serialization_processor.h" | 16 #include "cc/test/fake_image_serialization_processor.h" |
| 17 #include "cc/test/fake_layer_tree_host.h" | 17 #include "cc/test/fake_layer_tree_host.h" |
| 18 #include "cc/test/fake_layer_tree_host_client.h" | 18 #include "cc/test/fake_layer_tree_host_client.h" |
| 19 #include "cc/test/fake_picture_layer.h" | 19 #include "cc/test/fake_picture_layer.h" |
| 20 #include "cc/test/fake_recording_source.h" | 20 #include "cc/test/fake_recording_source.h" |
| 21 #include "cc/test/remote_client_layer_factory.h" | 21 #include "cc/test/remote_client_layer_factory.h" |
| 22 #include "cc/test/remote_compositor_test.h" | 22 #include "cc/test/remote_compositor_test.h" |
| 23 #include "cc/test/serialization_test_utils.h" | 23 #include "cc/test/serialization_test_utils.h" |
| 24 #include "cc/test/skia_common.h" | |
| 25 #include "cc/trees/layer_tree.h" | 24 #include "cc/trees/layer_tree.h" |
| 26 #include "cc/trees/layer_tree_host_common.h" | 25 #include "cc/trees/layer_tree_host_common.h" |
| 27 #include "cc/trees/layer_tree_settings.h" | 26 #include "cc/trees/layer_tree_settings.h" |
| 28 #include "third_party/skia/include/core/SkColor.h" | 27 #include "third_party/skia/include/core/SkColor.h" |
| 29 #include "ui/gfx/geometry/point.h" | 28 #include "ui/gfx/geometry/point.h" |
| 30 #include "ui/gfx/geometry/size.h" | 29 #include "ui/gfx/geometry/size.h" |
| 31 #include "ui/gfx/geometry/vector2d_f.h" | 30 #include "ui/gfx/geometry/vector2d_f.h" |
| 32 | 31 |
| 33 namespace cc { | 32 namespace cc { |
| 34 | 33 |
| 34 #define EXPECT_CLIENT_LAYER_DIRTY(engine_layer) \ |
| 35 do { \ |
| 36 Layer* client_layer = compositor_state_deserializer_->GetLayerForEngineId( \ |
| 37 engine_layer->id()); \ |
| 38 LayerTree* client_tree = client_layer->GetLayerTree(); \ |
| 39 EXPECT_TRUE( \ |
| 40 client_tree->LayerNeedsPushPropertiesForTesting(client_layer)); \ |
| 41 } while (false) |
| 42 |
| 35 class LayerTreeHostSerializationTest : public RemoteCompositorTest { | 43 class LayerTreeHostSerializationTest : public RemoteCompositorTest { |
| 36 protected: | 44 protected: |
| 37 void VerifySerializationAndDeserialization() { | 45 void VerifySerializationAndDeserialization() { |
| 38 // Synchronize state. | 46 // Synchronize state. |
| 47 CHECK(HasPendingUpdate()); |
| 39 base::RunLoop().RunUntilIdle(); | 48 base::RunLoop().RunUntilIdle(); |
| 40 VerifySerializedTreesAreIdentical( | 49 VerifySerializedTreesAreIdentical( |
| 41 layer_tree_host_remote_->GetLayerTree(), | 50 layer_tree_host_remote_->GetLayerTree(), |
| 42 layer_tree_host_in_process_->GetLayerTree(), | 51 layer_tree_host_in_process_->GetLayerTree(), |
| 43 compositor_state_deserializer_.get()); | 52 compositor_state_deserializer_.get()); |
| 44 } | 53 } |
| 45 | 54 |
| 46 void SetUpViewportLayers(LayerTree* engine_layer_tree) { | 55 void SetUpViewportLayers(LayerTree* engine_layer_tree) { |
| 47 scoped_refptr<Layer> overscroll_elasticity_layer = Layer::Create(); | 56 scoped_refptr<Layer> overscroll_elasticity_layer = Layer::Create(); |
| 48 scoped_refptr<Layer> page_scale_layer = Layer::Create(); | 57 scoped_refptr<Layer> page_scale_layer = Layer::Create(); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 VerifySerializationAndDeserialization(); | 130 VerifySerializationAndDeserialization(); |
| 122 | 131 |
| 123 // Now change the Layer Hierarchy | 132 // Now change the Layer Hierarchy |
| 124 layer_src_c->RemoveFromParent(); | 133 layer_src_c->RemoveFromParent(); |
| 125 layer_src_b->RemoveFromParent(); | 134 layer_src_b->RemoveFromParent(); |
| 126 layer_src_root->AddChild(layer_src_c); | 135 layer_src_root->AddChild(layer_src_c); |
| 127 layer_src_c->AddChild(layer_src_d); | 136 layer_src_c->AddChild(layer_src_d); |
| 128 VerifySerializationAndDeserialization(); | 137 VerifySerializationAndDeserialization(); |
| 129 } | 138 } |
| 130 | 139 |
| 140 TEST_F(LayerTreeHostSerializationTest, TestNoExistingRoot) { |
| 141 /* Test deserialization of a tree that looks like: |
| 142 root |
| 143 / \ |
| 144 a b |
| 145 \ |
| 146 c |
| 147 There is no existing root node before serialization. |
| 148 */ |
| 149 scoped_refptr<Layer> old_root_layer = Layer::Create(); |
| 150 scoped_refptr<Layer> layer_a = Layer::Create(); |
| 151 scoped_refptr<Layer> layer_b = Layer::Create(); |
| 152 scoped_refptr<Layer> layer_c = Layer::Create(); |
| 153 old_root_layer->AddChild(layer_a); |
| 154 old_root_layer->AddChild(layer_b); |
| 155 layer_b->AddChild(layer_c); |
| 156 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(old_root_layer); |
| 157 VerifySerializationAndDeserialization(); |
| 158 |
| 159 // Swap the root node. |
| 160 scoped_refptr<Layer> new_root_layer = Layer::Create(); |
| 161 new_root_layer->AddChild(layer_a); |
| 162 new_root_layer->AddChild(layer_b); |
| 163 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(old_root_layer); |
| 164 VerifySerializationAndDeserialization(); |
| 165 } |
| 166 |
| 167 TEST_F(LayerTreeHostSerializationTest, RecursivePropertiesSerialization) { |
| 168 /* Testing serialization of properties for a tree that looks like this: |
| 169 root+ |
| 170 / \ |
| 171 a* b+[mask:*] |
| 172 / \ |
| 173 c d |
| 174 Layers marked with * have changed properties. |
| 175 Layers marked with + have descendants with changed properties. |
| 176 Layer b also has a mask layer. |
| 177 */ |
| 178 scoped_refptr<Layer> layer_src_root = Layer::Create(); |
| 179 scoped_refptr<Layer> layer_src_a = Layer::Create(); |
| 180 scoped_refptr<Layer> layer_src_b = Layer::Create(); |
| 181 scoped_refptr<Layer> layer_src_b_mask = Layer::Create(); |
| 182 scoped_refptr<Layer> layer_src_c = Layer::Create(); |
| 183 scoped_refptr<Layer> layer_src_d = Layer::Create(); |
| 184 |
| 185 layer_src_root->AddChild(layer_src_a); |
| 186 layer_src_root->AddChild(layer_src_b); |
| 187 layer_src_a->AddChild(layer_src_c); |
| 188 layer_src_b->AddChild(layer_src_d); |
| 189 layer_src_b->SetMaskLayer(layer_src_b_mask.get()); |
| 190 |
| 191 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(layer_src_root); |
| 192 VerifySerializationAndDeserialization(); |
| 193 EXPECT_EQ(layer_tree_host_remote_->GetLayerTree() |
| 194 ->LayersThatShouldPushProperties() |
| 195 .size(), |
| 196 0u); |
| 197 EXPECT_EQ(layer_tree_host_in_process_->GetLayerTree() |
| 198 ->LayersThatShouldPushProperties() |
| 199 .size(), |
| 200 6u); |
| 201 } |
| 202 |
| 203 TEST_F(LayerTreeHostSerializationTest, ChildrenOrderChange) { |
| 204 /* Testing serialization and deserialization of a tree that initially looks |
| 205 like this: |
| 206 root |
| 207 / \ |
| 208 a b |
| 209 The children are then re-ordered and changed to: |
| 210 root |
| 211 / \ |
| 212 b a |
| 213 \ |
| 214 c |
| 215 */ |
| 216 scoped_refptr<Layer> layer_src_root = Layer::Create(); |
| 217 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(layer_src_root); |
| 218 scoped_refptr<Layer> layer_src_a = Layer::Create(); |
| 219 scoped_refptr<Layer> layer_src_b = Layer::Create(); |
| 220 |
| 221 layer_src_root->AddChild(layer_src_b); |
| 222 layer_src_root->AddChild(layer_src_a); |
| 223 VerifySerializationAndDeserialization(); |
| 224 |
| 225 Layer* client_root = |
| 226 compositor_state_deserializer_->GetLayerForEngineId(layer_src_root->id()); |
| 227 Layer* client_a = |
| 228 compositor_state_deserializer_->GetLayerForEngineId(layer_src_a->id()); |
| 229 Layer* client_b = |
| 230 compositor_state_deserializer_->GetLayerForEngineId(layer_src_b->id()); |
| 231 |
| 232 // Swap the children. |
| 233 layer_src_root->RemoveAllChildren(); |
| 234 layer_src_root->AddChild(layer_src_a); |
| 235 layer_src_root->AddChild(layer_src_b); |
| 236 layer_src_a->AddChild(Layer::Create()); |
| 237 VerifySerializationAndDeserialization(); |
| 238 |
| 239 // Verify all old layers are re-used. |
| 240 Layer* new_client_root = |
| 241 compositor_state_deserializer_->GetLayerForEngineId(layer_src_root->id()); |
| 242 Layer* new_client_a = |
| 243 compositor_state_deserializer_->GetLayerForEngineId(layer_src_a->id()); |
| 244 Layer* new_client_b = |
| 245 compositor_state_deserializer_->GetLayerForEngineId(layer_src_b->id()); |
| 246 EXPECT_EQ(client_root, new_client_root); |
| 247 EXPECT_EQ(client_a, new_client_a); |
| 248 EXPECT_EQ(client_b, new_client_b); |
| 249 } |
| 250 |
| 251 TEST_F(LayerTreeHostSerializationTest, DeletingLayers) { |
| 252 /* Testing serialization and deserialization of a tree that initially |
| 253 looks like this: |
| 254 root |
| 255 / \ |
| 256 a b |
| 257 \ |
| 258 c+[mask:*] |
| 259 First the mask layer is deleted. |
| 260 Then the subtree from node |b| is deleted in the next update. |
| 261 */ |
| 262 scoped_refptr<Layer> layer_src_root = Layer::Create(); |
| 263 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(layer_src_root); |
| 264 |
| 265 scoped_refptr<Layer> layer_src_a = Layer::Create(); |
| 266 scoped_refptr<Layer> layer_src_b = Layer::Create(); |
| 267 scoped_refptr<Layer> layer_src_c = Layer::Create(); |
| 268 scoped_refptr<Layer> layer_src_c_mask = Layer::Create(); |
| 269 layer_src_root->AddChild(layer_src_a); |
| 270 layer_src_root->AddChild(layer_src_b); |
| 271 layer_src_b->AddChild(layer_src_c); |
| 272 layer_src_c->SetMaskLayer(layer_src_c_mask.get()); |
| 273 VerifySerializationAndDeserialization(); |
| 274 |
| 275 // Delete the mask layer. |
| 276 layer_src_c->SetMaskLayer(nullptr); |
| 277 VerifySerializationAndDeserialization(); |
| 278 |
| 279 // Remove child b. |
| 280 layer_src_b->RemoveFromParent(); |
| 281 VerifySerializationAndDeserialization(); |
| 282 } |
| 283 |
| 284 TEST_F(LayerTreeHostSerializationTest, LayerDataSerialization) { |
| 285 scoped_refptr<Layer> layer = Layer::Create(); |
| 286 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(layer); |
| 287 VerifySerializationAndDeserialization(); |
| 288 |
| 289 // Change all the fields. |
| 290 layer->SetTransformOrigin(gfx::Point3F(3.0f, 1.0f, 4.0f)); |
| 291 layer->SetBackgroundColor(SK_ColorRED); |
| 292 layer->SetBounds(gfx::Size(3, 14)); |
| 293 layer->SetDoubleSided(!layer->double_sided()); |
| 294 layer->SetHideLayerAndSubtree(!layer->hide_layer_and_subtree()); |
| 295 layer->SetMasksToBounds(!layer->masks_to_bounds()); |
| 296 layer->AddMainThreadScrollingReasons( |
| 297 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); |
| 298 layer->SetNonFastScrollableRegion(Region(gfx::Rect(5, 1, 14, 3))); |
| 299 layer->SetNonFastScrollableRegion(Region(gfx::Rect(3, 14, 1, 5))); |
| 300 layer->SetContentsOpaque(!layer->contents_opaque()); |
| 301 layer->SetOpacity(0.4f); |
| 302 layer->SetBlendMode(SkXfermode::kOverlay_Mode); |
| 303 layer->SetIsRootForIsolatedGroup(!layer->is_root_for_isolated_group()); |
| 304 layer->SetPosition(gfx::PointF(3.14f, 6.28f)); |
| 305 layer->SetIsContainerForFixedPositionLayers( |
| 306 !layer->IsContainerForFixedPositionLayers()); |
| 307 LayerPositionConstraint pos_con; |
| 308 pos_con.set_is_fixed_to_bottom_edge(true); |
| 309 layer->SetPositionConstraint(pos_con); |
| 310 layer->SetShouldFlattenTransform(!layer->should_flatten_transform()); |
| 311 layer->SetUseParentBackfaceVisibility( |
| 312 !layer->use_parent_backface_visibility()); |
| 313 gfx::Transform transform; |
| 314 transform.Rotate(90); |
| 315 layer->SetTransform(transform); |
| 316 layer->Set3dSortingContextId(42); |
| 317 layer->SetUserScrollable(layer->user_scrollable_horizontal(), |
| 318 layer->user_scrollable_vertical()); |
| 319 layer->SetScrollOffset(gfx::ScrollOffset(3, 14)); |
| 320 gfx::Rect update_rect(14, 15); |
| 321 layer->SetNeedsDisplayRect(update_rect); |
| 322 |
| 323 VerifySerializationAndDeserialization(); |
| 324 Layer* client_layer = |
| 325 compositor_state_deserializer_->GetLayerForEngineId(layer->id()); |
| 326 EXPECT_EQ(update_rect, client_layer->update_rect()); |
| 327 } |
| 328 |
| 329 TEST_F(LayerTreeHostSerializationTest, SolidColorScrollbarLayer) { |
| 330 scoped_refptr<Layer> root_layer = Layer::Create(); |
| 331 layer_tree_host_remote_->GetLayerTree()->SetRootLayer(root_layer); |
| 332 scoped_refptr<Layer> child_layer = Layer::Create(); |
| 333 root_layer->AddChild(child_layer); |
| 334 |
| 335 std::vector<scoped_refptr<SolidColorScrollbarLayer>> scrollbar_layers; |
| 336 scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( |
| 337 ScrollbarOrientation::HORIZONTAL, 20, 5, true, root_layer->id())); |
| 338 scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( |
| 339 ScrollbarOrientation::VERTICAL, 20, 5, false, child_layer->id())); |
| 340 scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( |
| 341 ScrollbarOrientation::HORIZONTAL, 0, 0, true, root_layer->id())); |
| 342 scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( |
| 343 ScrollbarOrientation::VERTICAL, 10, 35, true, child_layer->id())); |
| 344 for (const auto& layer : scrollbar_layers) { |
| 345 root_layer->AddChild(layer); |
| 346 } |
| 347 |
| 348 VerifySerializationAndDeserialization(); |
| 349 for (const auto& engine_layer : scrollbar_layers) { |
| 350 VerifySerializedScrollbarLayersAreIdentical( |
| 351 engine_layer.get(), compositor_state_deserializer_.get()); |
| 352 } |
| 353 } |
| 354 |
| 131 TEST_F(LayerTreeHostSerializationTest, PictureLayerSerialization) { | 355 TEST_F(LayerTreeHostSerializationTest, PictureLayerSerialization) { |
| 132 // Override the layer factor to create FakePictureLayers in the deserializer. | 356 // Override the layer factor to create FakePictureLayers in the deserializer. |
| 133 compositor_state_deserializer_->SetLayerFactoryForTesting( | 357 compositor_state_deserializer_->SetLayerFactoryForTesting( |
| 134 base::MakeUnique<RemoteClientLayerFactory>()); | 358 base::MakeUnique<RemoteClientLayerFactory>()); |
| 135 | 359 |
| 136 LayerTree* engine_layer_tree = layer_tree_host_remote_->GetLayerTree(); | 360 LayerTree* engine_layer_tree = layer_tree_host_remote_->GetLayerTree(); |
| 137 scoped_refptr<Layer> root_layer_src = Layer::Create(); | 361 scoped_refptr<Layer> root_layer_src = Layer::Create(); |
| 138 engine_layer_tree->SetRootLayer(root_layer_src); | 362 engine_layer_tree->SetRootLayer(root_layer_src); |
| 139 | 363 |
| 140 // Ensure that a PictureLayer work correctly for multiple rounds of | 364 // Ensure that a PictureLayer work correctly for multiple rounds of |
| 141 // serialization and deserialization. | 365 // serialization and deserialization. |
| 142 FakeContentLayerClient content_client; | 366 FakeContentLayerClient content_client; |
| 143 gfx::Size bounds(256, 256); | 367 gfx::Size bounds(256, 256); |
| 144 content_client.set_bounds(bounds); | 368 content_client.set_bounds(bounds); |
| 145 SkPaint simple_paint; | 369 SkPaint simple_paint; |
| 146 simple_paint.setColor(SkColorSetARGB(255, 12, 23, 34)); | 370 simple_paint.setColor(SkColorSetARGB(255, 12, 23, 34)); |
| 147 content_client.add_draw_rect(gfx::Rect(bounds), simple_paint); | 371 content_client.add_draw_rect(gfx::Rect(bounds), simple_paint); |
| 148 scoped_refptr<FakePictureLayer> picture_layer_src = | 372 scoped_refptr<FakePictureLayer> picture_layer_src = |
| 149 FakePictureLayer::Create(&content_client); | 373 FakePictureLayer::Create(&content_client); |
| 150 | 374 |
| 151 root_layer_src->AddChild(picture_layer_src); | 375 root_layer_src->AddChild(picture_layer_src); |
| 376 picture_layer_src->SetNearestNeighbor(!picture_layer_src->nearest_neighbor()); |
| 152 picture_layer_src->SetNeedsDisplay(); | 377 picture_layer_src->SetNeedsDisplay(); |
| 153 VerifySerializationAndDeserialization(); | 378 VerifySerializationAndDeserialization(); |
| 154 | |
| 155 layer_tree_host_in_process_->UpdateLayers(); | 379 layer_tree_host_in_process_->UpdateLayers(); |
| 156 PictureLayer* picture_layer_dst = reinterpret_cast<PictureLayer*>( | 380 VerifySerializedPictureLayersAreIdentical( |
| 157 compositor_state_deserializer_->GetLayerForEngineId( | 381 picture_layer_src.get(), compositor_state_deserializer_.get()); |
| 158 picture_layer_src->id())); | |
| 159 EXPECT_TRUE(AreDisplayListDrawingResultsSame( | |
| 160 gfx::Rect(gfx::Rect(picture_layer_src->bounds())), | |
| 161 picture_layer_src->GetDisplayItemList(), | |
| 162 picture_layer_dst->GetDisplayItemList())); | |
| 163 | 382 |
| 164 // Another round. | 383 // Another round. |
| 165 picture_layer_src->SetNeedsDisplay(); | 384 picture_layer_src->SetNeedsDisplay(); |
| 385 SkPaint new_paint; |
| 386 new_paint.setColor(SkColorSetARGB(255, 12, 32, 44)); |
| 387 content_client.add_draw_rect(gfx::Rect(bounds), new_paint); |
| 166 VerifySerializationAndDeserialization(); | 388 VerifySerializationAndDeserialization(); |
| 167 layer_tree_host_in_process_->UpdateLayers(); | 389 layer_tree_host_in_process_->UpdateLayers(); |
| 168 EXPECT_TRUE(AreDisplayListDrawingResultsSame( | 390 VerifySerializedPictureLayersAreIdentical( |
| 169 gfx::Rect(gfx::Rect(picture_layer_src->bounds())), | 391 picture_layer_src.get(), compositor_state_deserializer_.get()); |
| 170 picture_layer_src->GetDisplayItemList(), | 392 } |
| 171 picture_layer_dst->GetDisplayItemList())); | 393 |
| 394 TEST_F(LayerTreeHostSerializationTest, EmptyPictureLayerSerialization) { |
| 395 // Override the layer factor to create FakePictureLayers in the deserializer. |
| 396 compositor_state_deserializer_->SetLayerFactoryForTesting( |
| 397 base::MakeUnique<RemoteClientLayerFactory>()); |
| 398 |
| 399 LayerTree* engine_layer_tree = layer_tree_host_remote_->GetLayerTree(); |
| 400 scoped_refptr<Layer> root_layer_src = Layer::Create(); |
| 401 engine_layer_tree->SetRootLayer(root_layer_src); |
| 402 scoped_refptr<FakePictureLayer> picture_layer_src = |
| 403 FakePictureLayer::Create(EmptyContentLayerClient::GetInstance()); |
| 404 root_layer_src->AddChild(picture_layer_src); |
| 405 picture_layer_src->SetNeedsDisplay(); |
| 406 VerifySerializationAndDeserialization(); |
| 407 layer_tree_host_in_process_->UpdateLayers(); |
| 408 VerifySerializedPictureLayersAreIdentical( |
| 409 picture_layer_src.get(), compositor_state_deserializer_.get()); |
| 172 } | 410 } |
| 173 | 411 |
| 174 } // namespace cc | 412 } // namespace cc |
| OLD | NEW |