1 // Copyright 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "cc/trees/layer_tree_host_common.h" 6 7 #include "cc/animation/layer_animation_controller.h" 8 #include "cc/base/math_util.h" 9 #include "cc/layers/content_layer.h" 10 #include "cc/layers/content_layer_client.h" 11 #include "cc/layers/heads_up_display_layer_impl.h" 12 #include "cc/layers/layer.h" 13 #include "cc/layers/layer_impl.h" 14 #include "cc/layers/render_surface.h" 15 #include "cc/layers/render_surface_impl.h" 16 #include "cc/output/copy_output_request.h" 17 #include "cc/output/copy_output_result.h" 18 #include "cc/test/animation_test_common.h" 19 #include "cc/test/fake_impl_proxy.h" 20 #include "cc/test/fake_layer_tree_host.h" 21 #include "cc/test/fake_layer_tree_host_impl.h" 22 #include "cc/test/geometry_test_utils.h" 23 #include "cc/trees/layer_tree_impl.h" 24 #include "cc/trees/proxy.h" 25 #include "cc/trees/single_thread_proxy.h" 26 #include "testing/gmock/include/gmock/gmock.h" 27 #include "testing/gtest/include/gtest/gtest.h" 28 #include "ui/gfx/quad_f.h" 29 #include "ui/gfx/size_conversions.h" 30 #include "ui/gfx/transform.h" 31 32 namespace cc { 33 namespace { 34 35 class LayerTreeHostCommonTestBase { 36 protected: 37 template <typename LayerType> 38 void SetLayerPropertiesForTestingInternal( 39 LayerType* layer, 40 const gfx::Transform& transform, 41 const gfx::Transform& sublayer_transform, 42 gfx::PointF anchor, 43 gfx::PointF position, 44 gfx::Size bounds, 45 bool preserves3d) { 46 layer->SetTransform(transform); 47 layer->SetSublayerTransform(sublayer_transform); 48 layer->SetAnchorPoint(anchor); 49 layer->SetPosition(position); 50 layer->SetBounds(bounds); 51 layer->SetPreserves3d(preserves3d); 52 } 53 54 void SetLayerPropertiesForTesting(Layer* layer, 55 const gfx::Transform& transform, 56 const gfx::Transform& sublayer_transform, 57 gfx::PointF anchor, 58 gfx::PointF position, 59 gfx::Size bounds, 60 bool preserves3d) { 61 SetLayerPropertiesForTestingInternal<Layer>(layer, 62 transform, 63 sublayer_transform, 64 anchor, 65 position, 66 bounds, 67 preserves3d); 68 } 69 70 void SetLayerPropertiesForTesting(LayerImpl* layer, 71 const gfx::Transform& transform, 72 const gfx::Transform& sublayer_transform, 73 gfx::PointF anchor, 74 gfx::PointF position, 75 gfx::Size bounds, 76 bool preserves3d) { 77 SetLayerPropertiesForTestingInternal<LayerImpl>(layer, 78 transform, 79 sublayer_transform, 80 anchor, 81 position, 82 bounds, 83 preserves3d); 84 layer->SetContentBounds(bounds); 85 } 86 87 void ExecuteCalculateDrawProperties(Layer* root_layer, 88 float device_scale_factor, 89 float page_scale_factor, 90 Layer* page_scale_application_layer, 91 bool can_use_lcd_text) { 92 EXPECT_TRUE(page_scale_application_layer || (page_scale_factor == 1.f)); 93 gfx::Transform identity_matrix; 94 gfx::Size device_viewport_size = 95 gfx::Size(root_layer->bounds().width() * device_scale_factor, 96 root_layer->bounds().height() * device_scale_factor); 97 98 render_surface_layer_list_.reset(new RenderSurfaceLayerList); 99 100 // We are probably not testing what is intended if the root_layer bounds are 101 // empty. 102 DCHECK(!root_layer->bounds().IsEmpty()); 103 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 104 root_layer, device_viewport_size, render_surface_layer_list_.get()); 105 inputs.device_scale_factor = device_scale_factor; 106 inputs.page_scale_factor = page_scale_factor; 107 inputs.page_scale_application_layer = page_scale_application_layer; 108 inputs.can_use_lcd_text = can_use_lcd_text; 109 inputs.can_adjust_raster_scales = true; 110 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 111 } 112 113 void ExecuteCalculateDrawProperties(LayerImpl* root_layer, 114 float device_scale_factor, 115 float page_scale_factor, 116 LayerImpl* page_scale_application_layer, 117 bool can_use_lcd_text) { 118 gfx::Transform identity_matrix; 119 LayerImplList dummy_render_surface_layer_list; 120 gfx::Size device_viewport_size = 121 gfx::Size(root_layer->bounds().width() * device_scale_factor, 122 root_layer->bounds().height() * device_scale_factor); 123 124 // We are probably not testing what is intended if the root_layer bounds are 125 // empty. 126 DCHECK(!root_layer->bounds().IsEmpty()); 127 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 128 root_layer, device_viewport_size, &dummy_render_surface_layer_list); 129 inputs.device_scale_factor = device_scale_factor; 130 inputs.page_scale_factor = page_scale_factor; 131 inputs.page_scale_application_layer = page_scale_application_layer; 132 inputs.can_use_lcd_text = can_use_lcd_text; 133 inputs.can_adjust_raster_scales = true; 134 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 135 } 136 137 template <class LayerType> 138 void ExecuteCalculateDrawProperties(LayerType* root_layer) { 139 LayerType* page_scale_application_layer = NULL; 140 ExecuteCalculateDrawProperties( 141 root_layer, 1.f, 1.f, page_scale_application_layer, false); 142 } 143 144 template <class LayerType> 145 void ExecuteCalculateDrawProperties(LayerType* root_layer, 146 float device_scale_factor) { 147 LayerType* page_scale_application_layer = NULL; 148 ExecuteCalculateDrawProperties(root_layer, 149 device_scale_factor, 150 1.f, 151 page_scale_application_layer, 152 false); 153 } 154 155 template <class LayerType> 156 void ExecuteCalculateDrawProperties(LayerType* root_layer, 157 float device_scale_factor, 158 float page_scale_factor, 159 LayerType* page_scale_application_layer) { 160 ExecuteCalculateDrawProperties(root_layer, 161 device_scale_factor, 162 page_scale_factor, 163 page_scale_application_layer, 164 false); 165 } 166 167 private: 168 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_; 169 }; 170 171 class LayerTreeHostCommonTest : public LayerTreeHostCommonTestBase, 172 public testing::Test { 173 }; 174 175 class LayerWithForcedDrawsContent : public Layer { 176 public: 177 LayerWithForcedDrawsContent() : Layer() {} 178 179 virtual bool DrawsContent() const OVERRIDE; 180 181 private: 182 virtual ~LayerWithForcedDrawsContent() {} 183 }; 184 185 class LayerCanClipSelf : public Layer { 186 public: 187 LayerCanClipSelf() : Layer() {} 188 189 virtual bool DrawsContent() const OVERRIDE; 190 virtual bool CanClipSelf() const OVERRIDE; 191 192 private: 193 virtual ~LayerCanClipSelf() {} 194 }; 195 196 bool LayerWithForcedDrawsContent::DrawsContent() const { return true; } 197 198 bool LayerCanClipSelf::DrawsContent() const { return true; } 199 200 bool LayerCanClipSelf::CanClipSelf() const { return true; } 201 202 class MockContentLayerClient : public ContentLayerClient { 203 public: 204 MockContentLayerClient() {} 205 virtual ~MockContentLayerClient() {} 206 virtual void PaintContents(SkCanvas* canvas, 207 gfx::Rect clip, 208 gfx::RectF* opaque) OVERRIDE {} 209 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} 210 }; 211 212 scoped_refptr<ContentLayer> CreateDrawableContentLayer( 213 ContentLayerClient* delegate) { 214 scoped_refptr<ContentLayer> to_return = ContentLayer::Create(delegate); 215 to_return->SetIsDrawable(true); 216 return to_return; 217 } 218 219 #define EXPECT_CONTENTS_SCALE_EQ(expected, layer) \ 220 do { \ 221 EXPECT_FLOAT_EQ(expected, layer->contents_scale_x()); \ 222 EXPECT_FLOAT_EQ(expected, layer->contents_scale_y()); \ 223 } while (false) 224 225 TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) { 226 // Sanity check: For layers positioned at zero, with zero size, 227 // and with identity transforms, then the draw transform, 228 // screen space transform, and the hierarchy passed on to children 229 // layers should also be identity transforms. 230 231 scoped_refptr<Layer> parent = Layer::Create(); 232 scoped_refptr<Layer> child = Layer::Create(); 233 scoped_refptr<Layer> grand_child = Layer::Create(); 234 parent->AddChild(child); 235 child->AddChild(grand_child); 236 237 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 238 host->SetRootLayer(parent); 239 240 gfx::Transform identity_matrix; 241 SetLayerPropertiesForTesting(parent.get(), 242 identity_matrix, 243 identity_matrix, 244 gfx::PointF(), 245 gfx::PointF(), 246 gfx::Size(100, 100), 247 false); 248 SetLayerPropertiesForTesting(child.get(), 249 identity_matrix, 250 identity_matrix, 251 gfx::PointF(), 252 gfx::PointF(), 253 gfx::Size(), 254 false); 255 SetLayerPropertiesForTesting(grand_child.get(), 256 identity_matrix, 257 identity_matrix, 258 gfx::PointF(), 259 gfx::PointF(), 260 gfx::Size(), 261 false); 262 263 ExecuteCalculateDrawProperties(parent.get()); 264 265 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform()); 266 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, 267 child->screen_space_transform()); 268 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, 269 grand_child->draw_transform()); 270 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, 271 grand_child->screen_space_transform()); 272 } 273 274 TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { 275 gfx::Transform identity_matrix; 276 scoped_refptr<Layer> layer = Layer::Create(); 277 278 scoped_refptr<Layer> root = Layer::Create(); 279 SetLayerPropertiesForTesting(root.get(), 280 identity_matrix, 281 identity_matrix, 282 gfx::PointF(), 283 gfx::PointF(), 284 gfx::Size(1, 2), 285 false); 286 root->AddChild(layer); 287 288 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 289 host->SetRootLayer(root); 290 291 // Case 1: setting the sublayer transform should not affect this layer's draw 292 // transform or screen-space transform. 293 gfx::Transform arbitrary_translation; 294 arbitrary_translation.Translate(10.0, 20.0); 295 SetLayerPropertiesForTesting(layer.get(), 296 identity_matrix, 297 arbitrary_translation, 298 gfx::PointF(), 299 gfx::PointF(), 300 gfx::Size(100, 100), 301 false); 302 ExecuteCalculateDrawProperties(root.get()); 303 gfx::Transform expected_draw_transform = identity_matrix; 304 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_draw_transform, 305 layer->draw_transform()); 306 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, 307 layer->screen_space_transform()); 308 309 // Case 2: Setting the bounds of the layer should not affect either the draw 310 // transform or the screenspace transform. 311 gfx::Transform translation_to_center; 312 translation_to_center.Translate(5.0, 6.0); 313 SetLayerPropertiesForTesting(layer.get(), 314 identity_matrix, 315 identity_matrix, 316 gfx::PointF(), 317 gfx::PointF(), 318 gfx::Size(10, 12), 319 false); 320 ExecuteCalculateDrawProperties(root.get()); 321 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, layer->draw_transform()); 322 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, 323 layer->screen_space_transform()); 324 325 // Case 3: The anchor point by itself (without a layer transform) should have 326 // no effect on the transforms. 327 SetLayerPropertiesForTesting(layer.get(), 328 identity_matrix, 329 identity_matrix, 330 gfx::PointF(0.25f, 0.25f), 331 gfx::PointF(), 332 gfx::Size(10, 12), 333 false); 334 ExecuteCalculateDrawProperties(root.get()); 335 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, layer->draw_transform()); 336 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, 337 layer->screen_space_transform()); 338 339 // Case 4: A change in actual position affects both the draw transform and 340 // screen space transform. 341 gfx::Transform position_transform; 342 position_transform.Translate(0.0, 1.2); 343 SetLayerPropertiesForTesting(layer.get(), 344 identity_matrix, 345 identity_matrix, 346 gfx::PointF(0.25f, 0.25f), 347 gfx::PointF(0.f, 1.2f), 348 gfx::Size(10, 12), 349 false); 350 ExecuteCalculateDrawProperties(root.get()); 351 EXPECT_TRANSFORMATION_MATRIX_EQ(position_transform, layer->draw_transform()); 352 EXPECT_TRANSFORMATION_MATRIX_EQ(position_transform, 353 layer->screen_space_transform()); 354 355 // Case 5: In the correct sequence of transforms, the layer transform should 356 // pre-multiply the translation_to_center. This is easily tested by using a 357 // scale transform, because scale and translation are not commutative. 358 gfx::Transform layer_transform; 359 layer_transform.Scale3d(2.0, 2.0, 1.0); 360 SetLayerPropertiesForTesting(layer.get(), 361 layer_transform, 362 identity_matrix, 363 gfx::PointF(), 364 gfx::PointF(), 365 gfx::Size(10, 12), 366 false); 367 ExecuteCalculateDrawProperties(root.get()); 368 EXPECT_TRANSFORMATION_MATRIX_EQ(layer_transform, layer->draw_transform()); 369 EXPECT_TRANSFORMATION_MATRIX_EQ(layer_transform, 370 layer->screen_space_transform()); 371 372 // Case 6: The layer transform should occur with respect to the anchor point. 373 gfx::Transform translation_to_anchor; 374 translation_to_anchor.Translate(5.0, 0.0); 375 gfx::Transform expected_result = 376 translation_to_anchor * layer_transform * Inverse(translation_to_anchor); 377 SetLayerPropertiesForTesting(layer.get(), 378 layer_transform, 379 identity_matrix, 380 gfx::PointF(0.5f, 0.f), 381 gfx::PointF(), 382 gfx::Size(10, 12), 383 false); 384 ExecuteCalculateDrawProperties(root.get()); 385 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_result, layer->draw_transform()); 386 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_result, 387 layer->screen_space_transform()); 388 389 // Case 7: Verify that position pre-multiplies the layer transform. The 390 // current implementation of CalculateDrawProperties does this implicitly, but 391 // it is still worth testing to detect accidental regressions. 392 expected_result = position_transform * translation_to_anchor * 393 layer_transform * Inverse(translation_to_anchor); 394 SetLayerPropertiesForTesting(layer.get(), 395 layer_transform, 396 identity_matrix, 397 gfx::PointF(0.5f, 0.f), 398 gfx::PointF(0.f, 1.2f), 399 gfx::Size(10, 12), 400 false); 401 ExecuteCalculateDrawProperties(root.get()); 402 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_result, layer->draw_transform()); 403 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_result, 404 layer->screen_space_transform()); 405 } 406 407 TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { 408 const gfx::Vector2d kScrollOffset(50, 100); 409 const gfx::Vector2dF kScrollDelta(2.34f, 5.67f); 410 const gfx::Vector2d kMaxScrollOffset(200, 200); 411 const gfx::PointF kScrollLayerPosition(-kScrollOffset.x(), 412 -kScrollOffset.y()); 413 const float kPageScale = 0.888f; 414 const float kDeviceScale = 1.666f; 415 416 FakeImplProxy proxy; 417 FakeLayerTreeHostImpl host_impl(&proxy); 418 419 gfx::Transform identity_matrix; 420 scoped_ptr<LayerImpl> sublayer_scoped_ptr( 421 LayerImpl::Create(host_impl.active_tree(), 1)); 422 LayerImpl* sublayer = sublayer_scoped_ptr.get(); 423 sublayer->SetContentsScale(kPageScale * kDeviceScale, 424 kPageScale * kDeviceScale); 425 SetLayerPropertiesForTesting(sublayer, 426 identity_matrix, 427 identity_matrix, 428 gfx::Point(), 429 gfx::PointF(), 430 gfx::Size(500, 500), 431 false); 432 433 scoped_ptr<LayerImpl> scroll_layerScopedPtr( 434 LayerImpl::Create(host_impl.active_tree(), 2)); 435 LayerImpl* scroll_layer = scroll_layerScopedPtr.get(); 436 SetLayerPropertiesForTesting(scroll_layer, 437 identity_matrix, 438 identity_matrix, 439 gfx::PointF(), 440 gfx::PointF(), 441 gfx::Size(10, 20), 442 false); 443 scroll_layer->SetScrollable(true); 444 scroll_layer->SetMaxScrollOffset(kMaxScrollOffset); 445 scroll_layer->SetScrollOffset(kScrollOffset); 446 scroll_layer->SetScrollDelta(kScrollDelta); 447 gfx::Transform impl_transform; 448 scroll_layer->AddChild(sublayer_scoped_ptr.Pass()); 449 450 scoped_ptr<LayerImpl> root(LayerImpl::Create(host_impl.active_tree(), 3)); 451 SetLayerPropertiesForTesting(root.get(), 452 identity_matrix, 453 identity_matrix, 454 gfx::PointF(), 455 gfx::PointF(), 456 gfx::Size(3, 4), 457 false); 458 root->AddChild(scroll_layerScopedPtr.Pass()); 459 460 ExecuteCalculateDrawProperties( 461 root.get(), kDeviceScale, kPageScale, scroll_layer->parent()); 462 gfx::Transform expected_transform = identity_matrix; 463 gfx::PointF sub_layer_screen_position = kScrollLayerPosition - kScrollDelta; 464 sub_layer_screen_position.Scale(kPageScale * kDeviceScale); 465 expected_transform.Translate(MathUtil::Round(sub_layer_screen_position.x()), 466 MathUtil::Round(sub_layer_screen_position.y())); 467 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, 468 sublayer->draw_transform()); 469 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, 470 sublayer->screen_space_transform()); 471 472 gfx::Transform arbitrary_translate; 473 const float kTranslateX = 10.6f; 474 const float kTranslateY = 20.6f; 475 arbitrary_translate.Translate(kTranslateX, kTranslateY); 476 SetLayerPropertiesForTesting(scroll_layer, 477 arbitrary_translate, 478 identity_matrix, 479 gfx::PointF(), 480 gfx::PointF(), 481 gfx::Size(10, 20), 482 false); 483 ExecuteCalculateDrawProperties( 484 root.get(), kDeviceScale, kPageScale, scroll_layer->parent()); 485 expected_transform.MakeIdentity(); 486 expected_transform.Translate( 487 MathUtil::Round(kTranslateX * kPageScale * kDeviceScale + 488 sub_layer_screen_position.x()), 489 MathUtil::Round(kTranslateY * kPageScale * kDeviceScale + 490 sub_layer_screen_position.y())); 491 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, 492 sublayer->draw_transform()); 493 } 494 495 TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { 496 gfx::Transform identity_matrix; 497 scoped_refptr<Layer> root = Layer::Create(); 498 scoped_refptr<Layer> parent = Layer::Create(); 499 scoped_refptr<Layer> child = Layer::Create(); 500 scoped_refptr<Layer> grand_child = Layer::Create(); 501 root->AddChild(parent); 502 parent->AddChild(child); 503 child->AddChild(grand_child); 504 505 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 506 host->SetRootLayer(root); 507 508 // One-time setup of root layer 509 SetLayerPropertiesForTesting(root.get(), 510 identity_matrix, 511 identity_matrix, 512 gfx::PointF(), 513 gfx::PointF(), 514 gfx::Size(1, 2), 515 false); 516 517 // Case 1: parent's anchor point should not affect child or grand_child. 518 SetLayerPropertiesForTesting(parent.get(), 519 identity_matrix, 520 identity_matrix, 521 gfx::PointF(0.25f, 0.25f), 522 gfx::PointF(), 523 gfx::Size(10, 12), 524 false); 525 SetLayerPropertiesForTesting(child.get(), 526 identity_matrix, 527 identity_matrix, 528 gfx::PointF(), 529 gfx::PointF(), 530 gfx::Size(16, 18), 531 false); 532 SetLayerPropertiesForTesting(grand_child.get(), 533 identity_matrix, 534 identity_matrix, 535 gfx::PointF(), 536 gfx::PointF(), 537 gfx::Size(76, 78), 538 false); 539 ExecuteCalculateDrawProperties(root.get()); 540 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform()); 541 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, 542 child->screen_space_transform()); 543 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, 544 grand_child->draw_transform()); 545 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, 546 grand_child->screen_space_transform()); 547 548 // Case 2: parent's position affects child and grand_child. 549 gfx::Transform parent_position_transform; 550 parent_position_transform.Translate(0.0, 1.2); 551 SetLayerPropertiesForTesting(parent.get(), 552 identity_matrix, 553 identity_matrix, 554 gfx::PointF(0.25f, 0.25f), 555 gfx::PointF(0.f, 1.2f), 556 gfx::Size(10, 12), 557 false); 558 SetLayerPropertiesForTesting(child.get(), 559 identity_matrix, 560 identity_matrix, 561 gfx::PointF(), 562 gfx::PointF(), 563 gfx::Size(16, 18), 564 false); 565 SetLayerPropertiesForTesting(grand_child.get(), 566 identity_matrix, 567 identity_matrix, 568 gfx::PointF(), 569 gfx::PointF(), 570 gfx::Size(76, 78), 571 false); 572 ExecuteCalculateDrawProperties(root.get()); 573 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_position_transform, 574 child->draw_transform()); 575 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_position_transform, 576 child->screen_space_transform()); 577 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_position_transform, 578 grand_child->draw_transform()); 579 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_position_transform, 580 grand_child->screen_space_transform()); 581 582 // Case 3: parent's local transform affects child and grandchild 583 gfx::Transform parent_layer_transform; 584 parent_layer_transform.Scale3d(2.0, 2.0, 1.0); 585 gfx::Transform parent_translation_to_anchor; 586 parent_translation_to_anchor.Translate(2.5, 3.0); 587 gfx::Transform parent_composite_transform = 588 parent_translation_to_anchor * parent_layer_transform * 589 Inverse(parent_translation_to_anchor); 590 SetLayerPropertiesForTesting(parent.get(), 591 parent_layer_transform, 592 identity_matrix, 593 gfx::PointF(0.25f, 0.25f), 594 gfx::PointF(), 595 gfx::Size(10, 12), 596 false); 597 SetLayerPropertiesForTesting(child.get(), 598 identity_matrix, 599 identity_matrix, 600 gfx::PointF(), 601 gfx::PointF(), 602 gfx::Size(16, 18), 603 false); 604 SetLayerPropertiesForTesting(grand_child.get(), 605 identity_matrix, 606 identity_matrix, 607 gfx::PointF(), 608 gfx::PointF(), 609 gfx::Size(76, 78), 610 false); 611 ExecuteCalculateDrawProperties(root.get()); 612 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform, 613 child->draw_transform()); 614 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform, 615 child->screen_space_transform()); 616 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform, 617 grand_child->draw_transform()); 618 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform, 619 grand_child->screen_space_transform()); 620 621 // Case 4: parent's sublayer matrix affects child and grandchild scaling is 622 // used here again so that the correct sequence of transforms is properly 623 // tested. Note that preserves3d is false, but the sublayer matrix should 624 // retain its 3D properties when given to child. But then, the child also 625 // does not preserve3D. When it gives its hierarchy to the grand_child, it 626 // should be flattened to 2D. 627 gfx::Transform parent_sublayer_matrix; 628 parent_sublayer_matrix.Scale3d(10.0, 10.0, 3.3); 629 // Sublayer matrix is applied to the anchor point of the parent layer. 630 parent_composite_transform = 631 parent_translation_to_anchor * parent_layer_transform * 632 Inverse(parent_translation_to_anchor) * parent_translation_to_anchor * 633 parent_sublayer_matrix * Inverse(parent_translation_to_anchor); 634 gfx::Transform flattened_composite_transform = parent_composite_transform; 635 flattened_composite_transform.FlattenTo2d(); 636 SetLayerPropertiesForTesting(parent.get(), 637 parent_layer_transform, 638 parent_sublayer_matrix, 639 gfx::PointF(0.25f, 0.25f), 640 gfx::PointF(), 641 gfx::Size(10, 12), 642 false); 643 SetLayerPropertiesForTesting(child.get(), 644 identity_matrix, 645 identity_matrix, 646 gfx::PointF(), 647 gfx::PointF(), 648 gfx::Size(16, 18), 649 false); 650 SetLayerPropertiesForTesting(grand_child.get(), 651 identity_matrix, 652 identity_matrix, 653 gfx::PointF(), 654 gfx::PointF(), 655 gfx::Size(76, 78), 656 false); 657 ExecuteCalculateDrawProperties(root.get()); 658 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform, 659 child->draw_transform()); 660 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform, 661 child->screen_space_transform()); 662 EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_composite_transform, 663 grand_child->draw_transform()); 664 EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_composite_transform, 665 grand_child->screen_space_transform()); 666 667 // Case 5: same as Case 4, except that child does preserve 3D, so the 668 // grand_child should receive the non-flattened composite transform. 669 SetLayerPropertiesForTesting(parent.get(), 670 parent_layer_transform, 671 parent_sublayer_matrix, 672 gfx::PointF(0.25f, 0.25f), 673 gfx::PointF(), 674 gfx::Size(10, 12), 675 false); 676 SetLayerPropertiesForTesting(child.get(), 677 identity_matrix, 678 identity_matrix, 679 gfx::PointF(), 680 gfx::PointF(), 681 gfx::Size(16, 18), 682 true); 683 SetLayerPropertiesForTesting(grand_child.get(), 684 identity_matrix, 685 identity_matrix, 686 gfx::PointF(), 687 gfx::PointF(), 688 gfx::Size(76, 78), 689 false); 690 ExecuteCalculateDrawProperties(root.get()); 691 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform, 692 child->draw_transform()); 693 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform, 694 child->screen_space_transform()); 695 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform, 696 grand_child->draw_transform()); 697 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform, 698 grand_child->screen_space_transform()); 699 } 700 701 TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { 702 scoped_refptr<Layer> root = Layer::Create(); 703 scoped_refptr<Layer> parent = Layer::Create(); 704 scoped_refptr<Layer> child = Layer::Create(); 705 scoped_refptr<LayerWithForcedDrawsContent> grand_child = 706 make_scoped_refptr(new LayerWithForcedDrawsContent()); 707 root->AddChild(parent); 708 parent->AddChild(child); 709 child->AddChild(grand_child); 710 711 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 712 host->SetRootLayer(root); 713 714 // One-time setup of root layer 715 gfx::Transform identity_matrix; 716 SetLayerPropertiesForTesting(root.get(), 717 identity_matrix, 718 identity_matrix, 719 gfx::PointF(), 720 gfx::PointF(), 721 gfx::Size(1, 2), 722 false); 723 724 // Child is set up so that a new render surface should be created. 725 child->SetOpacity(0.5f); 726 child->SetForceRenderSurface(true); 727 728 gfx::Transform parent_layer_transform; 729 parent_layer_transform.Scale3d(1.0, 0.9, 1.0); 730 gfx::Transform parent_translation_to_anchor; 731 parent_translation_to_anchor.Translate(25.0, 30.0); 732 gfx::Transform parent_sublayer_matrix; 733 parent_sublayer_matrix.Scale3d(0.9, 1.0, 3.3); 734 735 gfx::Transform parent_composite_transform = 736 parent_translation_to_anchor * parent_layer_transform * 737 Inverse(parent_translation_to_anchor) * parent_translation_to_anchor * 738 parent_sublayer_matrix * Inverse(parent_translation_to_anchor); 739 gfx::Vector2dF parent_composite_scale = 740 MathUtil::ComputeTransform2dScaleComponents(parent_composite_transform, 741 1.f); 742 gfx::Transform surface_sublayer_transform; 743 surface_sublayer_transform.Scale(parent_composite_scale.x(), 744 parent_composite_scale.y()); 745 gfx::Transform surface_sublayer_composite_transform = 746 parent_composite_transform * Inverse(surface_sublayer_transform); 747 748 // Child's render surface should not exist yet. 749 ASSERT_FALSE(child->render_surface()); 750 751 SetLayerPropertiesForTesting(parent.get(), 752 parent_layer_transform, 753 parent_sublayer_matrix, 754 gfx::PointF(0.25f, 0.25f), 755 gfx::PointF(), 756 gfx::Size(100, 120), 757 false); 758 SetLayerPropertiesForTesting(child.get(), 759 identity_matrix, 760 identity_matrix, 761 gfx::PointF(), 762 gfx::PointF(), 763 gfx::Size(16, 18), 764 false); 765 SetLayerPropertiesForTesting(grand_child.get(), 766 identity_matrix, 767 identity_matrix, 768 gfx::PointF(), 769 gfx::PointF(), 770 gfx::Size(8, 10), 771 false); 772 ExecuteCalculateDrawProperties(root.get()); 773 774 // Render surface should have been created now. 775 ASSERT_TRUE(child->render_surface()); 776 ASSERT_EQ(child, child->render_target()); 777 778 // The child layer's draw transform should refer to its new render surface. 779 // The screen-space transform, however, should still refer to the root. 780 EXPECT_TRANSFORMATION_MATRIX_EQ(surface_sublayer_transform, 781 child->draw_transform()); 782 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform, 783 child->screen_space_transform()); 784 785 // Because the grand_child is the only drawable content, the child's render 786 // surface will tighten its bounds to the grand_child. The scale at which the 787 // surface's subtree is drawn must be removed from the composite transform. 788 EXPECT_TRANSFORMATION_MATRIX_EQ( 789 surface_sublayer_composite_transform, 790 child->render_target()->render_surface()->draw_transform()); 791 792 // The screen space is the same as the target since the child surface draws 793 // into the root. 794 EXPECT_TRANSFORMATION_MATRIX_EQ( 795 surface_sublayer_composite_transform, 796 child->render_target()->render_surface()->screen_space_transform()); 797 } 798 799 TEST_F(LayerTreeHostCommonTest, SublayerTransformWithAnchorPoint) { 800 // crbug.com/157961 - we were always applying the sublayer transform about 801 // the center of the layer, rather than the anchor point. 802 803 scoped_refptr<Layer> root = Layer::Create(); 804 scoped_refptr<Layer> parent = Layer::Create(); 805 scoped_refptr<LayerWithForcedDrawsContent> child = 806 make_scoped_refptr(new LayerWithForcedDrawsContent()); 807 root->AddChild(parent); 808 parent->AddChild(child); 809 810 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 811 host->SetRootLayer(root); 812 813 gfx::Transform identity_matrix; 814 gfx::Transform parent_sublayer_matrix; 815 parent_sublayer_matrix.ApplyPerspectiveDepth(2.0); 816 gfx::PointF parent_anchor_point(0.2f, 0.8f); 817 818 SetLayerPropertiesForTesting(root.get(), 819 identity_matrix, 820 identity_matrix, 821 gfx::PointF(), 822 gfx::PointF(), 823 gfx::Size(1, 2), 824 false); 825 SetLayerPropertiesForTesting(parent.get(), 826 identity_matrix, 827 parent_sublayer_matrix, 828 parent_anchor_point, 829 gfx::PointF(), 830 gfx::Size(100, 100), 831 false); 832 SetLayerPropertiesForTesting(child.get(), 833 identity_matrix, 834 identity_matrix, 835 gfx::PointF(), 836 gfx::PointF(), 837 gfx::Size(10, 10), 838 false); 839 ExecuteCalculateDrawProperties(root.get()); 840 841 gfx::Transform expected_child_draw_transform; 842 expected_child_draw_transform.Translate(20.0, 80.0); 843 expected_child_draw_transform.ApplyPerspectiveDepth(2.0); 844 expected_child_draw_transform.Translate(-20.0, -80.0); 845 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_draw_transform, 846 child->draw_transform()); 847 } 848 849 TEST_F(LayerTreeHostCommonTest, SeparateRenderTargetRequirementWithClipping) { 850 scoped_refptr<Layer> root = Layer::Create(); 851 scoped_refptr<Layer> parent = Layer::Create(); 852 scoped_refptr<Layer> child = Layer::Create(); 853 scoped_refptr<Layer> grand_child = make_scoped_refptr(new LayerCanClipSelf()); 854 root->AddChild(parent); 855 parent->AddChild(child); 856 child->AddChild(grand_child); 857 parent->SetMasksToBounds(true); 858 child->SetMasksToBounds(true); 859 860 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 861 host->SetRootLayer(root); 862 863 gfx::Transform identity_matrix; 864 gfx::Transform parent_layer_transform; 865 gfx::Transform parent_sublayer_matrix; 866 gfx::Transform child_layer_matrix; 867 868 // No render surface should exist yet. 869 EXPECT_FALSE(root->render_surface()); 870 EXPECT_FALSE(parent->render_surface()); 871 EXPECT_FALSE(child->render_surface()); 872 EXPECT_FALSE(grand_child->render_surface()); 873 874 // One-time setup of root layer 875 parent_layer_transform.Scale3d(1.0, 0.9, 1.0); 876 parent_sublayer_matrix.Scale3d(0.9, 1.0, 3.3); 877 child_layer_matrix.Rotate(20.0); 878 879 SetLayerPropertiesForTesting(root.get(), 880 identity_matrix, 881 identity_matrix, 882 gfx::PointF(), 883 gfx::PointF(), 884 gfx::Size(1, 2), 885 false); 886 SetLayerPropertiesForTesting(parent.get(), 887 parent_layer_transform, 888 parent_sublayer_matrix, 889 gfx::PointF(0.25f, 0.25f), 890 gfx::PointF(), 891 gfx::Size(100, 120), 892 false); 893 SetLayerPropertiesForTesting(child.get(), 894 child_layer_matrix, 895 identity_matrix, 896 gfx::PointF(), 897 gfx::PointF(), 898 gfx::Size(16, 18), 899 false); 900 SetLayerPropertiesForTesting(grand_child.get(), 901 identity_matrix, 902 identity_matrix, 903 gfx::PointF(), 904 gfx::PointF(), 905 gfx::Size(8, 10), 906 false); 907 908 ExecuteCalculateDrawProperties(root.get()); 909 910 // Render surfaces should have been created according to clipping rules now 911 // (grandchild can clip self). 912 EXPECT_TRUE(root->render_surface()); 913 EXPECT_FALSE(parent->render_surface()); 914 EXPECT_FALSE(child->render_surface()); 915 EXPECT_FALSE(grand_child->render_surface()); 916 } 917 918 TEST_F(LayerTreeHostCommonTest, 919 SeparateRenderTargetRequirementWithoutClipping) { 920 scoped_refptr<Layer> root = Layer::Create(); 921 scoped_refptr<Layer> parent = Layer::Create(); 922 scoped_refptr<Layer> child = Layer::Create(); 923 // This layer cannot clip itself, a feature we are testing here. 924 scoped_refptr<Layer> grand_child = 925 make_scoped_refptr(new LayerWithForcedDrawsContent()); 926 root->AddChild(parent); 927 parent->AddChild(child); 928 child->AddChild(grand_child); 929 parent->SetMasksToBounds(true); 930 child->SetMasksToBounds(true); 931 932 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 933 host->SetRootLayer(root); 934 935 gfx::Transform identity_matrix; 936 gfx::Transform parent_layer_transform; 937 gfx::Transform parent_sublayer_matrix; 938 gfx::Transform child_layer_matrix; 939 940 // No render surface should exist yet. 941 EXPECT_FALSE(root->render_surface()); 942 EXPECT_FALSE(parent->render_surface()); 943 EXPECT_FALSE(child->render_surface()); 944 EXPECT_FALSE(grand_child->render_surface()); 945 946 // One-time setup of root layer 947 parent_layer_transform.Scale3d(1.0, 0.9, 1.0); 948 parent_sublayer_matrix.Scale3d(0.9, 1.0, 3.3); 949 child_layer_matrix.Rotate(20.0); 950 951 SetLayerPropertiesForTesting(root.get(), 952 identity_matrix, 953 identity_matrix, 954 gfx::PointF(), 955 gfx::PointF(), 956 gfx::Size(1, 2), 957 false); 958 SetLayerPropertiesForTesting(parent.get(), 959 parent_layer_transform, 960 parent_sublayer_matrix, 961 gfx::PointF(0.25f, 0.25f), 962 gfx::PointF(), 963 gfx::Size(100, 120), 964 false); 965 SetLayerPropertiesForTesting(child.get(), 966 child_layer_matrix, 967 identity_matrix, 968 gfx::PointF(), 969 gfx::PointF(), 970 gfx::Size(16, 18), 971 false); 972 SetLayerPropertiesForTesting(grand_child.get(), 973 identity_matrix, 974 identity_matrix, 975 gfx::PointF(), 976 gfx::PointF(), 977 gfx::Size(8, 10), 978 false); 979 980 ExecuteCalculateDrawProperties(root.get()); 981 982 // Render surfaces should have been created according to clipping rules now 983 // (grandchild can't clip self). 984 EXPECT_TRUE(root->render_surface()); 985 EXPECT_FALSE(parent->render_surface()); 986 EXPECT_TRUE(child->render_surface()); 987 EXPECT_FALSE(grand_child->render_surface()); 988 } 989 990 TEST_F(LayerTreeHostCommonTest, TransformsForReplica) { 991 scoped_refptr<Layer> root = Layer::Create(); 992 scoped_refptr<Layer> parent = Layer::Create(); 993 scoped_refptr<Layer> child = Layer::Create(); 994 scoped_refptr<Layer> child_replica = Layer::Create(); 995 scoped_refptr<LayerWithForcedDrawsContent> grand_child = 996 make_scoped_refptr(new LayerWithForcedDrawsContent()); 997 root->AddChild(parent); 998 parent->AddChild(child); 999 child->AddChild(grand_child); 1000 child->SetReplicaLayer(child_replica.get()); 1001 1002 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 1003 host->SetRootLayer(root); 1004 1005 // One-time setup of root layer 1006 gfx::Transform identity_matrix; 1007 SetLayerPropertiesForTesting(root.get(), 1008 identity_matrix, 1009 identity_matrix, 1010 gfx::PointF(), 1011 gfx::PointF(), 1012 gfx::Size(1, 2), 1013 false); 1014 1015 // Child is set up so that a new render surface should be created. 1016 child->SetOpacity(0.5f); 1017 1018 gfx::Transform parent_layer_transform; 1019 parent_layer_transform.Scale3d(2.0, 2.0, 1.0); 1020 gfx::Transform parent_translation_to_anchor; 1021 parent_translation_to_anchor.Translate(2.5, 3.0); 1022 gfx::Transform parent_sublayer_matrix; 1023 parent_sublayer_matrix.Scale3d(10.0, 10.0, 3.3); 1024 gfx::Transform parent_composite_transform = 1025 parent_translation_to_anchor * parent_layer_transform * 1026 Inverse(parent_translation_to_anchor) * parent_translation_to_anchor * 1027 parent_sublayer_matrix * Inverse(parent_translation_to_anchor); 1028 gfx::Transform replica_layer_transform; 1029 replica_layer_transform.Scale3d(3.0, 3.0, 1.0); 1030 gfx::Vector2dF parent_composite_scale = 1031 MathUtil::ComputeTransform2dScaleComponents(parent_composite_transform, 1032 1.f); 1033 gfx::Transform surface_sublayer_transform; 1034 surface_sublayer_transform.Scale(parent_composite_scale.x(), 1035 parent_composite_scale.y()); 1036 gfx::Transform replica_composite_transform = 1037 parent_composite_transform * replica_layer_transform * 1038 Inverse(surface_sublayer_transform); 1039 1040 // Child's render surface should not exist yet. 1041 ASSERT_FALSE(child->render_surface()); 1042 1043 SetLayerPropertiesForTesting(parent.get(), 1044 parent_layer_transform, 1045 parent_sublayer_matrix, 1046 gfx::PointF(0.25f, 0.25f), 1047 gfx::PointF(), 1048 gfx::Size(10, 12), 1049 false); 1050 SetLayerPropertiesForTesting(child.get(), 1051 identity_matrix, 1052 identity_matrix, 1053 gfx::PointF(), 1054 gfx::PointF(), 1055 gfx::Size(16, 18), 1056 false); 1057 SetLayerPropertiesForTesting(grand_child.get(), 1058 identity_matrix, 1059 identity_matrix, 1060 gfx::PointF(), 1061 gfx::PointF(-0.5f, -0.5f), 1062 gfx::Size(1, 1), 1063 false); 1064 SetLayerPropertiesForTesting(child_replica.get(), 1065 replica_layer_transform, 1066 identity_matrix, 1067 gfx::PointF(), 1068 gfx::PointF(), 1069 gfx::Size(), 1070 false); 1071 ExecuteCalculateDrawProperties(root.get()); 1072 1073 // Render surface should have been created now. 1074 ASSERT_TRUE(child->render_surface()); 1075 ASSERT_EQ(child, child->render_target()); 1076 1077 EXPECT_TRANSFORMATION_MATRIX_EQ( 1078 replica_composite_transform, 1079 child->render_target()->render_surface()->replica_draw_transform()); 1080 EXPECT_TRANSFORMATION_MATRIX_EQ(replica_composite_transform, 1081 child->render_target()->render_surface() 1082 ->replica_screen_space_transform()); 1083 } 1084 1085 TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { 1086 // This test creates a more complex tree and verifies it all at once. This 1087 // covers the following cases: 1088 // - layers that are described w.r.t. a render surface: should have draw 1089 // transforms described w.r.t. that surface 1090 // - A render surface described w.r.t. an ancestor render surface: should 1091 // have a draw transform described w.r.t. that ancestor surface 1092 // - Replicas of a render surface are described w.r.t. the replica's 1093 // transform around its anchor, along with the surface itself. 1094 // - Sanity check on recursion: verify transforms of layers described w.r.t. 1095 // a render surface that is described w.r.t. an ancestor render surface. 1096 // - verifying that each layer has a reference to the correct render surface 1097 // and render target values. 1098 1099 scoped_refptr<Layer> root = Layer::Create(); 1100 scoped_refptr<Layer> parent = Layer::Create(); 1101 scoped_refptr<Layer> render_surface1 = Layer::Create(); 1102 scoped_refptr<Layer> render_surface2 = Layer::Create(); 1103 scoped_refptr<Layer> child_of_root = Layer::Create(); 1104 scoped_refptr<Layer> child_of_rs1 = Layer::Create(); 1105 scoped_refptr<Layer> child_of_rs2 = Layer::Create(); 1106 scoped_refptr<Layer> replica_of_rs1 = Layer::Create(); 1107 scoped_refptr<Layer> replica_of_rs2 = Layer::Create(); 1108 scoped_refptr<Layer> grand_child_of_root = Layer::Create(); 1109 scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs1 = 1110 make_scoped_refptr(new LayerWithForcedDrawsContent()); 1111 scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs2 = 1112 make_scoped_refptr(new LayerWithForcedDrawsContent()); 1113 root->AddChild(parent); 1114 parent->AddChild(render_surface1); 1115 parent->AddChild(child_of_root); 1116 render_surface1->AddChild(child_of_rs1); 1117 render_surface1->AddChild(render_surface2); 1118 render_surface2->AddChild(child_of_rs2); 1119 child_of_root->AddChild(grand_child_of_root); 1120 child_of_rs1->AddChild(grand_child_of_rs1); 1121 child_of_rs2->AddChild(grand_child_of_rs2); 1122 render_surface1->SetReplicaLayer(replica_of_rs1.get()); 1123 render_surface2->SetReplicaLayer(replica_of_rs2.get()); 1124 1125 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 1126 host->SetRootLayer(root); 1127 1128 // In combination with descendant draws content, opacity != 1 forces the layer 1129 // to have a new render surface. 1130 render_surface1->SetOpacity(0.5f); 1131 render_surface2->SetOpacity(0.33f); 1132 1133 // One-time setup of root layer 1134 gfx::Transform identity_matrix; 1135 SetLayerPropertiesForTesting(root.get(), 1136 identity_matrix, 1137 identity_matrix, 1138 gfx::PointF(), 1139 gfx::PointF(), 1140 gfx::Size(1, 2), 1141 false); 1142 1143 // All layers in the tree are initialized with an anchor at .25 and a size of 1144 // (10,10). matrix "A" is the composite layer transform used in all layers, 1145 // centered about the anchor point. matrix "B" is the sublayer transform used 1146 // in all layers, centered about the center position of the layer. matrix "R" 1147 // is the composite replica transform used in all replica layers. 1148 // 1149 // x component tests that layer_transform and sublayer_transform are done in 1150 // the right order (translation and scale are noncommutative). y component 1151 // has a translation by 1 for every ancestor, which indicates the "depth" of 1152 // the layer in the hierarchy. 1153 gfx::Transform translation_to_anchor; 1154 translation_to_anchor.Translate(2.5, 0.0); 1155 gfx::Transform layer_transform; 1156 layer_transform.Translate(1.0, 1.0); 1157 gfx::Transform sublayer_transform; 1158 sublayer_transform.Scale3d(10.0, 1.0, 1.0); 1159 gfx::Transform replica_layer_transform; 1160 replica_layer_transform.Scale3d(-2.0, 5.0, 1.0); 1161 1162 gfx::Transform A = 1163 translation_to_anchor * layer_transform * Inverse(translation_to_anchor); 1164 gfx::Transform B = translation_to_anchor * sublayer_transform * 1165 Inverse(translation_to_anchor); 1166 gfx::Transform R = A * translation_to_anchor * replica_layer_transform * 1167 Inverse(translation_to_anchor); 1168 1169 gfx::Vector2dF surface1_parent_transform_scale = 1170 MathUtil::ComputeTransform2dScaleComponents(A * B, 1.f); 1171 gfx::Transform surface1_sublayer_transform; 1172 surface1_sublayer_transform.Scale(surface1_parent_transform_scale.x(), 1173 surface1_parent_transform_scale.y()); 1174 1175 // SS1 = transform given to the subtree of render_surface1 1176 gfx::Transform SS1 = surface1_sublayer_transform; 1177 // S1 = transform to move from render_surface1 pixels to the layer space of 1178 // the owning layer 1179 gfx::Transform S1 = Inverse(surface1_sublayer_transform); 1180 1181 gfx::Vector2dF surface2_parent_transform_scale = 1182 MathUtil::ComputeTransform2dScaleComponents(SS1 * A * B, 1.f); 1183 gfx::Transform surface2_sublayer_transform; 1184 surface2_sublayer_transform.Scale(surface2_parent_transform_scale.x(), 1185 surface2_parent_transform_scale.y()); 1186 1187 // SS2 = transform given to the subtree of render_surface2 1188 gfx::Transform SS2 = surface2_sublayer_transform; 1189 // S2 = transform to move from render_surface2 pixels to the layer space of 1190 // the owning layer 1191 gfx::Transform S2 = Inverse(surface2_sublayer_transform); 1192 1193 SetLayerPropertiesForTesting(parent.get(), 1194 layer_transform, 1195 sublayer_transform, 1196 gfx::PointF(0.25f, 0.f), 1197 gfx::PointF(), 1198 gfx::Size(10, 10), 1199 false); 1200 SetLayerPropertiesForTesting(render_surface1.get(), 1201 layer_transform, 1202 sublayer_transform, 1203 gfx::PointF(0.25f, 0.f), 1204 gfx::PointF(), 1205 gfx::Size(10, 10), 1206 false); 1207 SetLayerPropertiesForTesting(render_surface2.get(), 1208 layer_transform, 1209 sublayer_transform, 1210 gfx::PointF(0.25f, 0.f), 1211 gfx::PointF(), 1212 gfx::Size(10, 10), 1213 false); 1214 SetLayerPropertiesForTesting(child_of_root.get(), 1215 layer_transform, 1216 sublayer_transform, 1217 gfx::PointF(0.25f, 0.f), 1218 gfx::PointF(), 1219 gfx::Size(10, 10), 1220 false); 1221 SetLayerPropertiesForTesting(child_of_rs1.get(), 1222 layer_transform, 1223 sublayer_transform, 1224 gfx::PointF(0.25f, 0.f), 1225 gfx::PointF(), 1226 gfx::Size(10, 10), 1227 false); 1228 SetLayerPropertiesForTesting(child_of_rs2.get(), 1229 layer_transform, 1230 sublayer_transform, 1231 gfx::PointF(0.25f, 0.f), 1232 gfx::PointF(), 1233 gfx::Size(10, 10), 1234 false); 1235 SetLayerPropertiesForTesting(grand_child_of_root.get(), 1236 layer_transform, 1237 sublayer_transform, 1238 gfx::PointF(0.25f, 0.f), 1239 gfx::PointF(), 1240 gfx::Size(10, 10), 1241 false); 1242 SetLayerPropertiesForTesting(grand_child_of_rs1.get(), 1243 layer_transform, 1244 sublayer_transform, 1245 gfx::PointF(0.25f, 0.f), 1246 gfx::PointF(), 1247 gfx::Size(10, 10), 1248 false); 1249 SetLayerPropertiesForTesting(grand_child_of_rs2.get(), 1250 layer_transform, 1251 sublayer_transform, 1252 gfx::PointF(0.25f, 0.f), 1253 gfx::PointF(), 1254 gfx::Size(10, 10), 1255 false); 1256 SetLayerPropertiesForTesting(replica_of_rs1.get(), 1257 replica_layer_transform, 1258 sublayer_transform, 1259 gfx::PointF(0.25f, 0.f), 1260 gfx::PointF(), 1261 gfx::Size(), 1262 false); 1263 SetLayerPropertiesForTesting(replica_of_rs2.get(), 1264 replica_layer_transform, 1265 sublayer_transform, 1266 gfx::PointF(0.25f, 0.f), 1267 gfx::PointF(), 1268 gfx::Size(), 1269 false); 1270 1271 ExecuteCalculateDrawProperties(root.get()); 1272 1273 // Only layers that are associated with render surfaces should have an actual 1274 // RenderSurface() value. 1275 ASSERT_TRUE(root->render_surface()); 1276 ASSERT_FALSE(child_of_root->render_surface()); 1277 ASSERT_FALSE(grand_child_of_root->render_surface()); 1278 1279 ASSERT_TRUE(render_surface1->render_surface()); 1280 ASSERT_FALSE(child_of_rs1->render_surface()); 1281 ASSERT_FALSE(grand_child_of_rs1->render_surface()); 1282 1283 ASSERT_TRUE(render_surface2->render_surface()); 1284 ASSERT_FALSE(child_of_rs2->render_surface()); 1285 ASSERT_FALSE(grand_child_of_rs2->render_surface()); 1286 1287 // Verify all render target accessors 1288 EXPECT_EQ(root, parent->render_target()); 1289 EXPECT_EQ(root, child_of_root->render_target()); 1290 EXPECT_EQ(root, grand_child_of_root->render_target()); 1291 1292 EXPECT_EQ(render_surface1, render_surface1->render_target()); 1293 EXPECT_EQ(render_surface1, child_of_rs1->render_target()); 1294 EXPECT_EQ(render_surface1, grand_child_of_rs1->render_target()); 1295 1296 EXPECT_EQ(render_surface2, render_surface2->render_target()); 1297 EXPECT_EQ(render_surface2, child_of_rs2->render_target()); 1298 EXPECT_EQ(render_surface2, grand_child_of_rs2->render_target()); 1299 1300 // Verify layer draw transforms note that draw transforms are described with 1301 // respect to the nearest ancestor render surface but screen space transforms 1302 // are described with respect to the root. 1303 EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->draw_transform()); 1304 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, child_of_root->draw_transform()); 1305 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, 1306 grand_child_of_root->draw_transform()); 1307 1308 EXPECT_TRANSFORMATION_MATRIX_EQ(SS1, render_surface1->draw_transform()); 1309 EXPECT_TRANSFORMATION_MATRIX_EQ(SS1 * B * A, child_of_rs1->draw_transform()); 1310 EXPECT_TRANSFORMATION_MATRIX_EQ(SS1 * B * A * B * A, 1311 grand_child_of_rs1->draw_transform()); 1312 1313 EXPECT_TRANSFORMATION_MATRIX_EQ(SS2, render_surface2->draw_transform()); 1314 EXPECT_TRANSFORMATION_MATRIX_EQ(SS2 * B * A, child_of_rs2->draw_transform()); 1315 EXPECT_TRANSFORMATION_MATRIX_EQ(SS2 * B * A * B * A, 1316 grand_child_of_rs2->draw_transform()); 1317 1318 // Verify layer screen-space transforms 1319 // 1320 EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->screen_space_transform()); 1321 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, 1322 child_of_root->screen_space_transform()); 1323 EXPECT_TRANSFORMATION_MATRIX_EQ( 1324 A * B * A * B * A, grand_child_of_root->screen_space_transform()); 1325 1326 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, 1327 render_surface1->screen_space_transform()); 1328 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, 1329 child_of_rs1->screen_space_transform()); 1330 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A, 1331 grand_child_of_rs1->screen_space_transform()); 1332 1333 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, 1334 render_surface2->screen_space_transform()); 1335 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A, 1336 child_of_rs2->screen_space_transform()); 1337 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A * B * A, 1338 grand_child_of_rs2->screen_space_transform()); 1339 1340 // Verify render surface transforms. 1341 // 1342 // Draw transform of render surface 1 is described with respect to root. 1343 EXPECT_TRANSFORMATION_MATRIX_EQ( 1344 A * B * A * S1, render_surface1->render_surface()->draw_transform()); 1345 EXPECT_TRANSFORMATION_MATRIX_EQ( 1346 A * B * R * S1, 1347 render_surface1->render_surface()->replica_draw_transform()); 1348 EXPECT_TRANSFORMATION_MATRIX_EQ( 1349 A * B * A * S1, 1350 render_surface1->render_surface()->screen_space_transform()); 1351 EXPECT_TRANSFORMATION_MATRIX_EQ( 1352 A * B * R * S1, 1353 render_surface1->render_surface()->replica_screen_space_transform()); 1354 // Draw transform of render surface 2 is described with respect to render 1355 // surface 1. 1356 EXPECT_TRANSFORMATION_MATRIX_EQ( 1357 SS1 * B * A * S2, render_surface2->render_surface()->draw_transform()); 1358 EXPECT_TRANSFORMATION_MATRIX_EQ( 1359 SS1 * B * R * S2, 1360 render_surface2->render_surface()->replica_draw_transform()); 1361 EXPECT_TRANSFORMATION_MATRIX_EQ( 1362 A * B * A * B * A * S2, 1363 render_surface2->render_surface()->screen_space_transform()); 1364 EXPECT_TRANSFORMATION_MATRIX_EQ( 1365 A * B * A * B * R * S2, 1366 render_surface2->render_surface()->replica_screen_space_transform()); 1367 1368 // Sanity check. If these fail there is probably a bug in the test itself. It 1369 // is expected that we correctly set up transforms so that the y-component of 1370 // the screen-space transform encodes the "depth" of the layer in the tree. 1371 EXPECT_FLOAT_EQ(1.0, 1372 parent->screen_space_transform().matrix().getDouble(1, 3)); 1373 EXPECT_FLOAT_EQ( 1374 2.0, child_of_root->screen_space_transform().matrix().getDouble(1, 3)); 1375 EXPECT_FLOAT_EQ( 1376 3.0, 1377 grand_child_of_root->screen_space_transform().matrix().getDouble(1, 3)); 1378 1379 EXPECT_FLOAT_EQ( 1380 2.0, render_surface1->screen_space_transform().matrix().getDouble(1, 3)); 1381 EXPECT_FLOAT_EQ( 1382 3.0, child_of_rs1->screen_space_transform().matrix().getDouble(1, 3)); 1383 EXPECT_FLOAT_EQ( 1384 4.0, 1385 grand_child_of_rs1->screen_space_transform().matrix().getDouble(1, 3)); 1386 1387 EXPECT_FLOAT_EQ( 1388 3.0, render_surface2->screen_space_transform().matrix().getDouble(1, 3)); 1389 EXPECT_FLOAT_EQ( 1390 4.0, child_of_rs2->screen_space_transform().matrix().getDouble(1, 3)); 1391 EXPECT_FLOAT_EQ( 1392 5.0, 1393 grand_child_of_rs2->screen_space_transform().matrix().getDouble(1, 3)); 1394 } 1395 1396 TEST_F(LayerTreeHostCommonTest, TransformsForFlatteningLayer) { 1397 // For layers that flatten their subtree, there should be an orthographic 1398 // projection (for x and y values) in the middle of the transform sequence. 1399 // Note that the way the code is currently implemented, it is not expected to 1400 // use a canonical orthographic projection. 1401 1402 scoped_refptr<Layer> root = Layer::Create(); 1403 scoped_refptr<Layer> child = Layer::Create(); 1404 scoped_refptr<LayerWithForcedDrawsContent> grand_child = 1405 make_scoped_refptr(new LayerWithForcedDrawsContent()); 1406 1407 gfx::Transform rotation_about_y_axis; 1408 rotation_about_y_axis.RotateAboutYAxis(30.0); 1409 1410 const gfx::Transform identity_matrix; 1411 SetLayerPropertiesForTesting(root.get(), 1412 identity_matrix, 1413 identity_matrix, 1414 gfx::PointF(), 1415 gfx::PointF(), 1416 gfx::Size(100, 100), 1417 false); 1418 SetLayerPropertiesForTesting(child.get(), 1419 rotation_about_y_axis, 1420 identity_matrix, 1421 gfx::PointF(), 1422 gfx::PointF(), 1423 gfx::Size(10, 10), 1424 false); 1425 SetLayerPropertiesForTesting(grand_child.get(), 1426 rotation_about_y_axis, 1427 identity_matrix, 1428 gfx::PointF(), 1429 gfx::PointF(), 1430 gfx::Size(10, 10), 1431 false); 1432 1433 root->AddChild(child); 1434 child->AddChild(grand_child); 1435 child->SetForceRenderSurface(true); 1436 1437 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 1438 host->SetRootLayer(root); 1439 1440 // No layers in this test should preserve 3d. 1441 ASSERT_FALSE(root->preserves_3d()); 1442 ASSERT_FALSE(child->preserves_3d()); 1443 ASSERT_FALSE(grand_child->preserves_3d()); 1444 1445 gfx::Transform expected_child_draw_transform = rotation_about_y_axis; 1446 gfx::Transform expected_child_screen_space_transform = rotation_about_y_axis; 1447 gfx::Transform expected_grand_child_draw_transform = 1448 rotation_about_y_axis; // draws onto child's render surface 1449 gfx::Transform flattened_rotation_about_y = rotation_about_y_axis; 1450 flattened_rotation_about_y.FlattenTo2d(); 1451 gfx::Transform expected_grand_child_screen_space_transform = 1452 flattened_rotation_about_y * rotation_about_y_axis; 1453 1454 ExecuteCalculateDrawProperties(root.get()); 1455 1456 // The child's draw transform should have been taken by its surface. 1457 ASSERT_TRUE(child->render_surface()); 1458 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_draw_transform, 1459 child->render_surface()->draw_transform()); 1460 EXPECT_TRANSFORMATION_MATRIX_EQ( 1461 expected_child_screen_space_transform, 1462 child->render_surface()->screen_space_transform()); 1463 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform()); 1464 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_screen_space_transform, 1465 child->screen_space_transform()); 1466 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_draw_transform, 1467 grand_child->draw_transform()); 1468 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform, 1469 grand_child->screen_space_transform()); 1470 } 1471 1472 TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { 1473 // A layer that is empty in one axis, but not the other, was accidentally 1474 // skipping a necessary translation. Without that translation, the coordinate 1475 // space of the layer's draw transform is incorrect. 1476 // 1477 // Normally this isn't a problem, because the layer wouldn't be drawn anyway, 1478 // but if that layer becomes a render surface, then its draw transform is 1479 // implicitly inherited by the rest of the subtree, which then is positioned 1480 // incorrectly as a result. 1481 1482 scoped_refptr<Layer> root = Layer::Create(); 1483 scoped_refptr<Layer> child = Layer::Create(); 1484 scoped_refptr<LayerWithForcedDrawsContent> grand_child = 1485 make_scoped_refptr(new LayerWithForcedDrawsContent()); 1486 1487 // The child height is zero, but has non-zero width that should be accounted 1488 // for while computing draw transforms. 1489 const gfx::Transform identity_matrix; 1490 SetLayerPropertiesForTesting(root.get(), 1491 identity_matrix, 1492 identity_matrix, 1493 gfx::PointF(), 1494 gfx::PointF(), 1495 gfx::Size(100, 100), 1496 false); 1497 SetLayerPropertiesForTesting(child.get(), 1498 identity_matrix, 1499 identity_matrix, 1500 gfx::PointF(), 1501 gfx::PointF(), 1502 gfx::Size(10, 0), 1503 false); 1504 SetLayerPropertiesForTesting(grand_child.get(), 1505 identity_matrix, 1506 identity_matrix, 1507 gfx::PointF(), 1508 gfx::PointF(), 1509 gfx::Size(10, 10), 1510 false); 1511 1512 root->AddChild(child); 1513 child->AddChild(grand_child); 1514 child->SetForceRenderSurface(true); 1515 1516 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 1517 host->SetRootLayer(root); 1518 1519 ExecuteCalculateDrawProperties(root.get()); 1520 1521 ASSERT_TRUE(child->render_surface()); 1522 // This is the real test, the rest are sanity checks. 1523 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, 1524 child->render_surface()->draw_transform()); 1525 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform()); 1526 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, 1527 grand_child->draw_transform()); 1528 } 1529 1530 TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { 1531 // Transformations applied at the root of the tree should be forwarded 1532 // to child layers instead of applied to the root RenderSurface. 1533 const gfx::Transform identity_matrix; 1534 scoped_refptr<Layer> root = Layer::Create(); 1535 scoped_refptr<Layer> child = Layer::Create(); 1536 child->SetScrollable(true); 1537 root->AddChild(child); 1538 1539 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 1540 host->SetRootLayer(root); 1541 1542 SetLayerPropertiesForTesting(root.get(), 1543 identity_matrix, 1544 identity_matrix, 1545 gfx::PointF(), 1546 gfx::PointF(), 1547 gfx::Size(20, 20), 1548 false); 1549 SetLayerPropertiesForTesting(child.get(), 1550 identity_matrix, 1551 identity_matrix, 1552 gfx::PointF(), 1553 gfx::PointF(), 1554 gfx::Size(20, 20), 1555 false); 1556 1557 gfx::Transform translate; 1558 translate.Translate(50, 50); 1559 { 1560 RenderSurfaceLayerList render_surface_layer_list; 1561 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 1562 root.get(), root->bounds(), translate, &render_surface_layer_list); 1563 inputs.can_adjust_raster_scales = true; 1564 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 1565 EXPECT_EQ(translate, root->draw_properties().target_space_transform); 1566 EXPECT_EQ(translate, child->draw_properties().target_space_transform); 1567 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); 1568 } 1569 1570 gfx::Transform scale; 1571 scale.Scale(2, 2); 1572 { 1573 RenderSurfaceLayerList render_surface_layer_list; 1574 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 1575 root.get(), root->bounds(), scale, &render_surface_layer_list); 1576 inputs.can_adjust_raster_scales = true; 1577 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 1578 EXPECT_EQ(scale, root->draw_properties().target_space_transform); 1579 EXPECT_EQ(scale, child->draw_properties().target_space_transform); 1580 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); 1581 } 1582 1583 gfx::Transform rotate; 1584 rotate.Rotate(2); 1585 { 1586 RenderSurfaceLayerList render_surface_layer_list; 1587 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 1588 root.get(), root->bounds(), rotate, &render_surface_layer_list); 1589 inputs.can_adjust_raster_scales = true; 1590 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 1591 EXPECT_EQ(rotate, root->draw_properties().target_space_transform); 1592 EXPECT_EQ(rotate, child->draw_properties().target_space_transform); 1593 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); 1594 } 1595 1596 gfx::Transform composite; 1597 composite.ConcatTransform(translate); 1598 composite.ConcatTransform(scale); 1599 composite.ConcatTransform(rotate); 1600 { 1601 RenderSurfaceLayerList render_surface_layer_list; 1602 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 1603 root.get(), root->bounds(), composite, &render_surface_layer_list); 1604 inputs.can_adjust_raster_scales = true; 1605 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 1606 EXPECT_EQ(composite, root->draw_properties().target_space_transform); 1607 EXPECT_EQ(composite, child->draw_properties().target_space_transform); 1608 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); 1609 } 1610 1611 // Verify it composes correctly with device scale. 1612 float device_scale_factor = 1.5f; 1613 1614 { 1615 RenderSurfaceLayerList render_surface_layer_list; 1616 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 1617 root.get(), root->bounds(), translate, &render_surface_layer_list); 1618 inputs.device_scale_factor = device_scale_factor; 1619 inputs.can_adjust_raster_scales = true; 1620 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 1621 gfx::Transform device_scaled_translate = translate; 1622 device_scaled_translate.Scale(device_scale_factor, device_scale_factor); 1623 EXPECT_EQ(device_scaled_translate, 1624 root->draw_properties().target_space_transform); 1625 EXPECT_EQ(device_scaled_translate, 1626 child->draw_properties().target_space_transform); 1627 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); 1628 } 1629 1630 // Verify it composes correctly with page scale. 1631 float page_scale_factor = 2.f; 1632 1633 { 1634 RenderSurfaceLayerList render_surface_layer_list; 1635 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 1636 root.get(), root->bounds(), translate, &render_surface_layer_list); 1637 inputs.page_scale_factor = page_scale_factor; 1638 inputs.page_scale_application_layer = root.get(); 1639 inputs.can_adjust_raster_scales = true; 1640 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 1641 gfx::Transform page_scaled_translate = translate; 1642 page_scaled_translate.Scale(page_scale_factor, page_scale_factor); 1643 EXPECT_EQ(translate, root->draw_properties().target_space_transform); 1644 EXPECT_EQ(page_scaled_translate, 1645 child->draw_properties().target_space_transform); 1646 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); 1647 } 1648 1649 // Verify that it composes correctly with transforms directly on root layer. 1650 root->SetTransform(composite); 1651 root->SetSublayerTransform(composite); 1652 1653 { 1654 RenderSurfaceLayerList render_surface_layer_list; 1655 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 1656 root.get(), root->bounds(), composite, &render_surface_layer_list); 1657 inputs.can_adjust_raster_scales = true; 1658 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 1659 gfx::Transform compositeSquared = composite; 1660 compositeSquared.ConcatTransform(composite); 1661 gfx::Transform compositeCubed = compositeSquared; 1662 compositeCubed.ConcatTransform(composite); 1663 EXPECT_EQ(compositeSquared, root->draw_properties().target_space_transform); 1664 EXPECT_EQ(compositeCubed, child->draw_properties().target_space_transform); 1665 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); 1666 } 1667 } 1668 1669 TEST_F(LayerTreeHostCommonTest, 1670 RenderSurfaceListForRenderSurfaceWithClippedLayer) { 1671 scoped_refptr<Layer> parent = Layer::Create(); 1672 scoped_refptr<Layer> render_surface1 = Layer::Create(); 1673 scoped_refptr<LayerWithForcedDrawsContent> child = 1674 make_scoped_refptr(new LayerWithForcedDrawsContent()); 1675 1676 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 1677 host->SetRootLayer(parent); 1678 1679 1680 const gfx::Transform identity_matrix; 1681 SetLayerPropertiesForTesting(parent.get(), 1682 identity_matrix, 1683 identity_matrix, 1684 gfx::PointF(), 1685 gfx::PointF(), 1686 gfx::Size(10, 10), 1687 false); 1688 SetLayerPropertiesForTesting(render_surface1.get(), 1689 identity_matrix, 1690 identity_matrix, 1691 gfx::PointF(), 1692 gfx::PointF(), 1693 gfx::Size(10, 10), 1694 false); 1695 SetLayerPropertiesForTesting(child.get(), 1696 identity_matrix, 1697 identity_matrix, 1698 gfx::PointF(), 1699 gfx::PointF(30.f, 30.f), 1700 gfx::Size(10, 10), 1701 false); 1702 1703 parent->AddChild(render_surface1); 1704 parent->SetMasksToBounds(true); 1705 render_surface1->AddChild(child); 1706 render_surface1->SetForceRenderSurface(true); 1707 1708 RenderSurfaceLayerList render_surface_layer_list; 1709 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 1710 parent.get(), 1711 parent->bounds(), 1712 gfx::Transform(), 1713 &render_surface_layer_list); 1714 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 1715 1716 // The child layer's content is entirely outside the parent's clip rect, so 1717 // the intermediate render surface should not be listed here, even if it was 1718 // forced to be created. Render surfaces without children or visible content 1719 // are unexpected at draw time (e.g. we might try to create a content texture 1720 // of size 0). 1721 ASSERT_TRUE(parent->render_surface()); 1722 ASSERT_FALSE(render_surface1->render_surface()); 1723 EXPECT_EQ(1U, render_surface_layer_list.size()); 1724 } 1725 1726 TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) { 1727 scoped_refptr<Layer> parent = Layer::Create(); 1728 scoped_refptr<Layer> render_surface1 = Layer::Create(); 1729 scoped_refptr<LayerWithForcedDrawsContent> child = 1730 make_scoped_refptr(new LayerWithForcedDrawsContent()); 1731 1732 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 1733 host->SetRootLayer(parent); 1734 1735 const gfx::Transform identity_matrix; 1736 SetLayerPropertiesForTesting(render_surface1.get(), 1737 identity_matrix, 1738 identity_matrix, 1739 gfx::PointF(), 1740 gfx::PointF(), 1741 gfx::Size(10, 10), 1742 false); 1743 SetLayerPropertiesForTesting(child.get(), 1744 identity_matrix, 1745 identity_matrix, 1746 gfx::PointF(), 1747 gfx::PointF(), 1748 gfx::Size(10, 10), 1749 false); 1750 1751 parent->AddChild(render_surface1); 1752 render_surface1->AddChild(child); 1753 render_surface1->SetForceRenderSurface(true); 1754 render_surface1->SetOpacity(0.f); 1755 1756 RenderSurfaceLayerList render_surface_layer_list; 1757 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 1758 parent.get(), parent->bounds(), &render_surface_layer_list); 1759 inputs.can_adjust_raster_scales = true; 1760 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 1761 1762 // Since the layer is transparent, render_surface1->render_surface() should 1763 // not have gotten added anywhere. Also, the drawable content rect should not 1764 // have been extended by the children. 1765 ASSERT_TRUE(parent->render_surface()); 1766 EXPECT_EQ(0U, parent->render_surface()->layer_list().size()); 1767 EXPECT_EQ(1U, render_surface_layer_list.size()); 1768 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id()); 1769 EXPECT_EQ(gfx::Rect(), parent->drawable_content_rect()); 1770 } 1771 1772 TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) { 1773 scoped_refptr<Layer> parent = Layer::Create(); 1774 scoped_refptr<Layer> render_surface1 = Layer::Create(); 1775 scoped_refptr<LayerWithForcedDrawsContent> child = 1776 make_scoped_refptr(new LayerWithForcedDrawsContent()); 1777 render_surface1->SetForceRenderSurface(true); 1778 1779 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 1780 host->SetRootLayer(parent); 1781 1782 const gfx::Transform identity_matrix; 1783 SetLayerPropertiesForTesting(parent.get(), 1784 identity_matrix, 1785 identity_matrix, 1786 gfx::PointF(), 1787 gfx::PointF(), 1788 gfx::Size(10, 10), 1789 false); 1790 SetLayerPropertiesForTesting(render_surface1.get(), 1791 identity_matrix, 1792 identity_matrix, 1793 gfx::PointF(), 1794 gfx::PointF(), 1795 gfx::Size(10, 10), 1796 false); 1797 SetLayerPropertiesForTesting(child.get(), 1798 identity_matrix, 1799 identity_matrix, 1800 gfx::PointF(), 1801 gfx::PointF(), 1802 gfx::Size(10, 10), 1803 false); 1804 1805 parent->AddChild(render_surface1); 1806 render_surface1->AddChild(child); 1807 1808 // Sanity check before the actual test 1809 EXPECT_FALSE(parent->render_surface()); 1810 EXPECT_FALSE(render_surface1->render_surface()); 1811 1812 { 1813 RenderSurfaceLayerList render_surface_layer_list; 1814 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 1815 parent.get(), parent->bounds(), &render_surface_layer_list); 1816 inputs.can_adjust_raster_scales = true; 1817 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 1818 1819 // The root layer always creates a render surface 1820 EXPECT_TRUE(parent->render_surface()); 1821 EXPECT_TRUE(render_surface1->render_surface()); 1822 EXPECT_EQ(2U, render_surface_layer_list.size()); 1823 } 1824 1825 { 1826 RenderSurfaceLayerList render_surface_layer_list; 1827 render_surface1->SetForceRenderSurface(false); 1828 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 1829 parent.get(), parent->bounds(), &render_surface_layer_list); 1830 inputs.can_adjust_raster_scales = true; 1831 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 1832 EXPECT_TRUE(parent->render_surface()); 1833 EXPECT_FALSE(render_surface1->render_surface()); 1834 EXPECT_EQ(1U, render_surface_layer_list.size()); 1835 } 1836 } 1837 1838 TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { 1839 // The entire subtree of layers that are outside the clip rect should be 1840 // culled away, and should not affect the render_surface_layer_list. 1841 // 1842 // The test tree is set up as follows: 1843 // - all layers except the leaf_nodes are forced to be a new render surface 1844 // that have something to draw. 1845 // - parent is a large container layer. 1846 // - child has masksToBounds=true to cause clipping. 1847 // - grand_child is positioned outside of the child's bounds 1848 // - great_grand_child is also kept outside child's bounds. 1849 // 1850 // In this configuration, grand_child and great_grand_child are completely 1851 // outside the clip rect, and they should never get scheduled on the list of 1852 // render surfaces. 1853 // 1854 1855 const gfx::Transform identity_matrix; 1856 scoped_refptr<Layer> parent = Layer::Create(); 1857 scoped_refptr<Layer> child = Layer::Create(); 1858 scoped_refptr<Layer> grand_child = Layer::Create(); 1859 scoped_refptr<Layer> great_grand_child = Layer::Create(); 1860 scoped_refptr<LayerWithForcedDrawsContent> leaf_node1 = 1861 make_scoped_refptr(new LayerWithForcedDrawsContent()); 1862 scoped_refptr<LayerWithForcedDrawsContent> leaf_node2 = 1863 make_scoped_refptr(new LayerWithForcedDrawsContent()); 1864 parent->AddChild(child); 1865 child->AddChild(grand_child); 1866 grand_child->AddChild(great_grand_child); 1867 1868 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 1869 host->SetRootLayer(parent); 1870 1871 // leaf_node1 ensures that parent and child are kept on the 1872 // render_surface_layer_list, even though grand_child and great_grand_child 1873 // should be clipped. 1874 child->AddChild(leaf_node1); 1875 great_grand_child->AddChild(leaf_node2); 1876 1877 SetLayerPropertiesForTesting(parent.get(), 1878 identity_matrix, 1879 identity_matrix, 1880 gfx::PointF(), 1881 gfx::PointF(), 1882 gfx::Size(500, 500), 1883 false); 1884 SetLayerPropertiesForTesting(child.get(), 1885 identity_matrix, 1886 identity_matrix, 1887 gfx::PointF(), 1888 gfx::PointF(), 1889 gfx::Size(20, 20), 1890 false); 1891 SetLayerPropertiesForTesting(grand_child.get(), 1892 identity_matrix, 1893 identity_matrix, 1894 gfx::PointF(), 1895 gfx::PointF(45.f, 45.f), 1896 gfx::Size(10, 10), 1897 false); 1898 SetLayerPropertiesForTesting(great_grand_child.get(), 1899 identity_matrix, 1900 identity_matrix, 1901 gfx::PointF(), 1902 gfx::PointF(), 1903 gfx::Size(10, 10), 1904 false); 1905 SetLayerPropertiesForTesting(leaf_node1.get(), 1906 identity_matrix, 1907 identity_matrix, 1908 gfx::PointF(), 1909 gfx::PointF(), 1910 gfx::Size(500, 500), 1911 false); 1912 SetLayerPropertiesForTesting(leaf_node2.get(), 1913 identity_matrix, 1914 identity_matrix, 1915 gfx::PointF(), 1916 gfx::PointF(), 1917 gfx::Size(20, 20), 1918 false); 1919 1920 child->SetMasksToBounds(true); 1921 child->SetOpacity(0.4f); 1922 child->SetForceRenderSurface(true); 1923 grand_child->SetOpacity(0.5f); 1924 great_grand_child->SetOpacity(0.4f); 1925 1926 RenderSurfaceLayerList render_surface_layer_list; 1927 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 1928 parent.get(), parent->bounds(), &render_surface_layer_list); 1929 inputs.can_adjust_raster_scales = true; 1930 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 1931 1932 ASSERT_EQ(2U, render_surface_layer_list.size()); 1933 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id()); 1934 EXPECT_EQ(child->id(), render_surface_layer_list.at(1)->id()); 1935 } 1936 1937 TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { 1938 // When a render surface has a clip rect, it is used to clip the content rect 1939 // of the surface. When the render surface is animating its transforms, then 1940 // the content rect's position in the clip rect is not defined on the main 1941 // thread, and its content rect should not be clipped. 1942 1943 // The test tree is set up as follows: 1944 // - parent is a container layer that masksToBounds=true to cause clipping. 1945 // - child is a render surface, which has a clip rect set to the bounds of 1946 // the parent. 1947 // - grand_child is a render surface, and the only visible content in child. 1948 // It is positioned outside of the clip rect from parent. 1949 1950 // In this configuration, grand_child should be outside the clipped 1951 // content rect of the child, making grand_child not appear in the 1952 // render_surface_layer_list. However, when we place an animation on the 1953 // child, this clipping should be avoided and we should keep the grand_child 1954 // in the render_surface_layer_list. 1955 1956 const gfx::Transform identity_matrix; 1957 scoped_refptr<Layer> parent = Layer::Create(); 1958 scoped_refptr<Layer> child = Layer::Create(); 1959 scoped_refptr<Layer> grand_child = Layer::Create(); 1960 scoped_refptr<LayerWithForcedDrawsContent> leaf_node = 1961 make_scoped_refptr(new LayerWithForcedDrawsContent()); 1962 parent->AddChild(child); 1963 child->AddChild(grand_child); 1964 grand_child->AddChild(leaf_node); 1965 1966 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 1967 host->SetRootLayer(parent); 1968 1969 SetLayerPropertiesForTesting(parent.get(), 1970 identity_matrix, 1971 identity_matrix, 1972 gfx::PointF(), 1973 gfx::PointF(), 1974 gfx::Size(100, 100), 1975 false); 1976 SetLayerPropertiesForTesting(child.get(), 1977 identity_matrix, 1978 identity_matrix, 1979 gfx::PointF(), 1980 gfx::PointF(), 1981 gfx::Size(20, 20), 1982 false); 1983 SetLayerPropertiesForTesting(grand_child.get(), 1984 identity_matrix, 1985 identity_matrix, 1986 gfx::PointF(), 1987 gfx::PointF(200.f, 200.f), 1988 gfx::Size(10, 10), 1989 false); 1990 SetLayerPropertiesForTesting(leaf_node.get(), 1991 identity_matrix, 1992 identity_matrix, 1993 gfx::PointF(), 1994 gfx::PointF(), 1995 gfx::Size(10, 10), 1996 false); 1997 1998 parent->SetMasksToBounds(true); 1999 child->SetOpacity(0.4f); 2000 child->SetForceRenderSurface(true); 2001 grand_child->SetOpacity(0.4f); 2002 grand_child->SetForceRenderSurface(true); 2003 2004 { 2005 RenderSurfaceLayerList render_surface_layer_list; 2006 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 2007 parent.get(), parent->bounds(), &render_surface_layer_list); 2008 inputs.can_adjust_raster_scales = true; 2009 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 2010 2011 // Without an animation, we should cull child and grand_child from the 2012 // render_surface_layer_list. 2013 ASSERT_EQ(1U, render_surface_layer_list.size()); 2014 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id()); 2015 } 2016 2017 // Now put an animating transform on child. 2018 AddAnimatedTransformToController( 2019 child->layer_animation_controller(), 10.0, 30, 0); 2020 2021 { 2022 RenderSurfaceLayerList render_surface_layer_list; 2023 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 2024 parent.get(), parent->bounds(), &render_surface_layer_list); 2025 inputs.can_adjust_raster_scales = true; 2026 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 2027 2028 // With an animating transform, we should keep child and grand_child in the 2029 // render_surface_layer_list. 2030 ASSERT_EQ(3U, render_surface_layer_list.size()); 2031 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id()); 2032 EXPECT_EQ(child->id(), render_surface_layer_list.at(1)->id()); 2033 EXPECT_EQ(grand_child->id(), render_surface_layer_list.at(2)->id()); 2034 } 2035 } 2036 2037 TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectly) { 2038 // Layer's IsClipped() property is set to true when: 2039 // - the layer clips its subtree, e.g. masks to bounds, 2040 // - the layer is clipped by an ancestor that contributes to the same 2041 // render target, 2042 // - a surface is clipped by an ancestor that contributes to the same 2043 // render target. 2044 // 2045 // In particular, for a layer that owns a render surface: 2046 // - the render surface inherits any clip from ancestors, and does NOT 2047 // pass that clipped status to the layer itself. 2048 // - but if the layer itself masks to bounds, it is considered clipped 2049 // and propagates the clip to the subtree. 2050 2051 const gfx::Transform identity_matrix; 2052 scoped_refptr<Layer> root = Layer::Create(); 2053 scoped_refptr<Layer> parent = Layer::Create(); 2054 scoped_refptr<Layer> child1 = Layer::Create(); 2055 scoped_refptr<Layer> child2 = Layer::Create(); 2056 scoped_refptr<Layer> grand_child = Layer::Create(); 2057 scoped_refptr<LayerWithForcedDrawsContent> leaf_node1 = 2058 make_scoped_refptr(new LayerWithForcedDrawsContent()); 2059 scoped_refptr<LayerWithForcedDrawsContent> leaf_node2 = 2060 make_scoped_refptr(new LayerWithForcedDrawsContent()); 2061 root->AddChild(parent); 2062 parent->AddChild(child1); 2063 parent->AddChild(child2); 2064 child1->AddChild(grand_child); 2065 child2->AddChild(leaf_node2); 2066 grand_child->AddChild(leaf_node1); 2067 2068 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 2069 host->SetRootLayer(root); 2070 2071 child2->SetForceRenderSurface(true); 2072 2073 SetLayerPropertiesForTesting(root.get(), 2074 identity_matrix, 2075 identity_matrix, 2076 gfx::PointF(), 2077 gfx::PointF(), 2078 gfx::Size(100, 100), 2079 false); 2080 SetLayerPropertiesForTesting(parent.get(), 2081 identity_matrix, 2082 identity_matrix, 2083 gfx::PointF(), 2084 gfx::PointF(), 2085 gfx::Size(100, 100), 2086 false); 2087 SetLayerPropertiesForTesting(child1.get(), 2088 identity_matrix, 2089 identity_matrix, 2090 gfx::PointF(), 2091 gfx::PointF(), 2092 gfx::Size(100, 100), 2093 false); 2094 SetLayerPropertiesForTesting(child2.get(), 2095 identity_matrix, 2096 identity_matrix, 2097 gfx::PointF(), 2098 gfx::PointF(), 2099 gfx::Size(100, 100), 2100 false); 2101 SetLayerPropertiesForTesting(grand_child.get(), 2102 identity_matrix, 2103 identity_matrix, 2104 gfx::PointF(), 2105 gfx::PointF(), 2106 gfx::Size(100, 100), 2107 false); 2108 SetLayerPropertiesForTesting(leaf_node1.get(), 2109 identity_matrix, 2110 identity_matrix, 2111 gfx::PointF(), 2112 gfx::PointF(), 2113 gfx::Size(100, 100), 2114 false); 2115 SetLayerPropertiesForTesting(leaf_node2.get(), 2116 identity_matrix, 2117 identity_matrix, 2118 gfx::PointF(), 2119 gfx::PointF(), 2120 gfx::Size(100, 100), 2121 false); 2122 2123 // Case 1: nothing is clipped except the root render surface. 2124 { 2125 RenderSurfaceLayerList render_surface_layer_list; 2126 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 2127 root.get(), parent->bounds(), &render_surface_layer_list); 2128 inputs.can_adjust_raster_scales = true; 2129 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 2130 2131 ASSERT_TRUE(root->render_surface()); 2132 ASSERT_TRUE(child2->render_surface()); 2133 2134 EXPECT_FALSE(root->is_clipped()); 2135 EXPECT_TRUE(root->render_surface()->is_clipped()); 2136 EXPECT_FALSE(parent->is_clipped()); 2137 EXPECT_FALSE(child1->is_clipped()); 2138 EXPECT_FALSE(child2->is_clipped()); 2139 EXPECT_FALSE(child2->render_surface()->is_clipped()); 2140 EXPECT_FALSE(grand_child->is_clipped()); 2141 EXPECT_FALSE(leaf_node1->is_clipped()); 2142 EXPECT_FALSE(leaf_node2->is_clipped()); 2143 } 2144 2145 // Case 2: parent masksToBounds, so the parent, child1, and child2's 2146 // surface are clipped. But layers that contribute to child2's surface are 2147 // not clipped explicitly because child2's surface already accounts for 2148 // that clip. 2149 { 2150 RenderSurfaceLayerList render_surface_layer_list; 2151 parent->SetMasksToBounds(true); 2152 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 2153 root.get(), parent->bounds(), &render_surface_layer_list); 2154 inputs.can_adjust_raster_scales = true; 2155 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 2156 2157 ASSERT_TRUE(root->render_surface()); 2158 ASSERT_TRUE(child2->render_surface()); 2159 2160 EXPECT_FALSE(root->is_clipped()); 2161 EXPECT_TRUE(root->render_surface()->is_clipped()); 2162 EXPECT_TRUE(parent->is_clipped()); 2163 EXPECT_TRUE(child1->is_clipped()); 2164 EXPECT_FALSE(child2->is_clipped()); 2165 EXPECT_TRUE(child2->render_surface()->is_clipped()); 2166 EXPECT_TRUE(grand_child->is_clipped()); 2167 EXPECT_TRUE(leaf_node1->is_clipped()); 2168 EXPECT_FALSE(leaf_node2->is_clipped()); 2169 } 2170 2171 // Case 3: child2 masksToBounds. The layer and subtree are clipped, and 2172 // child2's render surface is not clipped. 2173 { 2174 RenderSurfaceLayerList render_surface_layer_list; 2175 parent->SetMasksToBounds(false); 2176 child2->SetMasksToBounds(true); 2177 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 2178 root.get(), parent->bounds(), &render_surface_layer_list); 2179 inputs.can_adjust_raster_scales = true; 2180 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 2181 2182 ASSERT_TRUE(root->render_surface()); 2183 ASSERT_TRUE(child2->render_surface()); 2184 2185 EXPECT_FALSE(root->is_clipped()); 2186 EXPECT_TRUE(root->render_surface()->is_clipped()); 2187 EXPECT_FALSE(parent->is_clipped()); 2188 EXPECT_FALSE(child1->is_clipped()); 2189 EXPECT_TRUE(child2->is_clipped()); 2190 EXPECT_FALSE(child2->render_surface()->is_clipped()); 2191 EXPECT_FALSE(grand_child->is_clipped()); 2192 EXPECT_FALSE(leaf_node1->is_clipped()); 2193 EXPECT_TRUE(leaf_node2->is_clipped()); 2194 } 2195 } 2196 2197 TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { 2198 // Verify that layers get the appropriate DrawableContentRect when their 2199 // parent masksToBounds is true. 2200 // 2201 // grand_child1 - completely inside the region; DrawableContentRect should 2202 // be the layer rect expressed in target space. 2203 // grand_child2 - partially clipped but NOT masksToBounds; the clip rect 2204 // will be the intersection of layer bounds and the mask region. 2205 // grand_child3 - partially clipped and masksToBounds; the 2206 // DrawableContentRect will still be the intersection of layer bounds and 2207 // the mask region. 2208 // grand_child4 - outside parent's clip rect; the DrawableContentRect should 2209 // be empty. 2210 // 2211 2212 const gfx::Transform identity_matrix; 2213 scoped_refptr<Layer> parent = Layer::Create(); 2214 scoped_refptr<Layer> child = Layer::Create(); 2215 scoped_refptr<Layer> grand_child1 = Layer::Create(); 2216 scoped_refptr<Layer> grand_child2 = Layer::Create(); 2217 scoped_refptr<Layer> grand_child3 = Layer::Create(); 2218 scoped_refptr<Layer> grand_child4 = Layer::Create(); 2219 2220 parent->AddChild(child); 2221 child->AddChild(grand_child1); 2222 child->AddChild(grand_child2); 2223 child->AddChild(grand_child3); 2224 child->AddChild(grand_child4); 2225 2226 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 2227 host->SetRootLayer(parent); 2228 2229 SetLayerPropertiesForTesting(parent.get(), 2230 identity_matrix, 2231 identity_matrix, 2232 gfx::PointF(), 2233 gfx::PointF(), 2234 gfx::Size(500, 500), 2235 false); 2236 SetLayerPropertiesForTesting(child.get(), 2237 identity_matrix, 2238 identity_matrix, 2239 gfx::PointF(), 2240 gfx::PointF(), 2241 gfx::Size(20, 20), 2242 false); 2243 SetLayerPropertiesForTesting(grand_child1.get(), 2244 identity_matrix, 2245 identity_matrix, 2246 gfx::PointF(), 2247 gfx::PointF(5.f, 5.f), 2248 gfx::Size(10, 10), 2249 false); 2250 SetLayerPropertiesForTesting(grand_child2.get(), 2251 identity_matrix, 2252 identity_matrix, 2253 gfx::PointF(), 2254 gfx::PointF(15.f, 15.f), 2255 gfx::Size(10, 10), 2256 false); 2257 SetLayerPropertiesForTesting(grand_child3.get(), 2258 identity_matrix, 2259 identity_matrix, 2260 gfx::PointF(), 2261 gfx::PointF(15.f, 15.f), 2262 gfx::Size(10, 10), 2263 false); 2264 SetLayerPropertiesForTesting(grand_child4.get(), 2265 identity_matrix, 2266 identity_matrix, 2267 gfx::PointF(), 2268 gfx::PointF(45.f, 45.f), 2269 gfx::Size(10, 10), 2270 false); 2271 2272 child->SetMasksToBounds(true); 2273 grand_child3->SetMasksToBounds(true); 2274 2275 // Force everyone to be a render surface. 2276 child->SetOpacity(0.4f); 2277 grand_child1->SetOpacity(0.5f); 2278 grand_child2->SetOpacity(0.5f); 2279 grand_child3->SetOpacity(0.5f); 2280 grand_child4->SetOpacity(0.5f); 2281 2282 RenderSurfaceLayerList render_surface_layer_list; 2283 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 2284 parent.get(), parent->bounds(), &render_surface_layer_list); 2285 inputs.can_adjust_raster_scales = true; 2286 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 2287 2288 EXPECT_RECT_EQ(gfx::Rect(5, 5, 10, 10), 2289 grand_child1->drawable_content_rect()); 2290 EXPECT_RECT_EQ(gfx::Rect(15, 15, 5, 5), 2291 grand_child3->drawable_content_rect()); 2292 EXPECT_RECT_EQ(gfx::Rect(15, 15, 5, 5), 2293 grand_child3->drawable_content_rect()); 2294 EXPECT_TRUE(grand_child4->drawable_content_rect().IsEmpty()); 2295 } 2296 2297 TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { 2298 // Verify that render surfaces (and their layers) get the appropriate 2299 // clip rects when their parent masksToBounds is true. 2300 // 2301 // Layers that own render surfaces (at least for now) do not inherit any 2302 // clipping; instead the surface will enforce the clip for the entire subtree. 2303 // They may still have a clip rect of their own layer bounds, however, if 2304 // masksToBounds was true. 2305 const gfx::Transform identity_matrix; 2306 scoped_refptr<Layer> parent = Layer::Create(); 2307 scoped_refptr<Layer> child = Layer::Create(); 2308 scoped_refptr<Layer> grand_child1 = Layer::Create(); 2309 scoped_refptr<Layer> grand_child2 = Layer::Create(); 2310 scoped_refptr<Layer> grand_child3 = Layer::Create(); 2311 scoped_refptr<Layer> grand_child4 = Layer::Create(); 2312 scoped_refptr<LayerWithForcedDrawsContent> leaf_node1 = 2313 make_scoped_refptr(new LayerWithForcedDrawsContent()); 2314 scoped_refptr<LayerWithForcedDrawsContent> leaf_node2 = 2315 make_scoped_refptr(new LayerWithForcedDrawsContent()); 2316 scoped_refptr<LayerWithForcedDrawsContent> leaf_node3 = 2317 make_scoped_refptr(new LayerWithForcedDrawsContent()); 2318 scoped_refptr<LayerWithForcedDrawsContent> leaf_node4 = 2319 make_scoped_refptr(new LayerWithForcedDrawsContent()); 2320 2321 parent->AddChild(child); 2322 child->AddChild(grand_child1); 2323 child->AddChild(grand_child2); 2324 child->AddChild(grand_child3); 2325 child->AddChild(grand_child4); 2326 2327 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 2328 host->SetRootLayer(parent); 2329 2330 // the leaf nodes ensure that these grand_children become render surfaces for 2331 // this test. 2332 grand_child1->AddChild(leaf_node1); 2333 grand_child2->AddChild(leaf_node2); 2334 grand_child3->AddChild(leaf_node3); 2335 grand_child4->AddChild(leaf_node4); 2336 2337 SetLayerPropertiesForTesting(parent.get(), 2338 identity_matrix, 2339 identity_matrix, 2340 gfx::PointF(), 2341 gfx::PointF(), 2342 gfx::Size(500, 500), 2343 false); 2344 SetLayerPropertiesForTesting(child.get(), 2345 identity_matrix, 2346 identity_matrix, 2347 gfx::PointF(), 2348 gfx::PointF(), 2349 gfx::Size(20, 20), 2350 false); 2351 SetLayerPropertiesForTesting(grand_child1.get(), 2352 identity_matrix, 2353 identity_matrix, 2354 gfx::PointF(), 2355 gfx::PointF(5.f, 5.f), 2356 gfx::Size(10, 10), 2357 false); 2358 SetLayerPropertiesForTesting(grand_child2.get(), 2359 identity_matrix, 2360 identity_matrix, 2361 gfx::PointF(), 2362 gfx::PointF(15.f, 15.f), 2363 gfx::Size(10, 10), 2364 false); 2365 SetLayerPropertiesForTesting(grand_child3.get(), 2366 identity_matrix, 2367 identity_matrix, 2368 gfx::PointF(), 2369 gfx::PointF(15.f, 15.f), 2370 gfx::Size(10, 10), 2371 false); 2372 SetLayerPropertiesForTesting(grand_child4.get(), 2373 identity_matrix, 2374 identity_matrix, 2375 gfx::PointF(), 2376 gfx::PointF(45.f, 45.f), 2377 gfx::Size(10, 10), 2378 false); 2379 SetLayerPropertiesForTesting(leaf_node1.get(), 2380 identity_matrix, 2381 identity_matrix, 2382 gfx::PointF(), 2383 gfx::PointF(), 2384 gfx::Size(10, 10), 2385 false); 2386 SetLayerPropertiesForTesting(leaf_node2.get(), 2387 identity_matrix, 2388 identity_matrix, 2389 gfx::PointF(), 2390 gfx::PointF(), 2391 gfx::Size(10, 10), 2392 false); 2393 SetLayerPropertiesForTesting(leaf_node3.get(), 2394 identity_matrix, 2395 identity_matrix, 2396 gfx::PointF(), 2397 gfx::PointF(), 2398 gfx::Size(10, 10), 2399 false); 2400 SetLayerPropertiesForTesting(leaf_node4.get(), 2401 identity_matrix, 2402 identity_matrix, 2403 gfx::PointF(), 2404 gfx::PointF(), 2405 gfx::Size(10, 10), 2406 false); 2407 2408 child->SetMasksToBounds(true); 2409 grand_child3->SetMasksToBounds(true); 2410 grand_child4->SetMasksToBounds(true); 2411 2412 // Force everyone to be a render surface. 2413 child->SetOpacity(0.4f); 2414 child->SetForceRenderSurface(true); 2415 grand_child1->SetOpacity(0.5f); 2416 grand_child1->SetForceRenderSurface(true); 2417 grand_child2->SetOpacity(0.5f); 2418 grand_child2->SetForceRenderSurface(true); 2419 grand_child3->SetOpacity(0.5f); 2420 grand_child3->SetForceRenderSurface(true); 2421 grand_child4->SetOpacity(0.5f); 2422 grand_child4->SetForceRenderSurface(true); 2423 2424 RenderSurfaceLayerList render_surface_layer_list; 2425 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 2426 parent.get(), parent->bounds(), &render_surface_layer_list); 2427 inputs.can_adjust_raster_scales = true; 2428 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 2429 ASSERT_TRUE(grand_child1->render_surface()); 2430 ASSERT_TRUE(grand_child2->render_surface()); 2431 ASSERT_TRUE(grand_child3->render_surface()); 2432 // Because grand_child4 is entirely clipped, it is expected to not have a 2433 // render surface. 2434 EXPECT_FALSE(grand_child4->render_surface()); 2435 2436 // Surfaces are clipped by their parent, but un-affected by the owning layer's 2437 // masksToBounds. 2438 EXPECT_RECT_EQ(gfx::Rect(0, 0, 20, 20), 2439 grand_child1->render_surface()->clip_rect()); 2440 EXPECT_RECT_EQ(gfx::Rect(0, 0, 20, 20), 2441 grand_child2->render_surface()->clip_rect()); 2442 EXPECT_RECT_EQ(gfx::Rect(0, 0, 20, 20), 2443 grand_child3->render_surface()->clip_rect()); 2444 } 2445 2446 TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { 2447 scoped_refptr<Layer> parent = Layer::Create(); 2448 scoped_refptr<Layer> render_surface1 = Layer::Create(); 2449 scoped_refptr<Layer> render_surface2 = Layer::Create(); 2450 scoped_refptr<Layer> child_of_root = Layer::Create(); 2451 scoped_refptr<Layer> child_of_rs1 = Layer::Create(); 2452 scoped_refptr<Layer> child_of_rs2 = Layer::Create(); 2453 scoped_refptr<Layer> grand_child_of_root = Layer::Create(); 2454 scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs1 = 2455 make_scoped_refptr(new LayerWithForcedDrawsContent()); 2456 scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs2 = 2457 make_scoped_refptr(new LayerWithForcedDrawsContent()); 2458 parent->AddChild(render_surface1); 2459 parent->AddChild(child_of_root); 2460 render_surface1->AddChild(child_of_rs1); 2461 render_surface1->AddChild(render_surface2); 2462 render_surface2->AddChild(child_of_rs2); 2463 child_of_root->AddChild(grand_child_of_root); 2464 child_of_rs1->AddChild(grand_child_of_rs1); 2465 child_of_rs2->AddChild(grand_child_of_rs2); 2466 2467 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 2468 host->SetRootLayer(parent); 2469 2470 // Make our render surfaces. 2471 render_surface1->SetForceRenderSurface(true); 2472 render_surface2->SetForceRenderSurface(true); 2473 2474 gfx::Transform layer_transform; 2475 layer_transform.Translate(1.0, 1.0); 2476 gfx::Transform sublayer_transform; 2477 sublayer_transform.Scale3d(10.0, 1.0, 1.0); 2478 2479 SetLayerPropertiesForTesting(parent.get(), 2480 layer_transform, 2481 sublayer_transform, 2482 gfx::PointF(0.25f, 0.f), 2483 gfx::PointF(2.5f, 0.f), 2484 gfx::Size(10, 10), 2485 false); 2486 SetLayerPropertiesForTesting(render_surface1.get(), 2487 layer_transform, 2488 sublayer_transform, 2489 gfx::PointF(0.25f, 0.f), 2490 gfx::PointF(2.5f, 0.f), 2491 gfx::Size(10, 10), 2492 false); 2493 SetLayerPropertiesForTesting(render_surface2.get(), 2494 layer_transform, 2495 sublayer_transform, 2496 gfx::PointF(0.25f, 0.f), 2497 gfx::PointF(2.5f, 0.f), 2498 gfx::Size(10, 10), 2499 false); 2500 SetLayerPropertiesForTesting(child_of_root.get(), 2501 layer_transform, 2502 sublayer_transform, 2503 gfx::PointF(0.25f, 0.f), 2504 gfx::PointF(2.5f, 0.f), 2505 gfx::Size(10, 10), 2506 false); 2507 SetLayerPropertiesForTesting(child_of_rs1.get(), 2508 layer_transform, 2509 sublayer_transform, 2510 gfx::PointF(0.25f, 0.f), 2511 gfx::PointF(2.5f, 0.f), 2512 gfx::Size(10, 10), 2513 false); 2514 SetLayerPropertiesForTesting(child_of_rs2.get(), 2515 layer_transform, 2516 sublayer_transform, 2517 gfx::PointF(0.25f, 0.f), 2518 gfx::PointF(2.5f, 0.f), 2519 gfx::Size(10, 10), 2520 false); 2521 SetLayerPropertiesForTesting(grand_child_of_root.get(), 2522 layer_transform, 2523 sublayer_transform, 2524 gfx::PointF(0.25f, 0.f), 2525 gfx::PointF(2.5f, 0.f), 2526 gfx::Size(10, 10), 2527 false); 2528 SetLayerPropertiesForTesting(grand_child_of_rs1.get(), 2529 layer_transform, 2530 sublayer_transform, 2531 gfx::PointF(0.25f, 0.f), 2532 gfx::PointF(2.5f, 0.f), 2533 gfx::Size(10, 10), 2534 false); 2535 SetLayerPropertiesForTesting(grand_child_of_rs2.get(), 2536 layer_transform, 2537 sublayer_transform, 2538 gfx::PointF(0.25f, 0.f), 2539 gfx::PointF(2.5f, 0.f), 2540 gfx::Size(10, 10), 2541 false); 2542 2543 // Put an animated opacity on the render surface. 2544 AddOpacityTransitionToController( 2545 render_surface1->layer_animation_controller(), 10.0, 1.f, 0.f, false); 2546 2547 // Also put an animated opacity on a layer without descendants. 2548 AddOpacityTransitionToController( 2549 grand_child_of_root->layer_animation_controller(), 10.0, 1.f, 0.f, false); 2550 2551 // Put a transform animation on the render surface. 2552 AddAnimatedTransformToController( 2553 render_surface2->layer_animation_controller(), 10.0, 30, 0); 2554 2555 // Also put transform animations on grand_child_of_root, and 2556 // grand_child_of_rs2 2557 AddAnimatedTransformToController( 2558 grand_child_of_root->layer_animation_controller(), 10.0, 30, 0); 2559 AddAnimatedTransformToController( 2560 grand_child_of_rs2->layer_animation_controller(), 10.0, 30, 0); 2561 2562 ExecuteCalculateDrawProperties(parent.get()); 2563 2564 // Only layers that are associated with render surfaces should have an actual 2565 // RenderSurface() value. 2566 ASSERT_TRUE(parent->render_surface()); 2567 ASSERT_FALSE(child_of_root->render_surface()); 2568 ASSERT_FALSE(grand_child_of_root->render_surface()); 2569 2570 ASSERT_TRUE(render_surface1->render_surface()); 2571 ASSERT_FALSE(child_of_rs1->render_surface()); 2572 ASSERT_FALSE(grand_child_of_rs1->render_surface()); 2573 2574 ASSERT_TRUE(render_surface2->render_surface()); 2575 ASSERT_FALSE(child_of_rs2->render_surface()); 2576 ASSERT_FALSE(grand_child_of_rs2->render_surface()); 2577 2578 // Verify all render target accessors 2579 EXPECT_EQ(parent, parent->render_target()); 2580 EXPECT_EQ(parent, child_of_root->render_target()); 2581 EXPECT_EQ(parent, grand_child_of_root->render_target()); 2582 2583 EXPECT_EQ(render_surface1, render_surface1->render_target()); 2584 EXPECT_EQ(render_surface1, child_of_rs1->render_target()); 2585 EXPECT_EQ(render_surface1, grand_child_of_rs1->render_target()); 2586 2587 EXPECT_EQ(render_surface2, render_surface2->render_target()); 2588 EXPECT_EQ(render_surface2, child_of_rs2->render_target()); 2589 EXPECT_EQ(render_surface2, grand_child_of_rs2->render_target()); 2590 2591 // Verify draw_opacity_is_animating values 2592 EXPECT_FALSE(parent->draw_opacity_is_animating()); 2593 EXPECT_FALSE(child_of_root->draw_opacity_is_animating()); 2594 EXPECT_TRUE(grand_child_of_root->draw_opacity_is_animating()); 2595 EXPECT_FALSE(render_surface1->draw_opacity_is_animating()); 2596 EXPECT_TRUE(render_surface1->render_surface()->draw_opacity_is_animating()); 2597 EXPECT_FALSE(child_of_rs1->draw_opacity_is_animating()); 2598 EXPECT_FALSE(grand_child_of_rs1->draw_opacity_is_animating()); 2599 EXPECT_FALSE(render_surface2->draw_opacity_is_animating()); 2600 EXPECT_FALSE(render_surface2->render_surface()->draw_opacity_is_animating()); 2601 EXPECT_FALSE(child_of_rs2->draw_opacity_is_animating()); 2602 EXPECT_FALSE(grand_child_of_rs2->draw_opacity_is_animating()); 2603 2604 // Verify draw_transform_is_animating values 2605 EXPECT_FALSE(parent->draw_transform_is_animating()); 2606 EXPECT_FALSE(child_of_root->draw_transform_is_animating()); 2607 EXPECT_TRUE(grand_child_of_root->draw_transform_is_animating()); 2608 EXPECT_FALSE(render_surface1->draw_transform_is_animating()); 2609 EXPECT_FALSE(render_surface1->render_surface() 2610 ->target_surface_transforms_are_animating()); 2611 EXPECT_FALSE(child_of_rs1->draw_transform_is_animating()); 2612 EXPECT_FALSE(grand_child_of_rs1->draw_transform_is_animating()); 2613 EXPECT_FALSE(render_surface2->draw_transform_is_animating()); 2614 EXPECT_TRUE(render_surface2->render_surface() 2615 ->target_surface_transforms_are_animating()); 2616 EXPECT_FALSE(child_of_rs2->draw_transform_is_animating()); 2617 EXPECT_TRUE(grand_child_of_rs2->draw_transform_is_animating()); 2618 2619 // Verify screen_space_transform_is_animating values 2620 EXPECT_FALSE(parent->screen_space_transform_is_animating()); 2621 EXPECT_FALSE(child_of_root->screen_space_transform_is_animating()); 2622 EXPECT_TRUE(grand_child_of_root->screen_space_transform_is_animating()); 2623 EXPECT_FALSE(render_surface1->screen_space_transform_is_animating()); 2624 EXPECT_FALSE(render_surface1->render_surface() 2625 ->screen_space_transforms_are_animating()); 2626 EXPECT_FALSE(child_of_rs1->screen_space_transform_is_animating()); 2627 EXPECT_FALSE(grand_child_of_rs1->screen_space_transform_is_animating()); 2628 EXPECT_TRUE(render_surface2->screen_space_transform_is_animating()); 2629 EXPECT_TRUE(render_surface2->render_surface() 2630 ->screen_space_transforms_are_animating()); 2631 EXPECT_TRUE(child_of_rs2->screen_space_transform_is_animating()); 2632 EXPECT_TRUE(grand_child_of_rs2->screen_space_transform_is_animating()); 2633 2634 // Sanity check. If these fail there is probably a bug in the test itself. 2635 // It is expected that we correctly set up transforms so that the y-component 2636 // of the screen-space transform encodes the "depth" of the layer in the tree. 2637 EXPECT_FLOAT_EQ(1.0, 2638 parent->screen_space_transform().matrix().getDouble(1, 3)); 2639 EXPECT_FLOAT_EQ( 2640 2.0, child_of_root->screen_space_transform().matrix().getDouble(1, 3)); 2641 EXPECT_FLOAT_EQ( 2642 3.0, 2643 grand_child_of_root->screen_space_transform().matrix().getDouble(1, 3)); 2644 2645 EXPECT_FLOAT_EQ( 2646 2.0, render_surface1->screen_space_transform().matrix().getDouble(1, 3)); 2647 EXPECT_FLOAT_EQ( 2648 3.0, child_of_rs1->screen_space_transform().matrix().getDouble(1, 3)); 2649 EXPECT_FLOAT_EQ( 2650 4.0, 2651 grand_child_of_rs1->screen_space_transform().matrix().getDouble(1, 3)); 2652 2653 EXPECT_FLOAT_EQ( 2654 3.0, render_surface2->screen_space_transform().matrix().getDouble(1, 3)); 2655 EXPECT_FLOAT_EQ( 2656 4.0, child_of_rs2->screen_space_transform().matrix().getDouble(1, 3)); 2657 EXPECT_FLOAT_EQ( 2658 5.0, 2659 grand_child_of_rs2->screen_space_transform().matrix().getDouble(1, 3)); 2660 } 2661 2662 TEST_F(LayerTreeHostCommonTest, VisibleRectForIdentityTransform) { 2663 // Test the calculateVisibleRect() function works correctly for identity 2664 // transforms. 2665 2666 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); 2667 gfx::Transform layer_to_surface_transform; 2668 2669 // Case 1: Layer is contained within the surface. 2670 gfx::Rect layer_content_rect = gfx::Rect(10, 10, 30, 30); 2671 gfx::Rect expected = gfx::Rect(10, 10, 30, 30); 2672 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( 2673 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2674 EXPECT_RECT_EQ(expected, actual); 2675 2676 // Case 2: Layer is outside the surface rect. 2677 layer_content_rect = gfx::Rect(120, 120, 30, 30); 2678 actual = LayerTreeHostCommon::CalculateVisibleRect( 2679 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2680 EXPECT_TRUE(actual.IsEmpty()); 2681 2682 // Case 3: Layer is partially overlapping the surface rect. 2683 layer_content_rect = gfx::Rect(80, 80, 30, 30); 2684 expected = gfx::Rect(80, 80, 20, 20); 2685 actual = LayerTreeHostCommon::CalculateVisibleRect( 2686 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2687 EXPECT_RECT_EQ(expected, actual); 2688 } 2689 2690 TEST_F(LayerTreeHostCommonTest, VisibleRectForTranslations) { 2691 // Test the calculateVisibleRect() function works correctly for scaling 2692 // transforms. 2693 2694 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); 2695 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30); 2696 gfx::Transform layer_to_surface_transform; 2697 2698 // Case 1: Layer is contained within the surface. 2699 layer_to_surface_transform.MakeIdentity(); 2700 layer_to_surface_transform.Translate(10.0, 10.0); 2701 gfx::Rect expected = gfx::Rect(0, 0, 30, 30); 2702 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( 2703 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2704 EXPECT_RECT_EQ(expected, actual); 2705 2706 // Case 2: Layer is outside the surface rect. 2707 layer_to_surface_transform.MakeIdentity(); 2708 layer_to_surface_transform.Translate(120.0, 120.0); 2709 actual = LayerTreeHostCommon::CalculateVisibleRect( 2710 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2711 EXPECT_TRUE(actual.IsEmpty()); 2712 2713 // Case 3: Layer is partially overlapping the surface rect. 2714 layer_to_surface_transform.MakeIdentity(); 2715 layer_to_surface_transform.Translate(80.0, 80.0); 2716 expected = gfx::Rect(0, 0, 20, 20); 2717 actual = LayerTreeHostCommon::CalculateVisibleRect( 2718 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2719 EXPECT_RECT_EQ(expected, actual); 2720 } 2721 2722 TEST_F(LayerTreeHostCommonTest, VisibleRectFor2DRotations) { 2723 // Test the calculateVisibleRect() function works correctly for rotations 2724 // about z-axis (i.e. 2D rotations). Remember that calculateVisibleRect() 2725 // should return the g in the layer's space. 2726 2727 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); 2728 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30); 2729 gfx::Transform layer_to_surface_transform; 2730 2731 // Case 1: Layer is contained within the surface. 2732 layer_to_surface_transform.MakeIdentity(); 2733 layer_to_surface_transform.Translate(50.0, 50.0); 2734 layer_to_surface_transform.Rotate(45.0); 2735 gfx::Rect expected = gfx::Rect(0, 0, 30, 30); 2736 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( 2737 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2738 EXPECT_RECT_EQ(expected, actual); 2739 2740 // Case 2: Layer is outside the surface rect. 2741 layer_to_surface_transform.MakeIdentity(); 2742 layer_to_surface_transform.Translate(-50.0, 0.0); 2743 layer_to_surface_transform.Rotate(45.0); 2744 actual = LayerTreeHostCommon::CalculateVisibleRect( 2745 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2746 EXPECT_TRUE(actual.IsEmpty()); 2747 2748 // Case 3: The layer is rotated about its top-left corner. In surface space, 2749 // the layer is oriented diagonally, with the left half outside of the render 2750 // surface. In this case, the g should still be the entire layer 2751 // (remember the g is computed in layer space); both the top-left 2752 // and bottom-right corners of the layer are still visible. 2753 layer_to_surface_transform.MakeIdentity(); 2754 layer_to_surface_transform.Rotate(45.0); 2755 expected = gfx::Rect(0, 0, 30, 30); 2756 actual = LayerTreeHostCommon::CalculateVisibleRect( 2757 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2758 EXPECT_RECT_EQ(expected, actual); 2759 2760 // Case 4: The layer is rotated about its top-left corner, and translated 2761 // upwards. In surface space, the layer is oriented diagonally, with only the 2762 // top corner of the surface overlapping the layer. In layer space, the render 2763 // surface overlaps the right side of the layer. The g should be 2764 // the layer's right half. 2765 layer_to_surface_transform.MakeIdentity(); 2766 layer_to_surface_transform.Translate(0.0, -sqrt(2.0) * 15.0); 2767 layer_to_surface_transform.Rotate(45.0); 2768 expected = gfx::Rect(15, 0, 15, 30); // Right half of layer bounds. 2769 actual = LayerTreeHostCommon::CalculateVisibleRect( 2770 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2771 EXPECT_RECT_EQ(expected, actual); 2772 } 2773 2774 TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dOrthographicTransform) { 2775 // Test that the calculateVisibleRect() function works correctly for 3d 2776 // transforms. 2777 2778 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); 2779 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100); 2780 gfx::Transform layer_to_surface_transform; 2781 2782 // Case 1: Orthographic projection of a layer rotated about y-axis by 45 2783 // degrees, should be fully contained in the render surface. 2784 layer_to_surface_transform.MakeIdentity(); 2785 layer_to_surface_transform.RotateAboutYAxis(45.0); 2786 gfx::Rect expected = gfx::Rect(0, 0, 100, 100); 2787 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( 2788 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2789 EXPECT_RECT_EQ(expected, actual); 2790 2791 // Case 2: Orthographic projection of a layer rotated about y-axis by 45 2792 // degrees, but shifted to the side so only the right-half the layer would be 2793 // visible on the surface. 2794 // 100 is the un-rotated layer width; divided by sqrt(2) is the rotated width. 2795 double half_width_of_rotated_layer = (100.0 / sqrt(2.0)) * 0.5; 2796 layer_to_surface_transform.MakeIdentity(); 2797 layer_to_surface_transform.Translate(-half_width_of_rotated_layer, 0.0); 2798 layer_to_surface_transform.RotateAboutYAxis(45.0); // Rotates about the left 2799 // edge of the layer. 2800 expected = gfx::Rect(50, 0, 50, 100); // Tight half of the layer. 2801 actual = LayerTreeHostCommon::CalculateVisibleRect( 2802 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2803 EXPECT_RECT_EQ(expected, actual); 2804 } 2805 2806 TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dPerspectiveTransform) { 2807 // Test the calculateVisibleRect() function works correctly when the layer has 2808 // a perspective projection onto the target surface. 2809 2810 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); 2811 gfx::Rect layer_content_rect = gfx::Rect(-50, -50, 200, 200); 2812 gfx::Transform layer_to_surface_transform; 2813 2814 // Case 1: Even though the layer is twice as large as the surface, due to 2815 // perspective foreshortening, the layer will fit fully in the surface when 2816 // its translated more than the perspective amount. 2817 layer_to_surface_transform.MakeIdentity(); 2818 2819 // The following sequence of transforms applies the perspective about the 2820 // center of the surface. 2821 layer_to_surface_transform.Translate(50.0, 50.0); 2822 layer_to_surface_transform.ApplyPerspectiveDepth(9.0); 2823 layer_to_surface_transform.Translate(-50.0, -50.0); 2824 2825 // This translate places the layer in front of the surface's projection plane. 2826 layer_to_surface_transform.Translate3d(0.0, 0.0, -27.0); 2827 2828 gfx::Rect expected = gfx::Rect(-50, -50, 200, 200); 2829 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( 2830 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2831 EXPECT_RECT_EQ(expected, actual); 2832 2833 // Case 2: same projection as before, except that the layer is also translated 2834 // to the side, so that only the right half of the layer should be visible. 2835 // 2836 // Explanation of expected result: The perspective ratio is (z distance 2837 // between layer and camera origin) / (z distance between projection plane and 2838 // camera origin) == ((-27 - 9) / 9) Then, by similar triangles, if we want to 2839 // move a layer by translating -50 units in projected surface units (so that 2840 // only half of it is visible), then we would need to translate by (-36 / 9) * 2841 // -50 == -200 in the layer's units. 2842 layer_to_surface_transform.Translate3d(-200.0, 0.0, 0.0); 2843 expected = gfx::Rect(gfx::Point(50, -50), 2844 gfx::Size(100, 200)); // The right half of the layer's 2845 // bounding rect. 2846 actual = LayerTreeHostCommon::CalculateVisibleRect( 2847 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2848 EXPECT_RECT_EQ(expected, actual); 2849 } 2850 2851 TEST_F(LayerTreeHostCommonTest, 2852 VisibleRectFor3dOrthographicIsNotClippedBehindSurface) { 2853 // There is currently no explicit concept of an orthographic projection plane 2854 // in our code (nor in the CSS spec to my knowledge). Therefore, layers that 2855 // are technically behind the surface in an orthographic world should not be 2856 // clipped when they are flattened to the surface. 2857 2858 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); 2859 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100); 2860 gfx::Transform layer_to_surface_transform; 2861 2862 // This sequence of transforms effectively rotates the layer about the y-axis 2863 // at the center of the layer. 2864 layer_to_surface_transform.MakeIdentity(); 2865 layer_to_surface_transform.Translate(50.0, 0.0); 2866 layer_to_surface_transform.RotateAboutYAxis(45.0); 2867 layer_to_surface_transform.Translate(-50.0, 0.0); 2868 2869 gfx::Rect expected = gfx::Rect(0, 0, 100, 100); 2870 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( 2871 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2872 EXPECT_RECT_EQ(expected, actual); 2873 } 2874 2875 TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dPerspectiveWhenClippedByW) { 2876 // Test the calculateVisibleRect() function works correctly when projecting a 2877 // surface onto a layer, but the layer is partially behind the camera (not 2878 // just behind the projection plane). In this case, the cartesian coordinates 2879 // may seem to be valid, but actually they are not. The visible rect needs to 2880 // be properly clipped by the w = 0 plane in homogeneous coordinates before 2881 // converting to cartesian coordinates. 2882 2883 gfx::Rect target_surface_rect = gfx::Rect(-50, -50, 100, 100); 2884 gfx::Rect layer_content_rect = gfx::Rect(-10, -1, 20, 2); 2885 gfx::Transform layer_to_surface_transform; 2886 2887 // The layer is positioned so that the right half of the layer should be in 2888 // front of the camera, while the other half is behind the surface's 2889 // projection plane. The following sequence of transforms applies the 2890 // perspective and rotation about the center of the layer. 2891 layer_to_surface_transform.MakeIdentity(); 2892 layer_to_surface_transform.ApplyPerspectiveDepth(1.0); 2893 layer_to_surface_transform.Translate3d(-2.0, 0.0, 1.0); 2894 layer_to_surface_transform.RotateAboutYAxis(45.0); 2895 2896 // Sanity check that this transform does indeed cause w < 0 when applying the 2897 // transform, otherwise this code is not testing the intended scenario. 2898 bool clipped; 2899 MathUtil::MapQuad(layer_to_surface_transform, 2900 gfx::QuadF(gfx::RectF(layer_content_rect)), 2901 &clipped); 2902 ASSERT_TRUE(clipped); 2903 2904 int expected_x_position = 0; 2905 int expected_width = 10; 2906 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( 2907 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2908 EXPECT_EQ(expected_x_position, actual.x()); 2909 EXPECT_EQ(expected_width, actual.width()); 2910 } 2911 2912 TEST_F(LayerTreeHostCommonTest, VisibleRectForPerspectiveUnprojection) { 2913 // To determine visible rect in layer space, there needs to be an 2914 // un-projection from surface space to layer space. When the original 2915 // transform was a perspective projection that was clipped, it returns a rect 2916 // that encloses the clipped bounds. Un-projecting this new rect may require 2917 // clipping again. 2918 2919 // This sequence of transforms causes one corner of the layer to protrude 2920 // across the w = 0 plane, and should be clipped. 2921 gfx::Rect target_surface_rect = gfx::Rect(-50, -50, 100, 100); 2922 gfx::Rect layer_content_rect = gfx::Rect(-10, -10, 20, 20); 2923 gfx::Transform layer_to_surface_transform; 2924 layer_to_surface_transform.MakeIdentity(); 2925 layer_to_surface_transform.ApplyPerspectiveDepth(1.0); 2926 layer_to_surface_transform.Translate3d(0.0, 0.0, -5.0); 2927 layer_to_surface_transform.RotateAboutYAxis(45.0); 2928 layer_to_surface_transform.RotateAboutXAxis(80.0); 2929 2930 // Sanity check that un-projection does indeed cause w < 0, otherwise this 2931 // code is not testing the intended scenario. 2932 bool clipped; 2933 gfx::RectF clipped_rect = 2934 MathUtil::MapClippedRect(layer_to_surface_transform, layer_content_rect); 2935 MathUtil::ProjectQuad( 2936 Inverse(layer_to_surface_transform), gfx::QuadF(clipped_rect), &clipped); 2937 ASSERT_TRUE(clipped); 2938 2939 // Only the corner of the layer is not visible on the surface because of being 2940 // clipped. But, the net result of rounding visible region to an axis-aligned 2941 // rect is that the entire layer should still be considered visible. 2942 gfx::Rect expected = gfx::Rect(-10, -10, 20, 20); 2943 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect( 2944 target_surface_rect, layer_content_rect, layer_to_surface_transform); 2945 EXPECT_RECT_EQ(expected, actual); 2946 } 2947 2948 TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) { 2949 scoped_refptr<Layer> root = Layer::Create(); 2950 scoped_refptr<LayerWithForcedDrawsContent> child1 = 2951 make_scoped_refptr(new LayerWithForcedDrawsContent()); 2952 scoped_refptr<LayerWithForcedDrawsContent> child2 = 2953 make_scoped_refptr(new LayerWithForcedDrawsContent()); 2954 scoped_refptr<LayerWithForcedDrawsContent> child3 = 2955 make_scoped_refptr(new LayerWithForcedDrawsContent()); 2956 root->AddChild(child1); 2957 root->AddChild(child2); 2958 root->AddChild(child3); 2959 2960 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 2961 host->SetRootLayer(root); 2962 2963 gfx::Transform identity_matrix; 2964 SetLayerPropertiesForTesting(root.get(), 2965 identity_matrix, 2966 identity_matrix, 2967 gfx::PointF(), 2968 gfx::PointF(), 2969 gfx::Size(100, 100), 2970 false); 2971 SetLayerPropertiesForTesting(child1.get(), 2972 identity_matrix, 2973 identity_matrix, 2974 gfx::PointF(), 2975 gfx::PointF(), 2976 gfx::Size(50, 50), 2977 false); 2978 SetLayerPropertiesForTesting(child2.get(), 2979 identity_matrix, 2980 identity_matrix, 2981 gfx::PointF(), 2982 gfx::PointF(75.f, 75.f), 2983 gfx::Size(50, 50), 2984 false); 2985 SetLayerPropertiesForTesting(child3.get(), 2986 identity_matrix, 2987 identity_matrix, 2988 gfx::PointF(), 2989 gfx::PointF(125.f, 125.f), 2990 gfx::Size(50, 50), 2991 false); 2992 2993 ExecuteCalculateDrawProperties(root.get()); 2994 2995 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 2996 root->render_surface()->DrawableContentRect()); 2997 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect()); 2998 2999 // Layers that do not draw content should have empty visible_content_rects. 3000 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect()); 3001 3002 // layer visible_content_rects are clipped by their target surface. 3003 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect()); 3004 EXPECT_RECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_content_rect()); 3005 EXPECT_TRUE(child3->visible_content_rect().IsEmpty()); 3006 3007 // layer drawable_content_rects are not clipped. 3008 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->drawable_content_rect()); 3009 EXPECT_RECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect()); 3010 EXPECT_RECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect()); 3011 } 3012 3013 TEST_F(LayerTreeHostCommonTest, 3014 DrawableAndVisibleContentRectsForLayersClippedByLayer) { 3015 scoped_refptr<Layer> root = Layer::Create(); 3016 scoped_refptr<Layer> child = Layer::Create(); 3017 scoped_refptr<LayerWithForcedDrawsContent> grand_child1 = 3018 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3019 scoped_refptr<LayerWithForcedDrawsContent> grand_child2 = 3020 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3021 scoped_refptr<LayerWithForcedDrawsContent> grand_child3 = 3022 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3023 root->AddChild(child); 3024 child->AddChild(grand_child1); 3025 child->AddChild(grand_child2); 3026 child->AddChild(grand_child3); 3027 3028 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 3029 host->SetRootLayer(root); 3030 3031 gfx::Transform identity_matrix; 3032 SetLayerPropertiesForTesting(root.get(), 3033 identity_matrix, 3034 identity_matrix, 3035 gfx::PointF(), 3036 gfx::PointF(), 3037 gfx::Size(100, 100), 3038 false); 3039 SetLayerPropertiesForTesting(child.get(), 3040 identity_matrix, 3041 identity_matrix, 3042 gfx::PointF(), 3043 gfx::PointF(), 3044 gfx::Size(100, 100), 3045 false); 3046 SetLayerPropertiesForTesting(grand_child1.get(), 3047 identity_matrix, 3048 identity_matrix, 3049 gfx::PointF(), 3050 gfx::PointF(5.f, 5.f), 3051 gfx::Size(50, 50), 3052 false); 3053 SetLayerPropertiesForTesting(grand_child2.get(), 3054 identity_matrix, 3055 identity_matrix, 3056 gfx::PointF(), 3057 gfx::PointF(75.f, 75.f), 3058 gfx::Size(50, 50), 3059 false); 3060 SetLayerPropertiesForTesting(grand_child3.get(), 3061 identity_matrix, 3062 identity_matrix, 3063 gfx::PointF(), 3064 gfx::PointF(125.f, 125.f), 3065 gfx::Size(50, 50), 3066 false); 3067 3068 child->SetMasksToBounds(true); 3069 ExecuteCalculateDrawProperties(root.get()); 3070 3071 ASSERT_FALSE(child->render_surface()); 3072 3073 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 3074 root->render_surface()->DrawableContentRect()); 3075 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect()); 3076 3077 // Layers that do not draw content should have empty visible content rects. 3078 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect()); 3079 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), child->visible_content_rect()); 3080 3081 // All grandchild visible content rects should be clipped by child. 3082 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), grand_child1->visible_content_rect()); 3083 EXPECT_RECT_EQ(gfx::Rect(0, 0, 25, 25), grand_child2->visible_content_rect()); 3084 EXPECT_TRUE(grand_child3->visible_content_rect().IsEmpty()); 3085 3086 // All grandchild DrawableContentRects should also be clipped by child. 3087 EXPECT_RECT_EQ(gfx::Rect(5, 5, 50, 50), 3088 grand_child1->drawable_content_rect()); 3089 EXPECT_RECT_EQ(gfx::Rect(75, 75, 25, 25), 3090 grand_child2->drawable_content_rect()); 3091 EXPECT_TRUE(grand_child3->drawable_content_rect().IsEmpty()); 3092 } 3093 3094 TEST_F(LayerTreeHostCommonTest, 3095 DrawableAndVisibleContentRectsForLayersInUnclippedRenderSurface) { 3096 scoped_refptr<Layer> root = Layer::Create(); 3097 scoped_refptr<Layer> render_surface1 = Layer::Create(); 3098 scoped_refptr<LayerWithForcedDrawsContent> child1 = 3099 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3100 scoped_refptr<LayerWithForcedDrawsContent> child2 = 3101 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3102 scoped_refptr<LayerWithForcedDrawsContent> child3 = 3103 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3104 root->AddChild(render_surface1); 3105 render_surface1->AddChild(child1); 3106 render_surface1->AddChild(child2); 3107 render_surface1->AddChild(child3); 3108 3109 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 3110 host->SetRootLayer(root); 3111 3112 gfx::Transform identity_matrix; 3113 SetLayerPropertiesForTesting(root.get(), 3114 identity_matrix, 3115 identity_matrix, 3116 gfx::PointF(), 3117 gfx::PointF(), 3118 gfx::Size(100, 100), 3119 false); 3120 SetLayerPropertiesForTesting(render_surface1.get(), 3121 identity_matrix, 3122 identity_matrix, 3123 gfx::PointF(), 3124 gfx::PointF(), 3125 gfx::Size(3, 4), 3126 false); 3127 SetLayerPropertiesForTesting(child1.get(), 3128 identity_matrix, 3129 identity_matrix, 3130 gfx::PointF(), 3131 gfx::PointF(5.f, 5.f), 3132 gfx::Size(50, 50), 3133 false); 3134 SetLayerPropertiesForTesting(child2.get(), 3135 identity_matrix, 3136 identity_matrix, 3137 gfx::PointF(), 3138 gfx::PointF(75.f, 75.f), 3139 gfx::Size(50, 50), 3140 false); 3141 SetLayerPropertiesForTesting(child3.get(), 3142 identity_matrix, 3143 identity_matrix, 3144 gfx::PointF(), 3145 gfx::PointF(125.f, 125.f), 3146 gfx::Size(50, 50), 3147 false); 3148 3149 render_surface1->SetForceRenderSurface(true); 3150 ExecuteCalculateDrawProperties(root.get()); 3151 3152 ASSERT_TRUE(render_surface1->render_surface()); 3153 3154 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 3155 root->render_surface()->DrawableContentRect()); 3156 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect()); 3157 3158 // Layers that do not draw content should have empty visible content rects. 3159 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect()); 3160 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), 3161 render_surface1->visible_content_rect()); 3162 3163 // An unclipped surface grows its DrawableContentRect to include all drawable 3164 // regions of the subtree. 3165 EXPECT_RECT_EQ(gfx::Rect(5, 5, 170, 170), 3166 render_surface1->render_surface()->DrawableContentRect()); 3167 3168 // All layers that draw content into the unclipped surface are also unclipped. 3169 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect()); 3170 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_content_rect()); 3171 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_content_rect()); 3172 3173 EXPECT_RECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect()); 3174 EXPECT_RECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect()); 3175 EXPECT_RECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect()); 3176 } 3177 3178 TEST_F(LayerTreeHostCommonTest, 3179 DrawableAndVisibleContentRectsForLayersWithUninvertibleTransform) { 3180 scoped_refptr<Layer> root = Layer::Create(); 3181 scoped_refptr<LayerWithForcedDrawsContent> child = 3182 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3183 root->AddChild(child); 3184 3185 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 3186 host->SetRootLayer(root); 3187 3188 gfx::Transform identity_matrix; 3189 gfx::Transform uninvertible_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); 3190 3191 SetLayerPropertiesForTesting(root.get(), 3192 identity_matrix, 3193 identity_matrix, 3194 gfx::PointF(), 3195 gfx::PointF(), 3196 gfx::Size(100, 100), 3197 false); 3198 SetLayerPropertiesForTesting(child.get(), 3199 uninvertible_matrix, 3200 identity_matrix, 3201 gfx::PointF(), 3202 gfx::PointF(5.f, 5.f), 3203 gfx::Size(50, 50), 3204 false); 3205 3206 ExecuteCalculateDrawProperties(root.get()); 3207 3208 EXPECT_TRUE(child->visible_content_rect().IsEmpty()); 3209 EXPECT_TRUE(child->drawable_content_rect().IsEmpty()); 3210 } 3211 3212 TEST_F(LayerTreeHostCommonTest, 3213 DrawableAndVisibleContentRectsForLayersInClippedRenderSurface) { 3214 scoped_refptr<Layer> root = Layer::Create(); 3215 scoped_refptr<Layer> render_surface1 = Layer::Create(); 3216 scoped_refptr<LayerWithForcedDrawsContent> child1 = 3217 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3218 scoped_refptr<LayerWithForcedDrawsContent> child2 = 3219 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3220 scoped_refptr<LayerWithForcedDrawsContent> child3 = 3221 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3222 root->AddChild(render_surface1); 3223 render_surface1->AddChild(child1); 3224 render_surface1->AddChild(child2); 3225 render_surface1->AddChild(child3); 3226 3227 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 3228 host->SetRootLayer(root); 3229 3230 gfx::Transform identity_matrix; 3231 SetLayerPropertiesForTesting(root.get(), 3232 identity_matrix, 3233 identity_matrix, 3234 gfx::PointF(), 3235 gfx::PointF(), 3236 gfx::Size(100, 100), 3237 false); 3238 SetLayerPropertiesForTesting(render_surface1.get(), 3239 identity_matrix, 3240 identity_matrix, 3241 gfx::PointF(), 3242 gfx::PointF(), 3243 gfx::Size(3, 4), 3244 false); 3245 SetLayerPropertiesForTesting(child1.get(), 3246 identity_matrix, 3247 identity_matrix, 3248 gfx::PointF(), 3249 gfx::PointF(5.f, 5.f), 3250 gfx::Size(50, 50), 3251 false); 3252 SetLayerPropertiesForTesting(child2.get(), 3253 identity_matrix, 3254 identity_matrix, 3255 gfx::PointF(), 3256 gfx::PointF(75.f, 75.f), 3257 gfx::Size(50, 50), 3258 false); 3259 SetLayerPropertiesForTesting(child3.get(), 3260 identity_matrix, 3261 identity_matrix, 3262 gfx::PointF(), 3263 gfx::PointF(125.f, 125.f), 3264 gfx::Size(50, 50), 3265 false); 3266 3267 root->SetMasksToBounds(true); 3268 render_surface1->SetForceRenderSurface(true); 3269 ExecuteCalculateDrawProperties(root.get()); 3270 3271 ASSERT_TRUE(render_surface1->render_surface()); 3272 3273 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 3274 root->render_surface()->DrawableContentRect()); 3275 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect()); 3276 3277 // Layers that do not draw content should have empty visible content rects. 3278 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect()); 3279 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), 3280 render_surface1->visible_content_rect()); 3281 3282 // A clipped surface grows its DrawableContentRect to include all drawable 3283 // regions of the subtree, but also gets clamped by the ancestor's clip. 3284 EXPECT_RECT_EQ(gfx::Rect(5, 5, 95, 95), 3285 render_surface1->render_surface()->DrawableContentRect()); 3286 3287 // All layers that draw content into the surface have their visible content 3288 // rect clipped by the surface clip rect. 3289 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect()); 3290 EXPECT_RECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_content_rect()); 3291 EXPECT_TRUE(child3->visible_content_rect().IsEmpty()); 3292 3293 // But the DrawableContentRects are unclipped. 3294 EXPECT_RECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect()); 3295 EXPECT_RECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect()); 3296 EXPECT_RECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect()); 3297 } 3298 3299 TEST_F(LayerTreeHostCommonTest, 3300 DrawableAndVisibleContentRectsForSurfaceHierarchy) { 3301 // Check that clipping does not propagate down surfaces. 3302 scoped_refptr<Layer> root = Layer::Create(); 3303 scoped_refptr<Layer> render_surface1 = Layer::Create(); 3304 scoped_refptr<Layer> render_surface2 = Layer::Create(); 3305 scoped_refptr<LayerWithForcedDrawsContent> child1 = 3306 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3307 scoped_refptr<LayerWithForcedDrawsContent> child2 = 3308 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3309 scoped_refptr<LayerWithForcedDrawsContent> child3 = 3310 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3311 root->AddChild(render_surface1); 3312 render_surface1->AddChild(render_surface2); 3313 render_surface2->AddChild(child1); 3314 render_surface2->AddChild(child2); 3315 render_surface2->AddChild(child3); 3316 3317 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 3318 host->SetRootLayer(root); 3319 3320 gfx::Transform identity_matrix; 3321 SetLayerPropertiesForTesting(root.get(), 3322 identity_matrix, 3323 identity_matrix, 3324 gfx::PointF(), 3325 gfx::PointF(), 3326 gfx::Size(100, 100), 3327 false); 3328 SetLayerPropertiesForTesting(render_surface1.get(), 3329 identity_matrix, 3330 identity_matrix, 3331 gfx::PointF(), 3332 gfx::PointF(), 3333 gfx::Size(3, 4), 3334 false); 3335 SetLayerPropertiesForTesting(render_surface2.get(), 3336 identity_matrix, 3337 identity_matrix, 3338 gfx::PointF(), 3339 gfx::PointF(), 3340 gfx::Size(7, 13), 3341 false); 3342 SetLayerPropertiesForTesting(child1.get(), 3343 identity_matrix, 3344 identity_matrix, 3345 gfx::PointF(), 3346 gfx::PointF(5.f, 5.f), 3347 gfx::Size(50, 50), 3348 false); 3349 SetLayerPropertiesForTesting(child2.get(), 3350 identity_matrix, 3351 identity_matrix, 3352 gfx::PointF(), 3353 gfx::PointF(75.f, 75.f), 3354 gfx::Size(50, 50), 3355 false); 3356 SetLayerPropertiesForTesting(child3.get(), 3357 identity_matrix, 3358 identity_matrix, 3359 gfx::PointF(), 3360 gfx::PointF(125.f, 125.f), 3361 gfx::Size(50, 50), 3362 false); 3363 3364 root->SetMasksToBounds(true); 3365 render_surface1->SetForceRenderSurface(true); 3366 render_surface2->SetForceRenderSurface(true); 3367 ExecuteCalculateDrawProperties(root.get()); 3368 3369 ASSERT_TRUE(render_surface1->render_surface()); 3370 ASSERT_TRUE(render_surface2->render_surface()); 3371 3372 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 3373 root->render_surface()->DrawableContentRect()); 3374 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect()); 3375 3376 // Layers that do not draw content should have empty visible content rects. 3377 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect()); 3378 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), 3379 render_surface1->visible_content_rect()); 3380 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), 3381 render_surface2->visible_content_rect()); 3382 3383 // A clipped surface grows its DrawableContentRect to include all drawable 3384 // regions of the subtree, but also gets clamped by the ancestor's clip. 3385 EXPECT_RECT_EQ(gfx::Rect(5, 5, 95, 95), 3386 render_surface1->render_surface()->DrawableContentRect()); 3387 3388 // render_surface1 lives in the "unclipped universe" of render_surface1, and 3389 // is only implicitly clipped by render_surface1's content rect. So, 3390 // render_surface2 grows to enclose all drawable content of its subtree. 3391 EXPECT_RECT_EQ(gfx::Rect(5, 5, 170, 170), 3392 render_surface2->render_surface()->DrawableContentRect()); 3393 3394 // All layers that draw content into render_surface2 think they are unclipped. 3395 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect()); 3396 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_content_rect()); 3397 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_content_rect()); 3398 3399 // DrawableContentRects are also unclipped. 3400 EXPECT_RECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect()); 3401 EXPECT_RECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect()); 3402 EXPECT_RECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect()); 3403 } 3404 3405 TEST_F(LayerTreeHostCommonTest, 3406 DrawableAndVisibleContentRectsWithTransformOnUnclippedSurface) { 3407 // Layers that have non-axis aligned bounds (due to transforms) have an 3408 // expanded, axis-aligned DrawableContentRect and visible content rect. 3409 3410 scoped_refptr<Layer> root = Layer::Create(); 3411 scoped_refptr<Layer> render_surface1 = Layer::Create(); 3412 scoped_refptr<LayerWithForcedDrawsContent> child1 = 3413 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3414 root->AddChild(render_surface1); 3415 render_surface1->AddChild(child1); 3416 3417 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 3418 host->SetRootLayer(root); 3419 3420 gfx::Transform identity_matrix; 3421 gfx::Transform child_rotation; 3422 child_rotation.Rotate(45.0); 3423 SetLayerPropertiesForTesting(root.get(), 3424 identity_matrix, 3425 identity_matrix, 3426 gfx::PointF(), 3427 gfx::PointF(), 3428 gfx::Size(100, 100), 3429 false); 3430 SetLayerPropertiesForTesting(render_surface1.get(), 3431 identity_matrix, 3432 identity_matrix, 3433 gfx::PointF(), 3434 gfx::PointF(), 3435 gfx::Size(3, 4), 3436 false); 3437 SetLayerPropertiesForTesting(child1.get(), 3438 child_rotation, 3439 identity_matrix, 3440 gfx::PointF(0.5f, 0.5f), 3441 gfx::PointF(25.f, 25.f), 3442 gfx::Size(50, 50), 3443 false); 3444 3445 render_surface1->SetForceRenderSurface(true); 3446 ExecuteCalculateDrawProperties(root.get()); 3447 3448 ASSERT_TRUE(render_surface1->render_surface()); 3449 3450 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 3451 root->render_surface()->DrawableContentRect()); 3452 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect()); 3453 3454 // Layers that do not draw content should have empty visible content rects. 3455 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect()); 3456 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), 3457 render_surface1->visible_content_rect()); 3458 3459 // The unclipped surface grows its DrawableContentRect to include all drawable 3460 // regions of the subtree. 3461 int diagonal_radius = ceil(sqrt(2.0) * 25.0); 3462 gfx::Rect expected_surface_drawable_content = 3463 gfx::Rect(50.0 - diagonal_radius, 3464 50.0 - diagonal_radius, 3465 diagonal_radius * 2.0, 3466 diagonal_radius * 2.0); 3467 EXPECT_RECT_EQ(expected_surface_drawable_content, 3468 render_surface1->render_surface()->DrawableContentRect()); 3469 3470 // All layers that draw content into the unclipped surface are also unclipped. 3471 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect()); 3472 EXPECT_RECT_EQ(expected_surface_drawable_content, 3473 child1->drawable_content_rect()); 3474 } 3475 3476 TEST_F(LayerTreeHostCommonTest, 3477 DrawableAndVisibleContentRectsWithTransformOnClippedSurface) { 3478 // Layers that have non-axis aligned bounds (due to transforms) have an 3479 // expanded, axis-aligned DrawableContentRect and visible content rect. 3480 3481 scoped_refptr<Layer> root = Layer::Create(); 3482 scoped_refptr<Layer> render_surface1 = Layer::Create(); 3483 scoped_refptr<LayerWithForcedDrawsContent> child1 = 3484 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3485 root->AddChild(render_surface1); 3486 render_surface1->AddChild(child1); 3487 3488 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 3489 host->SetRootLayer(root); 3490 3491 gfx::Transform identity_matrix; 3492 gfx::Transform child_rotation; 3493 child_rotation.Rotate(45.0); 3494 SetLayerPropertiesForTesting(root.get(), 3495 identity_matrix, 3496 identity_matrix, 3497 gfx::PointF(), 3498 gfx::PointF(), 3499 gfx::Size(50, 50), 3500 false); 3501 SetLayerPropertiesForTesting(render_surface1.get(), 3502 identity_matrix, 3503 identity_matrix, 3504 gfx::PointF(), 3505 gfx::PointF(), 3506 gfx::Size(3, 4), 3507 false); 3508 SetLayerPropertiesForTesting(child1.get(), 3509 child_rotation, 3510 identity_matrix, 3511 gfx::PointF(0.5f, 0.5f), 3512 gfx::PointF(25.f, 25.f), 3513 gfx::Size(50, 50), 3514 false); 3515 3516 root->SetMasksToBounds(true); 3517 render_surface1->SetForceRenderSurface(true); 3518 ExecuteCalculateDrawProperties(root.get()); 3519 3520 ASSERT_TRUE(render_surface1->render_surface()); 3521 3522 // The clipped surface clamps the DrawableContentRect that encloses the 3523 // rotated layer. 3524 int diagonal_radius = ceil(sqrt(2.0) * 25.0); 3525 gfx::Rect unclipped_surface_content = gfx::Rect(50.0 - diagonal_radius, 3526 50.0 - diagonal_radius, 3527 diagonal_radius * 2.0, 3528 diagonal_radius * 2.0); 3529 gfx::Rect expected_surface_drawable_content = 3530 gfx::IntersectRects(unclipped_surface_content, gfx::Rect(0, 0, 50, 50)); 3531 EXPECT_RECT_EQ(expected_surface_drawable_content, 3532 render_surface1->render_surface()->DrawableContentRect()); 3533 3534 // On the clipped surface, only a quarter of the child1 is visible, but when 3535 // rotating it back to child1's content space, the actual enclosing rect ends 3536 // up covering the full left half of child1. 3537 EXPECT_RECT_EQ(gfx::Rect(0, 0, 26, 50), child1->visible_content_rect()); 3538 3539 // The child's DrawableContentRect is unclipped. 3540 EXPECT_RECT_EQ(unclipped_surface_content, child1->drawable_content_rect()); 3541 } 3542 3543 TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { 3544 MockContentLayerClient client; 3545 3546 scoped_refptr<Layer> root = Layer::Create(); 3547 scoped_refptr<ContentLayer> render_surface1 = 3548 CreateDrawableContentLayer(&client); 3549 scoped_refptr<ContentLayer> render_surface2 = 3550 CreateDrawableContentLayer(&client); 3551 scoped_refptr<ContentLayer> child1 = CreateDrawableContentLayer(&client); 3552 scoped_refptr<ContentLayer> child2 = CreateDrawableContentLayer(&client); 3553 scoped_refptr<ContentLayer> child3 = CreateDrawableContentLayer(&client); 3554 root->AddChild(render_surface1); 3555 render_surface1->AddChild(render_surface2); 3556 render_surface2->AddChild(child1); 3557 render_surface2->AddChild(child2); 3558 render_surface2->AddChild(child3); 3559 3560 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 3561 host->SetRootLayer(root); 3562 3563 gfx::Transform identity_matrix; 3564 SetLayerPropertiesForTesting(root.get(), 3565 identity_matrix, 3566 identity_matrix, 3567 gfx::PointF(), 3568 gfx::PointF(), 3569 gfx::Size(100, 100), 3570 false); 3571 SetLayerPropertiesForTesting(render_surface1.get(), 3572 identity_matrix, 3573 identity_matrix, 3574 gfx::PointF(), 3575 gfx::PointF(5.f, 5.f), 3576 gfx::Size(3, 4), 3577 false); 3578 SetLayerPropertiesForTesting(render_surface2.get(), 3579 identity_matrix, 3580 identity_matrix, 3581 gfx::PointF(), 3582 gfx::PointF(5.f, 5.f), 3583 gfx::Size(7, 13), 3584 false); 3585 SetLayerPropertiesForTesting(child1.get(), 3586 identity_matrix, 3587 identity_matrix, 3588 gfx::PointF(), 3589 gfx::PointF(5.f, 5.f), 3590 gfx::Size(50, 50), 3591 false); 3592 SetLayerPropertiesForTesting(child2.get(), 3593 identity_matrix, 3594 identity_matrix, 3595 gfx::PointF(), 3596 gfx::PointF(75.f, 75.f), 3597 gfx::Size(50, 50), 3598 false); 3599 SetLayerPropertiesForTesting(child3.get(), 3600 identity_matrix, 3601 identity_matrix, 3602 gfx::PointF(), 3603 gfx::PointF(125.f, 125.f), 3604 gfx::Size(50, 50), 3605 false); 3606 3607 float device_scale_factor = 2.f; 3608 3609 root->SetMasksToBounds(true); 3610 render_surface1->SetForceRenderSurface(true); 3611 render_surface2->SetForceRenderSurface(true); 3612 ExecuteCalculateDrawProperties(root.get(), device_scale_factor); 3613 3614 ASSERT_TRUE(render_surface1->render_surface()); 3615 ASSERT_TRUE(render_surface2->render_surface()); 3616 3617 // drawable_content_rects for all layers and surfaces are scaled by 3618 // device_scale_factor. 3619 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), 3620 root->render_surface()->DrawableContentRect()); 3621 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), root->drawable_content_rect()); 3622 EXPECT_RECT_EQ(gfx::Rect(10, 10, 190, 190), 3623 render_surface1->render_surface()->DrawableContentRect()); 3624 3625 // render_surface2 lives in the "unclipped universe" of render_surface1, and 3626 // is only implicitly clipped by render_surface1. 3627 EXPECT_RECT_EQ(gfx::Rect(10, 10, 350, 350), 3628 render_surface2->render_surface()->DrawableContentRect()); 3629 3630 EXPECT_RECT_EQ(gfx::Rect(10, 10, 100, 100), child1->drawable_content_rect()); 3631 EXPECT_RECT_EQ(gfx::Rect(150, 150, 100, 100), 3632 child2->drawable_content_rect()); 3633 EXPECT_RECT_EQ(gfx::Rect(250, 250, 100, 100), 3634 child3->drawable_content_rect()); 3635 3636 // The root layer does not actually draw content of its own. 3637 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect()); 3638 3639 // All layer visible content rects are expressed in content space of each 3640 // layer, so they are also scaled by the device_scale_factor. 3641 EXPECT_RECT_EQ(gfx::Rect(0, 0, 6, 8), 3642 render_surface1->visible_content_rect()); 3643 EXPECT_RECT_EQ(gfx::Rect(0, 0, 14, 26), 3644 render_surface2->visible_content_rect()); 3645 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), child1->visible_content_rect()); 3646 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), child2->visible_content_rect()); 3647 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), child3->visible_content_rect()); 3648 } 3649 3650 TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) { 3651 // Verify the behavior of back-face culling when there are no preserve-3d 3652 // layers. Note that 3d transforms still apply in this case, but they are 3653 // "flattened" to each parent layer according to current W3C spec. 3654 3655 const gfx::Transform identity_matrix; 3656 scoped_refptr<Layer> parent = Layer::Create(); 3657 scoped_refptr<LayerWithForcedDrawsContent> front_facing_child = 3658 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3659 scoped_refptr<LayerWithForcedDrawsContent> back_facing_child = 3660 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3661 scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface = 3662 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3663 scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface = 3664 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3665 scoped_refptr<LayerWithForcedDrawsContent> 3666 front_facing_child_of_front_facing_surface = 3667 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3668 scoped_refptr<LayerWithForcedDrawsContent> 3669 back_facing_child_of_front_facing_surface = 3670 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3671 scoped_refptr<LayerWithForcedDrawsContent> 3672 front_facing_child_of_back_facing_surface = 3673 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3674 scoped_refptr<LayerWithForcedDrawsContent> 3675 back_facing_child_of_back_facing_surface = 3676 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3677 3678 parent->AddChild(front_facing_child); 3679 parent->AddChild(back_facing_child); 3680 parent->AddChild(front_facing_surface); 3681 parent->AddChild(back_facing_surface); 3682 front_facing_surface->AddChild(front_facing_child_of_front_facing_surface); 3683 front_facing_surface->AddChild(back_facing_child_of_front_facing_surface); 3684 back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); 3685 back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); 3686 3687 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 3688 host->SetRootLayer(parent); 3689 3690 // Nothing is double-sided 3691 front_facing_child->SetDoubleSided(false); 3692 back_facing_child->SetDoubleSided(false); 3693 front_facing_surface->SetDoubleSided(false); 3694 back_facing_surface->SetDoubleSided(false); 3695 front_facing_child_of_front_facing_surface->SetDoubleSided(false); 3696 back_facing_child_of_front_facing_surface->SetDoubleSided(false); 3697 front_facing_child_of_back_facing_surface->SetDoubleSided(false); 3698 back_facing_child_of_back_facing_surface->SetDoubleSided(false); 3699 3700 gfx::Transform backface_matrix; 3701 backface_matrix.Translate(50.0, 50.0); 3702 backface_matrix.RotateAboutYAxis(180.0); 3703 backface_matrix.Translate(-50.0, -50.0); 3704 3705 // Having a descendant and opacity will force these to have render surfaces. 3706 front_facing_surface->SetOpacity(0.5f); 3707 back_facing_surface->SetOpacity(0.5f); 3708 3709 // Nothing preserves 3d. According to current W3C CSS gfx::Transforms spec, 3710 // these layers should blindly use their own local transforms to determine 3711 // back-face culling. 3712 SetLayerPropertiesForTesting(parent.get(), 3713 identity_matrix, 3714 identity_matrix, 3715 gfx::PointF(), 3716 gfx::PointF(), 3717 gfx::Size(100, 100), 3718 false); 3719 SetLayerPropertiesForTesting(front_facing_child.get(), 3720 identity_matrix, 3721 identity_matrix, 3722 gfx::PointF(), 3723 gfx::PointF(), 3724 gfx::Size(100, 100), 3725 false); 3726 SetLayerPropertiesForTesting(back_facing_child.get(), 3727 backface_matrix, 3728 identity_matrix, 3729 gfx::PointF(), 3730 gfx::PointF(), 3731 gfx::Size(100, 100), 3732 false); 3733 SetLayerPropertiesForTesting(front_facing_surface.get(), 3734 identity_matrix, 3735 identity_matrix, 3736 gfx::PointF(), 3737 gfx::PointF(), 3738 gfx::Size(100, 100), 3739 false); 3740 SetLayerPropertiesForTesting(back_facing_surface.get(), 3741 backface_matrix, 3742 identity_matrix, 3743 gfx::PointF(), 3744 gfx::PointF(), 3745 gfx::Size(100, 100), 3746 false); 3747 SetLayerPropertiesForTesting(front_facing_child_of_front_facing_surface.get(), 3748 identity_matrix, 3749 identity_matrix, 3750 gfx::PointF(), 3751 gfx::PointF(), 3752 gfx::Size(100, 100), 3753 false); 3754 SetLayerPropertiesForTesting(back_facing_child_of_front_facing_surface.get(), 3755 backface_matrix, 3756 identity_matrix, 3757 gfx::PointF(), 3758 gfx::PointF(), 3759 gfx::Size(100, 100), 3760 false); 3761 SetLayerPropertiesForTesting(front_facing_child_of_back_facing_surface.get(), 3762 identity_matrix, 3763 identity_matrix, 3764 gfx::PointF(), 3765 gfx::PointF(), 3766 gfx::Size(100, 100), 3767 false); 3768 SetLayerPropertiesForTesting(back_facing_child_of_back_facing_surface.get(), 3769 backface_matrix, 3770 identity_matrix, 3771 gfx::PointF(), 3772 gfx::PointF(), 3773 gfx::Size(100, 100), 3774 false); 3775 3776 RenderSurfaceLayerList render_surface_layer_list; 3777 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 3778 parent.get(), parent->bounds(), &render_surface_layer_list); 3779 inputs.can_adjust_raster_scales = true; 3780 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 3781 3782 // Verify which render surfaces were created. 3783 EXPECT_FALSE(front_facing_child->render_surface()); 3784 EXPECT_FALSE(back_facing_child->render_surface()); 3785 EXPECT_TRUE(front_facing_surface->render_surface()); 3786 EXPECT_TRUE(back_facing_surface->render_surface()); 3787 EXPECT_FALSE(front_facing_child_of_front_facing_surface->render_surface()); 3788 EXPECT_FALSE(back_facing_child_of_front_facing_surface->render_surface()); 3789 EXPECT_FALSE(front_facing_child_of_back_facing_surface->render_surface()); 3790 EXPECT_FALSE(back_facing_child_of_back_facing_surface->render_surface()); 3791 3792 // Verify the render_surface_layer_list. 3793 ASSERT_EQ(3u, render_surface_layer_list.size()); 3794 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id()); 3795 EXPECT_EQ(front_facing_surface->id(), render_surface_layer_list.at(1)->id()); 3796 // Even though the back facing surface LAYER gets culled, the other 3797 // descendants should still be added, so the SURFACE should not be culled. 3798 EXPECT_EQ(back_facing_surface->id(), render_surface_layer_list.at(2)->id()); 3799 3800 // Verify root surface's layer list. 3801 ASSERT_EQ( 3802 3u, 3803 render_surface_layer_list.at(0)->render_surface()->layer_list().size()); 3804 EXPECT_EQ(front_facing_child->id(), 3805 render_surface_layer_list.at(0) 3806 ->render_surface()->layer_list().at(0)->id()); 3807 EXPECT_EQ(front_facing_surface->id(), 3808 render_surface_layer_list.at(0) 3809 ->render_surface()->layer_list().at(1)->id()); 3810 EXPECT_EQ(back_facing_surface->id(), 3811 render_surface_layer_list.at(0) 3812 ->render_surface()->layer_list().at(2)->id()); 3813 3814 // Verify front_facing_surface's layer list. 3815 ASSERT_EQ( 3816 2u, 3817 render_surface_layer_list.at(1)->render_surface()->layer_list().size()); 3818 EXPECT_EQ(front_facing_surface->id(), 3819 render_surface_layer_list.at(1) 3820 ->render_surface()->layer_list().at(0)->id()); 3821 EXPECT_EQ(front_facing_child_of_front_facing_surface->id(), 3822 render_surface_layer_list.at(1) 3823 ->render_surface()->layer_list().at(1)->id()); 3824 3825 // Verify back_facing_surface's layer list; its own layer should be culled 3826 // from the surface list. 3827 ASSERT_EQ( 3828 1u, 3829 render_surface_layer_list.at(2)->render_surface()->layer_list().size()); 3830 EXPECT_EQ(front_facing_child_of_back_facing_surface->id(), 3831 render_surface_layer_list.at(2) 3832 ->render_surface()->layer_list().at(0)->id()); 3833 } 3834 3835 TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) { 3836 // Verify the behavior of back-face culling when preserves-3d transform style 3837 // is used. 3838 3839 const gfx::Transform identity_matrix; 3840 scoped_refptr<Layer> parent = Layer::Create(); 3841 scoped_refptr<LayerWithForcedDrawsContent> front_facing_child = 3842 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3843 scoped_refptr<LayerWithForcedDrawsContent> back_facing_child = 3844 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3845 scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface = 3846 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3847 scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface = 3848 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3849 scoped_refptr<LayerWithForcedDrawsContent> 3850 front_facing_child_of_front_facing_surface = 3851 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3852 scoped_refptr<LayerWithForcedDrawsContent> 3853 back_facing_child_of_front_facing_surface = 3854 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3855 scoped_refptr<LayerWithForcedDrawsContent> 3856 front_facing_child_of_back_facing_surface = 3857 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3858 scoped_refptr<LayerWithForcedDrawsContent> 3859 back_facing_child_of_back_facing_surface = 3860 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3861 scoped_refptr<LayerWithForcedDrawsContent> dummy_replica_layer1 = 3862 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3863 scoped_refptr<LayerWithForcedDrawsContent> dummy_replica_layer2 = 3864 make_scoped_refptr(new LayerWithForcedDrawsContent()); 3865 3866 parent->AddChild(front_facing_child); 3867 parent->AddChild(back_facing_child); 3868 parent->AddChild(front_facing_surface); 3869 parent->AddChild(back_facing_surface); 3870 front_facing_surface->AddChild(front_facing_child_of_front_facing_surface); 3871 front_facing_surface->AddChild(back_facing_child_of_front_facing_surface); 3872 back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); 3873 back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); 3874 3875 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 3876 host->SetRootLayer(parent); 3877 3878 // Nothing is double-sided 3879 front_facing_child->SetDoubleSided(false); 3880 back_facing_child->SetDoubleSided(false); 3881 front_facing_surface->SetDoubleSided(false); 3882 back_facing_surface->SetDoubleSided(false); 3883 front_facing_child_of_front_facing_surface->SetDoubleSided(false); 3884 back_facing_child_of_front_facing_surface->SetDoubleSided(false); 3885 front_facing_child_of_back_facing_surface->SetDoubleSided(false); 3886 back_facing_child_of_back_facing_surface->SetDoubleSided(false); 3887 3888 gfx::Transform backface_matrix; 3889 backface_matrix.Translate(50.0, 50.0); 3890 backface_matrix.RotateAboutYAxis(180.0); 3891 backface_matrix.Translate(-50.0, -50.0); 3892 3893 // Opacity will not force creation of render surfaces in this case because of 3894 // the preserve-3d transform style. Instead, an example of when a surface 3895 // would be created with preserve-3d is when there is a replica layer. 3896 front_facing_surface->SetReplicaLayer(dummy_replica_layer1.get()); 3897 back_facing_surface->SetReplicaLayer(dummy_replica_layer2.get()); 3898 3899 // Each surface creates its own new 3d rendering context (as defined by W3C 3900 // spec). According to current W3C CSS gfx::Transforms spec, layers in a 3d 3901 // rendering context should use the transform with respect to that context. 3902 // This 3d rendering context occurs when (a) parent's transform style is flat 3903 // and (b) the layer's transform style is preserve-3d. 3904 SetLayerPropertiesForTesting(parent.get(), 3905 identity_matrix, 3906 identity_matrix, 3907 gfx::PointF(), 3908 gfx::PointF(), 3909 gfx::Size(100, 100), 3910 false); // parent transform style is flat. 3911 SetLayerPropertiesForTesting(front_facing_child.get(), 3912 identity_matrix, 3913 identity_matrix, 3914 gfx::PointF(), 3915 gfx::PointF(), 3916 gfx::Size(100, 100), 3917 false); 3918 SetLayerPropertiesForTesting(back_facing_child.get(), 3919 backface_matrix, 3920 identity_matrix, 3921 gfx::PointF(), 3922 gfx::PointF(), 3923 gfx::Size(100, 100), 3924 false); 3925 SetLayerPropertiesForTesting( 3926 front_facing_surface.get(), 3927 identity_matrix, 3928 identity_matrix, 3929 gfx::PointF(), 3930 gfx::PointF(), 3931 gfx::Size(100, 100), 3932 true); // surface transform style is preserve-3d. 3933 SetLayerPropertiesForTesting( 3934 back_facing_surface.get(), 3935 backface_matrix, 3936 identity_matrix, 3937 gfx::PointF(), 3938 gfx::PointF(), 3939 gfx::Size(100, 100), 3940 true); // surface transform style is preserve-3d. 3941 SetLayerPropertiesForTesting(front_facing_child_of_front_facing_surface.get(), 3942 identity_matrix, 3943 identity_matrix, 3944 gfx::PointF(), 3945 gfx::PointF(), 3946 gfx::Size(100, 100), 3947 false); 3948 SetLayerPropertiesForTesting(back_facing_child_of_front_facing_surface.get(), 3949 backface_matrix, 3950 identity_matrix, 3951 gfx::PointF(), 3952 gfx::PointF(), 3953 gfx::Size(100, 100), 3954 false); 3955 SetLayerPropertiesForTesting(front_facing_child_of_back_facing_surface.get(), 3956 identity_matrix, 3957 identity_matrix, 3958 gfx::PointF(), 3959 gfx::PointF(), 3960 gfx::Size(100, 100), 3961 false); 3962 SetLayerPropertiesForTesting(back_facing_child_of_back_facing_surface.get(), 3963 backface_matrix, 3964 identity_matrix, 3965 gfx::PointF(), 3966 gfx::PointF(), 3967 gfx::Size(100, 100), 3968 false); 3969 3970 RenderSurfaceLayerList render_surface_layer_list; 3971 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 3972 parent.get(), parent->bounds(), &render_surface_layer_list); 3973 inputs.can_adjust_raster_scales = true; 3974 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 3975 3976 // Verify which render surfaces were created. 3977 EXPECT_FALSE(front_facing_child->render_surface()); 3978 EXPECT_FALSE(back_facing_child->render_surface()); 3979 EXPECT_TRUE(front_facing_surface->render_surface()); 3980 EXPECT_FALSE(back_facing_surface->render_surface()); 3981 EXPECT_FALSE(front_facing_child_of_front_facing_surface->render_surface()); 3982 EXPECT_FALSE(back_facing_child_of_front_facing_surface->render_surface()); 3983 EXPECT_FALSE(front_facing_child_of_back_facing_surface->render_surface()); 3984 EXPECT_FALSE(back_facing_child_of_back_facing_surface->render_surface()); 3985 3986 // Verify the render_surface_layer_list. The back-facing surface should be 3987 // culled. 3988 ASSERT_EQ(2u, render_surface_layer_list.size()); 3989 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id()); 3990 EXPECT_EQ(front_facing_surface->id(), render_surface_layer_list.at(1)->id()); 3991 3992 // Verify root surface's layer list. 3993 ASSERT_EQ( 3994 2u, 3995 render_surface_layer_list.at(0)->render_surface()->layer_list().size()); 3996 EXPECT_EQ(front_facing_child->id(), 3997 render_surface_layer_list.at(0) 3998 ->render_surface()->layer_list().at(0)->id()); 3999 EXPECT_EQ(front_facing_surface->id(), 4000 render_surface_layer_list.at(0) 4001 ->render_surface()->layer_list().at(1)->id()); 4002 4003 // Verify front_facing_surface's layer list. 4004 ASSERT_EQ( 4005 2u, 4006 render_surface_layer_list.at(1)->render_surface()->layer_list().size()); 4007 EXPECT_EQ(front_facing_surface->id(), 4008 render_surface_layer_list.at(1) 4009 ->render_surface()->layer_list().at(0)->id()); 4010 EXPECT_EQ(front_facing_child_of_front_facing_surface->id(), 4011 render_surface_layer_list.at(1) 4012 ->render_surface()->layer_list().at(1)->id()); 4013 } 4014 4015 TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithAnimatingTransforms) { 4016 // Verify that layers are appropriately culled when their back face is showing 4017 // and they are not double sided, while animations are going on. 4018 // 4019 // Layers that are animating do not get culled on the main thread, as their 4020 // transforms should be treated as "unknown" so we can not be sure that their 4021 // back face is really showing. 4022 const gfx::Transform identity_matrix; 4023 scoped_refptr<Layer> parent = Layer::Create(); 4024 scoped_refptr<LayerWithForcedDrawsContent> child = 4025 make_scoped_refptr(new LayerWithForcedDrawsContent()); 4026 scoped_refptr<LayerWithForcedDrawsContent> animating_surface = 4027 make_scoped_refptr(new LayerWithForcedDrawsContent()); 4028 scoped_refptr<LayerWithForcedDrawsContent> child_of_animating_surface = 4029 make_scoped_refptr(new LayerWithForcedDrawsContent()); 4030 scoped_refptr<LayerWithForcedDrawsContent> animating_child = 4031 make_scoped_refptr(new LayerWithForcedDrawsContent()); 4032 scoped_refptr<LayerWithForcedDrawsContent> child2 = 4033 make_scoped_refptr(new LayerWithForcedDrawsContent()); 4034 4035 parent->AddChild(child); 4036 parent->AddChild(animating_surface); 4037 animating_surface->AddChild(child_of_animating_surface); 4038 parent->AddChild(animating_child); 4039 parent->AddChild(child2); 4040 4041 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 4042 host->SetRootLayer(parent); 4043 4044 // Nothing is double-sided 4045 child->SetDoubleSided(false); 4046 child2->SetDoubleSided(false); 4047 animating_surface->SetDoubleSided(false); 4048 child_of_animating_surface->SetDoubleSided(false); 4049 animating_child->SetDoubleSided(false); 4050 4051 gfx::Transform backface_matrix; 4052 backface_matrix.Translate(50.0, 50.0); 4053 backface_matrix.RotateAboutYAxis(180.0); 4054 backface_matrix.Translate(-50.0, -50.0); 4055 4056 // Make our render surface. 4057 animating_surface->SetForceRenderSurface(true); 4058 4059 // Animate the transform on the render surface. 4060 AddAnimatedTransformToController( 4061 animating_surface->layer_animation_controller(), 10.0, 30, 0); 4062 // This is just an animating layer, not a surface. 4063 AddAnimatedTransformToController( 4064 animating_child->layer_animation_controller(), 10.0, 30, 0); 4065 4066 SetLayerPropertiesForTesting(parent.get(), 4067 identity_matrix, 4068 identity_matrix, 4069 gfx::PointF(), 4070 gfx::PointF(), 4071 gfx::Size(100, 100), 4072 false); 4073 SetLayerPropertiesForTesting(child.get(), 4074 backface_matrix, 4075 identity_matrix, 4076 gfx::PointF(), 4077 gfx::PointF(), 4078 gfx::Size(100, 100), 4079 false); 4080 SetLayerPropertiesForTesting(animating_surface.get(), 4081 backface_matrix, 4082 identity_matrix, 4083 gfx::PointF(), 4084 gfx::PointF(), 4085 gfx::Size(100, 100), 4086 false); 4087 SetLayerPropertiesForTesting(child_of_animating_surface.get(), 4088 backface_matrix, 4089 identity_matrix, 4090 gfx::PointF(), 4091 gfx::PointF(), 4092 gfx::Size(100, 100), 4093 false); 4094 SetLayerPropertiesForTesting(animating_child.get(), 4095 backface_matrix, 4096 identity_matrix, 4097 gfx::PointF(), 4098 gfx::PointF(), 4099 gfx::Size(100, 100), 4100 false); 4101 SetLayerPropertiesForTesting(child2.get(), 4102 identity_matrix, 4103 identity_matrix, 4104 gfx::PointF(), 4105 gfx::PointF(), 4106 gfx::Size(100, 100), 4107 false); 4108 4109 RenderSurfaceLayerList render_surface_layer_list; 4110 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 4111 parent.get(), parent->bounds(), &render_surface_layer_list); 4112 inputs.can_adjust_raster_scales = true; 4113 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 4114 4115 EXPECT_FALSE(child->render_surface()); 4116 EXPECT_TRUE(animating_surface->render_surface()); 4117 EXPECT_FALSE(child_of_animating_surface->render_surface()); 4118 EXPECT_FALSE(animating_child->render_surface()); 4119 EXPECT_FALSE(child2->render_surface()); 4120 4121 // Verify that the animating_child and child_of_animating_surface were not 4122 // culled, but that child was. 4123 ASSERT_EQ(2u, render_surface_layer_list.size()); 4124 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id()); 4125 EXPECT_EQ(animating_surface->id(), render_surface_layer_list.at(1)->id()); 4126 4127 // The non-animating child be culled from the layer list for the parent render 4128 // surface. 4129 ASSERT_EQ( 4130 3u, 4131 render_surface_layer_list.at(0)->render_surface()->layer_list().size()); 4132 EXPECT_EQ(animating_surface->id(), 4133 render_surface_layer_list.at(0) 4134 ->render_surface()->layer_list().at(0)->id()); 4135 EXPECT_EQ(animating_child->id(), 4136 render_surface_layer_list.at(0) 4137 ->render_surface()->layer_list().at(1)->id()); 4138 EXPECT_EQ(child2->id(), 4139 render_surface_layer_list.at(0) 4140 ->render_surface()->layer_list().at(2)->id()); 4141 4142 ASSERT_EQ( 4143 2u, 4144 render_surface_layer_list.at(1)->render_surface()->layer_list().size()); 4145 EXPECT_EQ(animating_surface->id(), 4146 render_surface_layer_list.at(1) 4147 ->render_surface()->layer_list().at(0)->id()); 4148 EXPECT_EQ(child_of_animating_surface->id(), 4149 render_surface_layer_list.at(1) 4150 ->render_surface()->layer_list().at(1)->id()); 4151 4152 EXPECT_FALSE(child2->visible_content_rect().IsEmpty()); 4153 4154 // The animating layers should have a visible content rect that represents the 4155 // area of the front face that is within the viewport. 4156 EXPECT_EQ(animating_child->visible_content_rect(), 4157 gfx::Rect(animating_child->content_bounds())); 4158 EXPECT_EQ(animating_surface->visible_content_rect(), 4159 gfx::Rect(animating_surface->content_bounds())); 4160 // And layers in the subtree of the animating layer should have valid visible 4161 // content rects also. 4162 EXPECT_EQ(child_of_animating_surface->visible_content_rect(), 4163 gfx::Rect(child_of_animating_surface->content_bounds())); 4164 } 4165 4166 TEST_F(LayerTreeHostCommonTest, 4167 BackFaceCullingWithPreserves3dForFlatteningSurface) { 4168 // Verify the behavior of back-face culling for a render surface that is 4169 // created when it flattens its subtree, and its parent has preserves-3d. 4170 4171 const gfx::Transform identity_matrix; 4172 scoped_refptr<Layer> parent = Layer::Create(); 4173 scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface = 4174 make_scoped_refptr(new LayerWithForcedDrawsContent()); 4175 scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface = 4176 make_scoped_refptr(new LayerWithForcedDrawsContent()); 4177 scoped_refptr<LayerWithForcedDrawsContent> child1 = 4178 make_scoped_refptr(new LayerWithForcedDrawsContent()); 4179 scoped_refptr<LayerWithForcedDrawsContent> child2 = 4180 make_scoped_refptr(new LayerWithForcedDrawsContent()); 4181 4182 parent->AddChild(front_facing_surface); 4183 parent->AddChild(back_facing_surface); 4184 front_facing_surface->AddChild(child1); 4185 back_facing_surface->AddChild(child2); 4186 4187 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 4188 host->SetRootLayer(parent); 4189 4190 // RenderSurfaces are not double-sided 4191 front_facing_surface->SetDoubleSided(false); 4192 back_facing_surface->SetDoubleSided(false); 4193 4194 gfx::Transform backface_matrix; 4195 backface_matrix.Translate(50.0, 50.0); 4196 backface_matrix.RotateAboutYAxis(180.0); 4197 backface_matrix.Translate(-50.0, -50.0); 4198 4199 SetLayerPropertiesForTesting(parent.get(), 4200 identity_matrix, 4201 identity_matrix, 4202 gfx::PointF(), 4203 gfx::PointF(), 4204 gfx::Size(100, 100), 4205 true); // parent transform style is preserve3d. 4206 SetLayerPropertiesForTesting(front_facing_surface.get(), 4207 identity_matrix, 4208 identity_matrix, 4209 gfx::PointF(), 4210 gfx::PointF(), 4211 gfx::Size(100, 100), 4212 false); // surface transform style is flat. 4213 SetLayerPropertiesForTesting(back_facing_surface.get(), 4214 backface_matrix, 4215 identity_matrix, 4216 gfx::PointF(), 4217 gfx::PointF(), 4218 gfx::Size(100, 100), 4219 false); // surface transform style is flat. 4220 SetLayerPropertiesForTesting(child1.get(), 4221 identity_matrix, 4222 identity_matrix, 4223 gfx::PointF(), 4224 gfx::PointF(), 4225 gfx::Size(100, 100), 4226 false); 4227 SetLayerPropertiesForTesting(child2.get(), 4228 identity_matrix, 4229 identity_matrix, 4230 gfx::PointF(), 4231 gfx::PointF(), 4232 gfx::Size(100, 100), 4233 false); 4234 4235 RenderSurfaceLayerList render_surface_layer_list; 4236 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 4237 parent.get(), parent->bounds(), &render_surface_layer_list); 4238 inputs.can_adjust_raster_scales = true; 4239 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 4240 4241 // Verify which render surfaces were created. 4242 EXPECT_TRUE(front_facing_surface->render_surface()); 4243 EXPECT_FALSE( 4244 back_facing_surface->render_surface()); // because it should be culled 4245 EXPECT_FALSE(child1->render_surface()); 4246 EXPECT_FALSE(child2->render_surface()); 4247 4248 // Verify the render_surface_layer_list. The back-facing surface should be 4249 // culled. 4250 ASSERT_EQ(2u, render_surface_layer_list.size()); 4251 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id()); 4252 EXPECT_EQ(front_facing_surface->id(), render_surface_layer_list.at(1)->id()); 4253 4254 // Verify root surface's layer list. 4255 ASSERT_EQ( 4256 1u, 4257 render_surface_layer_list.at(0)->render_surface()->layer_list().size()); 4258 EXPECT_EQ(front_facing_surface->id(), 4259 render_surface_layer_list.at(0) 4260 ->render_surface()->layer_list().at(0)->id()); 4261 4262 // Verify front_facing_surface's layer list. 4263 ASSERT_EQ( 4264 2u, 4265 render_surface_layer_list.at(1)->render_surface()->layer_list().size()); 4266 EXPECT_EQ(front_facing_surface->id(), 4267 render_surface_layer_list.at(1) 4268 ->render_surface()->layer_list().at(0)->id()); 4269 EXPECT_EQ(child1->id(), 4270 render_surface_layer_list.at(1) 4271 ->render_surface()->layer_list().at(1)->id()); 4272 } 4273 4274 4275 TEST_F(LayerTreeHostCommonTest, HitTestingForEmptyLayerList) { 4276 // Hit testing on an empty render_surface_layer_list should return a null 4277 // pointer. 4278 LayerImplList render_surface_layer_list; 4279 4280 gfx::Point test_point(0, 0); 4281 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4282 test_point, render_surface_layer_list); 4283 EXPECT_FALSE(result_layer); 4284 4285 test_point = gfx::Point(10, 20); 4286 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4287 test_point, render_surface_layer_list); 4288 EXPECT_FALSE(result_layer); 4289 } 4290 4291 TEST_F(LayerTreeHostCommonTest, HitTestingForSingleLayer) { 4292 FakeImplProxy proxy; 4293 FakeLayerTreeHostImpl host_impl(&proxy); 4294 scoped_ptr<LayerImpl> root = 4295 LayerImpl::Create(host_impl.active_tree(), 12345); 4296 4297 gfx::Transform identity_matrix; 4298 gfx::PointF anchor; 4299 gfx::PointF position; 4300 gfx::Size bounds(100, 100); 4301 SetLayerPropertiesForTesting(root.get(), 4302 identity_matrix, 4303 identity_matrix, 4304 anchor, 4305 position, 4306 bounds, 4307 false); 4308 root->SetDrawsContent(true); 4309 4310 LayerImplList render_surface_layer_list; 4311 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 4312 root.get(), root->bounds(), &render_surface_layer_list); 4313 inputs.can_adjust_raster_scales = true; 4314 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 4315 4316 // Sanity check the scenario we just created. 4317 ASSERT_EQ(1u, render_surface_layer_list.size()); 4318 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 4319 4320 // Hit testing for a point outside the layer should return a null pointer. 4321 gfx::Point test_point(101, 101); 4322 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4323 test_point, render_surface_layer_list); 4324 EXPECT_FALSE(result_layer); 4325 4326 test_point = gfx::Point(-1, -1); 4327 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4328 test_point, render_surface_layer_list); 4329 EXPECT_FALSE(result_layer); 4330 4331 // Hit testing for a point inside should return the root layer. 4332 test_point = gfx::Point(1, 1); 4333 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4334 test_point, render_surface_layer_list); 4335 ASSERT_TRUE(result_layer); 4336 EXPECT_EQ(12345, result_layer->id()); 4337 4338 test_point = gfx::Point(99, 99); 4339 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4340 test_point, render_surface_layer_list); 4341 ASSERT_TRUE(result_layer); 4342 EXPECT_EQ(12345, result_layer->id()); 4343 } 4344 4345 TEST_F(LayerTreeHostCommonTest, HitTestingForSingleLayerAndHud) { 4346 FakeImplProxy proxy; 4347 FakeLayerTreeHostImpl host_impl(&proxy); 4348 scoped_ptr<LayerImpl> root = 4349 LayerImpl::Create(host_impl.active_tree(), 12345); 4350 scoped_ptr<HeadsUpDisplayLayerImpl> hud = 4351 HeadsUpDisplayLayerImpl::Create(host_impl.active_tree(), 11111); 4352 4353 gfx::Transform identity_matrix; 4354 gfx::PointF anchor; 4355 gfx::PointF position; 4356 gfx::Size bounds(100, 100); 4357 SetLayerPropertiesForTesting(root.get(), 4358 identity_matrix, 4359 identity_matrix, 4360 anchor, 4361 position, 4362 bounds, 4363 false); 4364 root->SetDrawsContent(true); 4365 4366 // Create hud and add it as a child of root. 4367 gfx::Size hud_bounds(200, 200); 4368 SetLayerPropertiesForTesting(hud.get(), 4369 identity_matrix, 4370 identity_matrix, 4371 anchor, 4372 position, 4373 hud_bounds, 4374 false); 4375 hud->SetDrawsContent(true); 4376 4377 host_impl.active_tree()->set_hud_layer(hud.get()); 4378 root->AddChild(hud.PassAs<LayerImpl>()); 4379 4380 LayerImplList render_surface_layer_list; 4381 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 4382 root.get(), hud_bounds, &render_surface_layer_list); 4383 inputs.can_adjust_raster_scales = true; 4384 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 4385 4386 // Sanity check the scenario we just created. 4387 ASSERT_EQ(1u, render_surface_layer_list.size()); 4388 ASSERT_EQ(2u, root->render_surface()->layer_list().size()); 4389 4390 // Hit testing for a point inside HUD, but outside root should return null 4391 gfx::Point test_point(101, 101); 4392 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4393 test_point, render_surface_layer_list); 4394 EXPECT_FALSE(result_layer); 4395 4396 test_point = gfx::Point(-1, -1); 4397 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4398 test_point, render_surface_layer_list); 4399 EXPECT_FALSE(result_layer); 4400 4401 // Hit testing for a point inside should return the root layer, never the HUD 4402 // layer. 4403 test_point = gfx::Point(1, 1); 4404 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4405 test_point, render_surface_layer_list); 4406 ASSERT_TRUE(result_layer); 4407 EXPECT_EQ(12345, result_layer->id()); 4408 4409 test_point = gfx::Point(99, 99); 4410 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4411 test_point, render_surface_layer_list); 4412 ASSERT_TRUE(result_layer); 4413 EXPECT_EQ(12345, result_layer->id()); 4414 } 4415 4416 TEST_F(LayerTreeHostCommonTest, HitTestingForUninvertibleTransform) { 4417 FakeImplProxy proxy; 4418 FakeLayerTreeHostImpl host_impl(&proxy); 4419 scoped_ptr<LayerImpl> root = 4420 LayerImpl::Create(host_impl.active_tree(), 12345); 4421 4422 gfx::Transform uninvertible_transform; 4423 uninvertible_transform.matrix().setDouble(0, 0, 0.0); 4424 uninvertible_transform.matrix().setDouble(1, 1, 0.0); 4425 uninvertible_transform.matrix().setDouble(2, 2, 0.0); 4426 uninvertible_transform.matrix().setDouble(3, 3, 0.0); 4427 ASSERT_FALSE(uninvertible_transform.IsInvertible()); 4428 4429 gfx::Transform identity_matrix; 4430 gfx::PointF anchor; 4431 gfx::PointF position; 4432 gfx::Size bounds(100, 100); 4433 SetLayerPropertiesForTesting(root.get(), 4434 uninvertible_transform, 4435 identity_matrix, 4436 anchor, 4437 position, 4438 bounds, 4439 false); 4440 root->SetDrawsContent(true); 4441 4442 LayerImplList render_surface_layer_list; 4443 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 4444 root.get(), root->bounds(), &render_surface_layer_list); 4445 inputs.can_adjust_raster_scales = true; 4446 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 4447 4448 // Sanity check the scenario we just created. 4449 ASSERT_EQ(1u, render_surface_layer_list.size()); 4450 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 4451 ASSERT_FALSE(root->screen_space_transform().IsInvertible()); 4452 4453 // Hit testing any point should not hit the layer. If the invertible matrix is 4454 // accidentally ignored and treated like an identity, then the hit testing 4455 // will incorrectly hit the layer when it shouldn't. 4456 gfx::Point test_point(1, 1); 4457 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4458 test_point, render_surface_layer_list); 4459 EXPECT_FALSE(result_layer); 4460 4461 test_point = gfx::Point(10, 10); 4462 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4463 test_point, render_surface_layer_list); 4464 EXPECT_FALSE(result_layer); 4465 4466 test_point = gfx::Point(10, 30); 4467 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4468 test_point, render_surface_layer_list); 4469 EXPECT_FALSE(result_layer); 4470 4471 test_point = gfx::Point(50, 50); 4472 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4473 test_point, render_surface_layer_list); 4474 EXPECT_FALSE(result_layer); 4475 4476 test_point = gfx::Point(67, 48); 4477 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4478 test_point, render_surface_layer_list); 4479 EXPECT_FALSE(result_layer); 4480 4481 test_point = gfx::Point(99, 99); 4482 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4483 test_point, render_surface_layer_list); 4484 EXPECT_FALSE(result_layer); 4485 4486 test_point = gfx::Point(-1, -1); 4487 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4488 test_point, render_surface_layer_list); 4489 EXPECT_FALSE(result_layer); 4490 } 4491 4492 TEST_F(LayerTreeHostCommonTest, HitTestingForSinglePositionedLayer) { 4493 FakeImplProxy proxy; 4494 FakeLayerTreeHostImpl host_impl(&proxy); 4495 scoped_ptr<LayerImpl> root = 4496 LayerImpl::Create(host_impl.active_tree(), 12345); 4497 4498 gfx::Transform identity_matrix; 4499 gfx::PointF anchor; 4500 // this layer is positioned, and hit testing should correctly know where the 4501 // layer is located. 4502 gfx::PointF position(50.f, 50.f); 4503 gfx::Size bounds(100, 100); 4504 SetLayerPropertiesForTesting(root.get(), 4505 identity_matrix, 4506 identity_matrix, 4507 anchor, 4508 position, 4509 bounds, 4510 false); 4511 root->SetDrawsContent(true); 4512 4513 LayerImplList render_surface_layer_list; 4514 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 4515 root.get(), root->bounds(), &render_surface_layer_list); 4516 inputs.can_adjust_raster_scales = true; 4517 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 4518 4519 // Sanity check the scenario we just created. 4520 ASSERT_EQ(1u, render_surface_layer_list.size()); 4521 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 4522 4523 // Hit testing for a point outside the layer should return a null pointer. 4524 gfx::Point test_point(49, 49); 4525 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4526 test_point, render_surface_layer_list); 4527 EXPECT_FALSE(result_layer); 4528 4529 // Even though the layer exists at (101, 101), it should not be visible there 4530 // since the root render surface would clamp it. 4531 test_point = gfx::Point(101, 101); 4532 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4533 test_point, render_surface_layer_list); 4534 EXPECT_FALSE(result_layer); 4535 4536 // Hit testing for a point inside should return the root layer. 4537 test_point = gfx::Point(51, 51); 4538 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4539 test_point, render_surface_layer_list); 4540 ASSERT_TRUE(result_layer); 4541 EXPECT_EQ(12345, result_layer->id()); 4542 4543 test_point = gfx::Point(99, 99); 4544 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4545 test_point, render_surface_layer_list); 4546 ASSERT_TRUE(result_layer); 4547 EXPECT_EQ(12345, result_layer->id()); 4548 } 4549 4550 TEST_F(LayerTreeHostCommonTest, HitTestingForSingleRotatedLayer) { 4551 FakeImplProxy proxy; 4552 FakeLayerTreeHostImpl host_impl(&proxy); 4553 scoped_ptr<LayerImpl> root = 4554 LayerImpl::Create(host_impl.active_tree(), 12345); 4555 4556 gfx::Transform identity_matrix; 4557 gfx::Transform rotation45_degrees_about_center; 4558 rotation45_degrees_about_center.Translate(50.0, 50.0); 4559 rotation45_degrees_about_center.RotateAboutZAxis(45.0); 4560 rotation45_degrees_about_center.Translate(-50.0, -50.0); 4561 gfx::PointF anchor; 4562 gfx::PointF position; 4563 gfx::Size bounds(100, 100); 4564 SetLayerPropertiesForTesting(root.get(), 4565 rotation45_degrees_about_center, 4566 identity_matrix, 4567 anchor, 4568 position, 4569 bounds, 4570 false); 4571 root->SetDrawsContent(true); 4572 4573 LayerImplList render_surface_layer_list; 4574 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 4575 root.get(), root->bounds(), &render_surface_layer_list); 4576 inputs.can_adjust_raster_scales = true; 4577 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 4578 4579 // Sanity check the scenario we just created. 4580 ASSERT_EQ(1u, render_surface_layer_list.size()); 4581 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 4582 4583 // Hit testing for points outside the layer. 4584 // These corners would have been inside the un-transformed layer, but they 4585 // should not hit the correctly transformed layer. 4586 gfx::Point test_point(99, 99); 4587 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4588 test_point, render_surface_layer_list); 4589 EXPECT_FALSE(result_layer); 4590 4591 test_point = gfx::Point(1, 1); 4592 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4593 test_point, render_surface_layer_list); 4594 EXPECT_FALSE(result_layer); 4595 4596 // Hit testing for a point inside should return the root layer. 4597 test_point = gfx::Point(1, 50); 4598 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4599 test_point, render_surface_layer_list); 4600 ASSERT_TRUE(result_layer); 4601 EXPECT_EQ(12345, result_layer->id()); 4602 4603 // Hit testing the corners that would overlap the unclipped layer, but are 4604 // outside the clipped region. 4605 test_point = gfx::Point(50, -1); 4606 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4607 test_point, render_surface_layer_list); 4608 ASSERT_FALSE(result_layer); 4609 4610 test_point = gfx::Point(-1, 50); 4611 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4612 test_point, render_surface_layer_list); 4613 ASSERT_FALSE(result_layer); 4614 } 4615 4616 TEST_F(LayerTreeHostCommonTest, HitTestingForSinglePerspectiveLayer) { 4617 FakeImplProxy proxy; 4618 FakeLayerTreeHostImpl host_impl(&proxy); 4619 scoped_ptr<LayerImpl> root = 4620 LayerImpl::Create(host_impl.active_tree(), 12345); 4621 4622 gfx::Transform identity_matrix; 4623 4624 // perspective_projection_about_center * translation_by_z is designed so that 4625 // the 100 x 100 layer becomes 50 x 50, and remains centered at (50, 50). 4626 gfx::Transform perspective_projection_about_center; 4627 perspective_projection_about_center.Translate(50.0, 50.0); 4628 perspective_projection_about_center.ApplyPerspectiveDepth(1.0); 4629 perspective_projection_about_center.Translate(-50.0, -50.0); 4630 gfx::Transform translation_by_z; 4631 translation_by_z.Translate3d(0.0, 0.0, -1.0); 4632 4633 gfx::PointF anchor; 4634 gfx::PointF position; 4635 gfx::Size bounds(100, 100); 4636 SetLayerPropertiesForTesting( 4637 root.get(), 4638 perspective_projection_about_center * translation_by_z, 4639 identity_matrix, 4640 anchor, 4641 position, 4642 bounds, 4643 false); 4644 root->SetDrawsContent(true); 4645 4646 LayerImplList render_surface_layer_list; 4647 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 4648 root.get(), root->bounds(), &render_surface_layer_list); 4649 inputs.can_adjust_raster_scales = true; 4650 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 4651 4652 // Sanity check the scenario we just created. 4653 ASSERT_EQ(1u, render_surface_layer_list.size()); 4654 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 4655 4656 // Hit testing for points outside the layer. 4657 // These corners would have been inside the un-transformed layer, but they 4658 // should not hit the correctly transformed layer. 4659 gfx::Point test_point(24, 24); 4660 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4661 test_point, render_surface_layer_list); 4662 EXPECT_FALSE(result_layer); 4663 4664 test_point = gfx::Point(76, 76); 4665 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4666 test_point, render_surface_layer_list); 4667 EXPECT_FALSE(result_layer); 4668 4669 // Hit testing for a point inside should return the root layer. 4670 test_point = gfx::Point(26, 26); 4671 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4672 test_point, render_surface_layer_list); 4673 ASSERT_TRUE(result_layer); 4674 EXPECT_EQ(12345, result_layer->id()); 4675 4676 test_point = gfx::Point(74, 74); 4677 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4678 test_point, render_surface_layer_list); 4679 ASSERT_TRUE(result_layer); 4680 EXPECT_EQ(12345, result_layer->id()); 4681 } 4682 4683 TEST_F(LayerTreeHostCommonTest, HitTestingForSingleLayerWithScaledContents) { 4684 // A layer's visible content rect is actually in the layer's content space. 4685 // The screen space transform converts from the layer's origin space to screen 4686 // space. This test makes sure that hit testing works correctly accounts for 4687 // the contents scale. A contents scale that is not 1 effectively forces a 4688 // non-identity transform between layer's content space and layer's origin 4689 // space. The hit testing code must take this into account. 4690 // 4691 // To test this, the layer is positioned at (25, 25), and is size (50, 50). If 4692 // contents scale is ignored, then hit testing will mis-interpret the visible 4693 // content rect as being larger than the actual bounds of the layer. 4694 // 4695 FakeImplProxy proxy; 4696 FakeLayerTreeHostImpl host_impl(&proxy); 4697 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); 4698 4699 gfx::Transform identity_matrix; 4700 gfx::PointF anchor; 4701 4702 SetLayerPropertiesForTesting(root.get(), 4703 identity_matrix, 4704 identity_matrix, 4705 anchor, 4706 gfx::PointF(), 4707 gfx::Size(100, 100), 4708 false); 4709 { 4710 gfx::PointF position(25.f, 25.f); 4711 gfx::Size bounds(50, 50); 4712 scoped_ptr<LayerImpl> test_layer = 4713 LayerImpl::Create(host_impl.active_tree(), 12345); 4714 SetLayerPropertiesForTesting(test_layer.get(), 4715 identity_matrix, 4716 identity_matrix, 4717 anchor, 4718 position, 4719 bounds, 4720 false); 4721 4722 // override content bounds and contents scale 4723 test_layer->SetContentBounds(gfx::Size(100, 100)); 4724 test_layer->SetContentsScale(2, 2); 4725 4726 test_layer->SetDrawsContent(true); 4727 root->AddChild(test_layer.Pass()); 4728 } 4729 4730 LayerImplList render_surface_layer_list; 4731 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 4732 root.get(), root->bounds(), &render_surface_layer_list); 4733 inputs.can_adjust_raster_scales = true; 4734 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 4735 4736 // Sanity check the scenario we just created. 4737 // The visible content rect for test_layer is actually 100x100, even though 4738 // its layout size is 50x50, positioned at 25x25. 4739 LayerImpl* test_layer = root->children()[0]; 4740 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), 4741 test_layer->visible_content_rect()); 4742 ASSERT_EQ(1u, render_surface_layer_list.size()); 4743 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 4744 4745 // Hit testing for a point outside the layer should return a null pointer (the 4746 // root layer does not draw content, so it will not be hit tested either). 4747 gfx::Point test_point(101, 101); 4748 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4749 test_point, render_surface_layer_list); 4750 EXPECT_FALSE(result_layer); 4751 4752 test_point = gfx::Point(24, 24); 4753 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4754 test_point, render_surface_layer_list); 4755 EXPECT_FALSE(result_layer); 4756 4757 test_point = gfx::Point(76, 76); 4758 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4759 test_point, render_surface_layer_list); 4760 EXPECT_FALSE(result_layer); 4761 4762 // Hit testing for a point inside should return the test layer. 4763 test_point = gfx::Point(26, 26); 4764 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4765 test_point, render_surface_layer_list); 4766 ASSERT_TRUE(result_layer); 4767 EXPECT_EQ(12345, result_layer->id()); 4768 4769 test_point = gfx::Point(74, 74); 4770 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4771 test_point, render_surface_layer_list); 4772 ASSERT_TRUE(result_layer); 4773 EXPECT_EQ(12345, result_layer->id()); 4774 } 4775 4776 TEST_F(LayerTreeHostCommonTest, HitTestingForSimpleClippedLayer) { 4777 // Test that hit-testing will only work for the visible portion of a layer, 4778 // and not the entire layer bounds. Here we just test the simple axis-aligned 4779 // case. 4780 gfx::Transform identity_matrix; 4781 gfx::PointF anchor; 4782 4783 FakeImplProxy proxy; 4784 FakeLayerTreeHostImpl host_impl(&proxy); 4785 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); 4786 SetLayerPropertiesForTesting(root.get(), 4787 identity_matrix, 4788 identity_matrix, 4789 anchor, 4790 gfx::PointF(), 4791 gfx::Size(100, 100), 4792 false); 4793 { 4794 scoped_ptr<LayerImpl> clipping_layer = 4795 LayerImpl::Create(host_impl.active_tree(), 123); 4796 // this layer is positioned, and hit testing should correctly know where the 4797 // layer is located. 4798 gfx::PointF position(25.f, 25.f); 4799 gfx::Size bounds(50, 50); 4800 SetLayerPropertiesForTesting(clipping_layer.get(), 4801 identity_matrix, 4802 identity_matrix, 4803 anchor, 4804 position, 4805 bounds, 4806 false); 4807 clipping_layer->SetMasksToBounds(true); 4808 4809 scoped_ptr<LayerImpl> child = 4810 LayerImpl::Create(host_impl.active_tree(), 456); 4811 position = gfx::PointF(-50.f, -50.f); 4812 bounds = gfx::Size(300, 300); 4813 SetLayerPropertiesForTesting(child.get(), 4814 identity_matrix, 4815 identity_matrix, 4816 anchor, 4817 position, 4818 bounds, 4819 false); 4820 child->SetDrawsContent(true); 4821 clipping_layer->AddChild(child.Pass()); 4822 root->AddChild(clipping_layer.Pass()); 4823 } 4824 4825 LayerImplList render_surface_layer_list; 4826 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 4827 root.get(), root->bounds(), &render_surface_layer_list); 4828 inputs.can_adjust_raster_scales = true; 4829 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 4830 4831 // Sanity check the scenario we just created. 4832 ASSERT_EQ(1u, render_surface_layer_list.size()); 4833 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 4834 ASSERT_EQ(456, root->render_surface()->layer_list().at(0)->id()); 4835 4836 // Hit testing for a point outside the layer should return a null pointer. 4837 // Despite the child layer being very large, it should be clipped to the root 4838 // layer's bounds. 4839 gfx::Point test_point(24, 24); 4840 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4841 test_point, render_surface_layer_list); 4842 EXPECT_FALSE(result_layer); 4843 4844 // Even though the layer exists at (101, 101), it should not be visible there 4845 // since the clipping_layer would clamp it. 4846 test_point = gfx::Point(76, 76); 4847 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4848 test_point, render_surface_layer_list); 4849 EXPECT_FALSE(result_layer); 4850 4851 // Hit testing for a point inside should return the child layer. 4852 test_point = gfx::Point(26, 26); 4853 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4854 test_point, render_surface_layer_list); 4855 ASSERT_TRUE(result_layer); 4856 EXPECT_EQ(456, result_layer->id()); 4857 4858 test_point = gfx::Point(74, 74); 4859 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4860 test_point, render_surface_layer_list); 4861 ASSERT_TRUE(result_layer); 4862 EXPECT_EQ(456, result_layer->id()); 4863 } 4864 4865 TEST_F(LayerTreeHostCommonTest, HitTestingForMultiClippedRotatedLayer) { 4866 // This test checks whether hit testing correctly avoids hit testing with 4867 // multiple ancestors that clip in non axis-aligned ways. To pass this test, 4868 // the hit testing algorithm needs to recognize that multiple parent layers 4869 // may clip the layer, and should not actually hit those clipped areas. 4870 // 4871 // The child and grand_child layers are both initialized to clip the 4872 // rotated_leaf. The child layer is rotated about the top-left corner, so that 4873 // the root + child clips combined create a triangle. The rotated_leaf will 4874 // only be visible where it overlaps this triangle. 4875 // 4876 FakeImplProxy proxy; 4877 FakeLayerTreeHostImpl host_impl(&proxy); 4878 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 123); 4879 4880 gfx::Transform identity_matrix; 4881 gfx::PointF anchor; 4882 gfx::PointF position; 4883 gfx::Size bounds(100, 100); 4884 SetLayerPropertiesForTesting(root.get(), 4885 identity_matrix, 4886 identity_matrix, 4887 anchor, 4888 position, 4889 bounds, 4890 false); 4891 root->SetMasksToBounds(true); 4892 { 4893 scoped_ptr<LayerImpl> child = 4894 LayerImpl::Create(host_impl.active_tree(), 456); 4895 scoped_ptr<LayerImpl> grand_child = 4896 LayerImpl::Create(host_impl.active_tree(), 789); 4897 scoped_ptr<LayerImpl> rotated_leaf = 4898 LayerImpl::Create(host_impl.active_tree(), 2468); 4899 4900 position = gfx::PointF(10.f, 10.f); 4901 bounds = gfx::Size(80, 80); 4902 SetLayerPropertiesForTesting(child.get(), 4903 identity_matrix, 4904 identity_matrix, 4905 anchor, 4906 position, 4907 bounds, 4908 false); 4909 child->SetMasksToBounds(true); 4910 4911 gfx::Transform rotation45_degrees_about_corner; 4912 rotation45_degrees_about_corner.RotateAboutZAxis(45.0); 4913 4914 // remember, positioned with respect to its parent which is already at 10, 4915 // 10 4916 position = gfx::PointF(); 4917 bounds = 4918 gfx::Size(200, 200); // to ensure it covers at least sqrt(2) * 100. 4919 SetLayerPropertiesForTesting(grand_child.get(), 4920 rotation45_degrees_about_corner, 4921 identity_matrix, 4922 anchor, 4923 position, 4924 bounds, 4925 false); 4926 grand_child->SetMasksToBounds(true); 4927 4928 // Rotates about the center of the layer 4929 gfx::Transform rotated_leaf_transform; 4930 rotated_leaf_transform.Translate( 4931 -10.0, -10.0); // cancel out the grand_parent's position 4932 rotated_leaf_transform.RotateAboutZAxis( 4933 -45.0); // cancel out the corner 45-degree rotation of the parent. 4934 rotated_leaf_transform.Translate(50.0, 50.0); 4935 rotated_leaf_transform.RotateAboutZAxis(45.0); 4936 rotated_leaf_transform.Translate(-50.0, -50.0); 4937 position = gfx::PointF(); 4938 bounds = gfx::Size(100, 100); 4939 SetLayerPropertiesForTesting(rotated_leaf.get(), 4940 rotated_leaf_transform, 4941 identity_matrix, 4942 anchor, 4943 position, 4944 bounds, 4945 false); 4946 rotated_leaf->SetDrawsContent(true); 4947 4948 grand_child->AddChild(rotated_leaf.Pass()); 4949 child->AddChild(grand_child.Pass()); 4950 root->AddChild(child.Pass()); 4951 } 4952 4953 LayerImplList render_surface_layer_list; 4954 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 4955 root.get(), root->bounds(), &render_surface_layer_list); 4956 inputs.can_adjust_raster_scales = true; 4957 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 4958 4959 // Sanity check the scenario we just created. 4960 // The grand_child is expected to create a render surface because it 4961 // MasksToBounds and is not axis aligned. 4962 ASSERT_EQ(2u, render_surface_layer_list.size()); 4963 ASSERT_EQ( 4964 1u, 4965 render_surface_layer_list.at(0)->render_surface()->layer_list().size()); 4966 ASSERT_EQ(789, 4967 render_surface_layer_list.at(0)->render_surface()->layer_list().at( 4968 0)->id()); // grand_child's surface. 4969 ASSERT_EQ( 4970 1u, 4971 render_surface_layer_list.at(1)->render_surface()->layer_list().size()); 4972 ASSERT_EQ( 4973 2468, 4974 render_surface_layer_list[1]->render_surface()->layer_list().at(0)->id()); 4975 4976 // (11, 89) is close to the the bottom left corner within the clip, but it is 4977 // not inside the layer. 4978 gfx::Point test_point(11, 89); 4979 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4980 test_point, render_surface_layer_list); 4981 EXPECT_FALSE(result_layer); 4982 4983 // Closer inwards from the bottom left will overlap the layer. 4984 test_point = gfx::Point(25, 75); 4985 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4986 test_point, render_surface_layer_list); 4987 ASSERT_TRUE(result_layer); 4988 EXPECT_EQ(2468, result_layer->id()); 4989 4990 // (4, 50) is inside the unclipped layer, but that corner of the layer should 4991 // be clipped away by the grandparent and should not get hit. If hit testing 4992 // blindly uses visible content rect without considering how parent may clip 4993 // the layer, then hit testing would accidentally think that the point 4994 // successfully hits the layer. 4995 test_point = gfx::Point(4, 50); 4996 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 4997 test_point, render_surface_layer_list); 4998 EXPECT_FALSE(result_layer); 4999 5000 // (11, 50) is inside the layer and within the clipped area. 5001 test_point = gfx::Point(11, 50); 5002 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5003 test_point, render_surface_layer_list); 5004 ASSERT_TRUE(result_layer); 5005 EXPECT_EQ(2468, result_layer->id()); 5006 5007 // Around the middle, just to the right and up, would have hit the layer 5008 // except that that area should be clipped away by the parent. 5009 test_point = gfx::Point(51, 51); 5010 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5011 test_point, render_surface_layer_list); 5012 EXPECT_FALSE(result_layer); 5013 5014 // Around the middle, just to the left and down, should successfully hit the 5015 // layer. 5016 test_point = gfx::Point(49, 51); 5017 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5018 test_point, render_surface_layer_list); 5019 ASSERT_TRUE(result_layer); 5020 EXPECT_EQ(2468, result_layer->id()); 5021 } 5022 5023 TEST_F(LayerTreeHostCommonTest, HitTestingForNonClippingIntermediateLayer) { 5024 // This test checks that hit testing code does not accidentally clip to layer 5025 // bounds for a layer that actually does not clip. 5026 gfx::Transform identity_matrix; 5027 gfx::PointF anchor; 5028 5029 FakeImplProxy proxy; 5030 FakeLayerTreeHostImpl host_impl(&proxy); 5031 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); 5032 SetLayerPropertiesForTesting(root.get(), 5033 identity_matrix, 5034 identity_matrix, 5035 anchor, 5036 gfx::PointF(), 5037 gfx::Size(100, 100), 5038 false); 5039 { 5040 scoped_ptr<LayerImpl> intermediate_layer = 5041 LayerImpl::Create(host_impl.active_tree(), 123); 5042 // this layer is positioned, and hit testing should correctly know where the 5043 // layer is located. 5044 gfx::PointF position(10.f, 10.f); 5045 gfx::Size bounds(50, 50); 5046 SetLayerPropertiesForTesting(intermediate_layer.get(), 5047 identity_matrix, 5048 identity_matrix, 5049 anchor, 5050 position, 5051 bounds, 5052 false); 5053 // Sanity check the intermediate layer should not clip. 5054 ASSERT_FALSE(intermediate_layer->masks_to_bounds()); 5055 ASSERT_FALSE(intermediate_layer->mask_layer()); 5056 5057 // The child of the intermediate_layer is translated so that it does not 5058 // overlap intermediate_layer at all. If child is incorrectly clipped, we 5059 // would not be able to hit it successfully. 5060 scoped_ptr<LayerImpl> child = 5061 LayerImpl::Create(host_impl.active_tree(), 456); 5062 position = gfx::PointF(60.f, 60.f); // 70, 70 in screen space 5063 bounds = gfx::Size(20, 20); 5064 SetLayerPropertiesForTesting(child.get(), 5065 identity_matrix, 5066 identity_matrix, 5067 anchor, 5068 position, 5069 bounds, 5070 false); 5071 child->SetDrawsContent(true); 5072 intermediate_layer->AddChild(child.Pass()); 5073 root->AddChild(intermediate_layer.Pass()); 5074 } 5075 5076 LayerImplList render_surface_layer_list; 5077 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 5078 root.get(), root->bounds(), &render_surface_layer_list); 5079 inputs.can_adjust_raster_scales = true; 5080 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 5081 5082 // Sanity check the scenario we just created. 5083 ASSERT_EQ(1u, render_surface_layer_list.size()); 5084 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 5085 ASSERT_EQ(456, root->render_surface()->layer_list().at(0)->id()); 5086 5087 // Hit testing for a point outside the layer should return a null pointer. 5088 gfx::Point test_point(69, 69); 5089 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5090 test_point, render_surface_layer_list); 5091 EXPECT_FALSE(result_layer); 5092 5093 test_point = gfx::Point(91, 91); 5094 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5095 test_point, render_surface_layer_list); 5096 EXPECT_FALSE(result_layer); 5097 5098 // Hit testing for a point inside should return the child layer. 5099 test_point = gfx::Point(71, 71); 5100 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5101 test_point, render_surface_layer_list); 5102 ASSERT_TRUE(result_layer); 5103 EXPECT_EQ(456, result_layer->id()); 5104 5105 test_point = gfx::Point(89, 89); 5106 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5107 test_point, render_surface_layer_list); 5108 ASSERT_TRUE(result_layer); 5109 EXPECT_EQ(456, result_layer->id()); 5110 } 5111 5112 TEST_F(LayerTreeHostCommonTest, HitTestingForMultipleLayers) { 5113 FakeImplProxy proxy; 5114 FakeLayerTreeHostImpl host_impl(&proxy); 5115 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); 5116 5117 gfx::Transform identity_matrix; 5118 gfx::PointF anchor; 5119 gfx::PointF position; 5120 gfx::Size bounds(100, 100); 5121 SetLayerPropertiesForTesting(root.get(), 5122 identity_matrix, 5123 identity_matrix, 5124 anchor, 5125 position, 5126 bounds, 5127 false); 5128 root->SetDrawsContent(true); 5129 { 5130 // child 1 and child2 are initialized to overlap between x=50 and x=60. 5131 // grand_child is set to overlap both child1 and child2 between y=50 and 5132 // y=60. The expected stacking order is: (front) child2, (second) 5133 // grand_child, (third) child1, and (back) the root layer behind all other 5134 // layers. 5135 5136 scoped_ptr<LayerImpl> child1 = 5137 LayerImpl::Create(host_impl.active_tree(), 2); 5138 scoped_ptr<LayerImpl> child2 = 5139 LayerImpl::Create(host_impl.active_tree(), 3); 5140 scoped_ptr<LayerImpl> grand_child1 = 5141 LayerImpl::Create(host_impl.active_tree(), 4); 5142 5143 position = gfx::PointF(10.f, 10.f); 5144 bounds = gfx::Size(50, 50); 5145 SetLayerPropertiesForTesting(child1.get(), 5146 identity_matrix, 5147 identity_matrix, 5148 anchor, 5149 position, 5150 bounds, 5151 false); 5152 child1->SetDrawsContent(true); 5153 5154 position = gfx::PointF(50.f, 10.f); 5155 bounds = gfx::Size(50, 50); 5156 SetLayerPropertiesForTesting(child2.get(), 5157 identity_matrix, 5158 identity_matrix, 5159 anchor, 5160 position, 5161 bounds, 5162 false); 5163 child2->SetDrawsContent(true); 5164 5165 // Remember that grand_child is positioned with respect to its parent (i.e. 5166 // child1). In screen space, the intended position is (10, 50), with size 5167 // 100 x 50. 5168 position = gfx::PointF(0.f, 40.f); 5169 bounds = gfx::Size(100, 50); 5170 SetLayerPropertiesForTesting(grand_child1.get(), 5171 identity_matrix, 5172 identity_matrix, 5173 anchor, 5174 position, 5175 bounds, 5176 false); 5177 grand_child1->SetDrawsContent(true); 5178 5179 child1->AddChild(grand_child1.Pass()); 5180 root->AddChild(child1.Pass()); 5181 root->AddChild(child2.Pass()); 5182 } 5183 5184 LayerImpl* child1 = root->children()[0]; 5185 LayerImpl* child2 = root->children()[1]; 5186 LayerImpl* grand_child1 = child1->children()[0]; 5187 5188 LayerImplList render_surface_layer_list; 5189 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 5190 root.get(), root->bounds(), &render_surface_layer_list); 5191 inputs.can_adjust_raster_scales = true; 5192 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 5193 5194 // Sanity check the scenario we just created. 5195 ASSERT_TRUE(child1); 5196 ASSERT_TRUE(child2); 5197 ASSERT_TRUE(grand_child1); 5198 ASSERT_EQ(1u, render_surface_layer_list.size()); 5199 5200 RenderSurfaceImpl* root_render_surface = root->render_surface(); 5201 ASSERT_EQ(4u, root_render_surface->layer_list().size()); 5202 ASSERT_EQ(1, root_render_surface->layer_list().at(0)->id()); // root layer 5203 ASSERT_EQ(2, root_render_surface->layer_list().at(1)->id()); // child1 5204 ASSERT_EQ(4, root_render_surface->layer_list().at(2)->id()); // grand_child1 5205 ASSERT_EQ(3, root_render_surface->layer_list().at(3)->id()); // child2 5206 5207 // Nothing overlaps the root_layer at (1, 1), so hit testing there should find 5208 // the root layer. 5209 gfx::Point test_point = gfx::Point(1, 1); 5210 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5211 test_point, render_surface_layer_list); 5212 ASSERT_TRUE(result_layer); 5213 EXPECT_EQ(1, result_layer->id()); 5214 5215 // At (15, 15), child1 and root are the only layers. child1 is expected to be 5216 // on top. 5217 test_point = gfx::Point(15, 15); 5218 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5219 test_point, render_surface_layer_list); 5220 ASSERT_TRUE(result_layer); 5221 EXPECT_EQ(2, result_layer->id()); 5222 5223 // At (51, 20), child1 and child2 overlap. child2 is expected to be on top. 5224 test_point = gfx::Point(51, 20); 5225 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5226 test_point, render_surface_layer_list); 5227 ASSERT_TRUE(result_layer); 5228 EXPECT_EQ(3, result_layer->id()); 5229 5230 // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on 5231 // top. 5232 test_point = gfx::Point(80, 51); 5233 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5234 test_point, render_surface_layer_list); 5235 ASSERT_TRUE(result_layer); 5236 EXPECT_EQ(3, result_layer->id()); 5237 5238 // At (51, 51), all layers overlap each other. child2 is expected to be on top 5239 // of all other layers. 5240 test_point = gfx::Point(51, 51); 5241 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5242 test_point, render_surface_layer_list); 5243 ASSERT_TRUE(result_layer); 5244 EXPECT_EQ(3, result_layer->id()); 5245 5246 // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to 5247 // be on top. 5248 test_point = gfx::Point(20, 51); 5249 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5250 test_point, render_surface_layer_list); 5251 ASSERT_TRUE(result_layer); 5252 EXPECT_EQ(4, result_layer->id()); 5253 } 5254 5255 TEST_F(LayerTreeHostCommonTest, HitTestingForMultipleLayerLists) { 5256 // 5257 // The geometry is set up similarly to the previous case, but 5258 // all layers are forced to be render surfaces now. 5259 // 5260 FakeImplProxy proxy; 5261 FakeLayerTreeHostImpl host_impl(&proxy); 5262 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); 5263 5264 gfx::Transform identity_matrix; 5265 gfx::PointF anchor; 5266 gfx::PointF position; 5267 gfx::Size bounds(100, 100); 5268 SetLayerPropertiesForTesting(root.get(), 5269 identity_matrix, 5270 identity_matrix, 5271 anchor, 5272 position, 5273 bounds, 5274 false); 5275 root->SetDrawsContent(true); 5276 { 5277 // child 1 and child2 are initialized to overlap between x=50 and x=60. 5278 // grand_child is set to overlap both child1 and child2 between y=50 and 5279 // y=60. The expected stacking order is: (front) child2, (second) 5280 // grand_child, (third) child1, and (back) the root layer behind all other 5281 // layers. 5282 5283 scoped_ptr<LayerImpl> child1 = 5284 LayerImpl::Create(host_impl.active_tree(), 2); 5285 scoped_ptr<LayerImpl> child2 = 5286 LayerImpl::Create(host_impl.active_tree(), 3); 5287 scoped_ptr<LayerImpl> grand_child1 = 5288 LayerImpl::Create(host_impl.active_tree(), 4); 5289 5290 position = gfx::PointF(10.f, 10.f); 5291 bounds = gfx::Size(50, 50); 5292 SetLayerPropertiesForTesting(child1.get(), 5293 identity_matrix, 5294 identity_matrix, 5295 anchor, 5296 position, 5297 bounds, 5298 false); 5299 child1->SetDrawsContent(true); 5300 child1->SetForceRenderSurface(true); 5301 5302 position = gfx::PointF(50.f, 10.f); 5303 bounds = gfx::Size(50, 50); 5304 SetLayerPropertiesForTesting(child2.get(), 5305 identity_matrix, 5306 identity_matrix, 5307 anchor, 5308 position, 5309 bounds, 5310 false); 5311 child2->SetDrawsContent(true); 5312 child2->SetForceRenderSurface(true); 5313 5314 // Remember that grand_child is positioned with respect to its parent (i.e. 5315 // child1). In screen space, the intended position is (10, 50), with size 5316 // 100 x 50. 5317 position = gfx::PointF(0.f, 40.f); 5318 bounds = gfx::Size(100, 50); 5319 SetLayerPropertiesForTesting(grand_child1.get(), 5320 identity_matrix, 5321 identity_matrix, 5322 anchor, 5323 position, 5324 bounds, 5325 false); 5326 grand_child1->SetDrawsContent(true); 5327 grand_child1->SetForceRenderSurface(true); 5328 5329 child1->AddChild(grand_child1.Pass()); 5330 root->AddChild(child1.Pass()); 5331 root->AddChild(child2.Pass()); 5332 } 5333 5334 LayerImpl* child1 = root->children()[0]; 5335 LayerImpl* child2 = root->children()[1]; 5336 LayerImpl* grand_child1 = child1->children()[0]; 5337 5338 LayerImplList render_surface_layer_list; 5339 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 5340 root.get(), root->bounds(), &render_surface_layer_list); 5341 inputs.can_adjust_raster_scales = true; 5342 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 5343 5344 // Sanity check the scenario we just created. 5345 ASSERT_TRUE(child1); 5346 ASSERT_TRUE(child2); 5347 ASSERT_TRUE(grand_child1); 5348 ASSERT_TRUE(child1->render_surface()); 5349 ASSERT_TRUE(child2->render_surface()); 5350 ASSERT_TRUE(grand_child1->render_surface()); 5351 ASSERT_EQ(4u, render_surface_layer_list.size()); 5352 // The root surface has the root layer, and child1's and child2's render 5353 // surfaces. 5354 ASSERT_EQ(3u, root->render_surface()->layer_list().size()); 5355 // The child1 surface has the child1 layer and grand_child1's render surface. 5356 ASSERT_EQ(2u, child1->render_surface()->layer_list().size()); 5357 ASSERT_EQ(1u, child2->render_surface()->layer_list().size()); 5358 ASSERT_EQ(1u, grand_child1->render_surface()->layer_list().size()); 5359 ASSERT_EQ(1, render_surface_layer_list.at(0)->id()); // root layer 5360 ASSERT_EQ(2, render_surface_layer_list[1]->id()); // child1 5361 ASSERT_EQ(4, render_surface_layer_list.at(2)->id()); // grand_child1 5362 ASSERT_EQ(3, render_surface_layer_list[3]->id()); // child2 5363 5364 // Nothing overlaps the root_layer at (1, 1), so hit testing there should find 5365 // the root layer. 5366 gfx::Point test_point = gfx::Point(1, 1); 5367 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5368 test_point, render_surface_layer_list); 5369 ASSERT_TRUE(result_layer); 5370 EXPECT_EQ(1, result_layer->id()); 5371 5372 // At (15, 15), child1 and root are the only layers. child1 is expected to be 5373 // on top. 5374 test_point = gfx::Point(15, 15); 5375 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5376 test_point, render_surface_layer_list); 5377 ASSERT_TRUE(result_layer); 5378 EXPECT_EQ(2, result_layer->id()); 5379 5380 // At (51, 20), child1 and child2 overlap. child2 is expected to be on top. 5381 test_point = gfx::Point(51, 20); 5382 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5383 test_point, render_surface_layer_list); 5384 ASSERT_TRUE(result_layer); 5385 EXPECT_EQ(3, result_layer->id()); 5386 5387 // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on 5388 // top. 5389 test_point = gfx::Point(80, 51); 5390 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5391 test_point, render_surface_layer_list); 5392 ASSERT_TRUE(result_layer); 5393 EXPECT_EQ(3, result_layer->id()); 5394 5395 // At (51, 51), all layers overlap each other. child2 is expected to be on top 5396 // of all other layers. 5397 test_point = gfx::Point(51, 51); 5398 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5399 test_point, render_surface_layer_list); 5400 ASSERT_TRUE(result_layer); 5401 EXPECT_EQ(3, result_layer->id()); 5402 5403 // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to 5404 // be on top. 5405 test_point = gfx::Point(20, 51); 5406 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint( 5407 test_point, render_surface_layer_list); 5408 ASSERT_TRUE(result_layer); 5409 EXPECT_EQ(4, result_layer->id()); 5410 } 5411 5412 TEST_F(LayerTreeHostCommonTest, 5413 HitCheckingTouchHandlerRegionsForEmptyLayerList) { 5414 // Hit checking on an empty render_surface_layer_list should return a null 5415 // pointer. 5416 LayerImplList render_surface_layer_list; 5417 5418 gfx::Point test_point(0, 0); 5419 LayerImpl* result_layer = 5420 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5421 test_point, render_surface_layer_list); 5422 EXPECT_FALSE(result_layer); 5423 5424 test_point = gfx::Point(10, 20); 5425 result_layer = 5426 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5427 test_point, render_surface_layer_list); 5428 EXPECT_FALSE(result_layer); 5429 } 5430 5431 TEST_F(LayerTreeHostCommonTest, HitCheckingTouchHandlerRegionsForSingleLayer) { 5432 FakeImplProxy proxy; 5433 FakeLayerTreeHostImpl host_impl(&proxy); 5434 scoped_ptr<LayerImpl> root = 5435 LayerImpl::Create(host_impl.active_tree(), 12345); 5436 5437 gfx::Transform identity_matrix; 5438 Region touch_handler_region(gfx::Rect(10, 10, 50, 50)); 5439 gfx::PointF anchor; 5440 gfx::PointF position; 5441 gfx::Size bounds(100, 100); 5442 SetLayerPropertiesForTesting(root.get(), 5443 identity_matrix, 5444 identity_matrix, 5445 anchor, 5446 position, 5447 bounds, 5448 false); 5449 root->SetDrawsContent(true); 5450 5451 LayerImplList render_surface_layer_list; 5452 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 5453 root.get(), root->bounds(), &render_surface_layer_list); 5454 inputs.can_adjust_raster_scales = true; 5455 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 5456 5457 // Sanity check the scenario we just created. 5458 ASSERT_EQ(1u, render_surface_layer_list.size()); 5459 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 5460 5461 // Hit checking for any point should return a null pointer for a layer without 5462 // any touch event handler regions. 5463 gfx::Point test_point(11, 11); 5464 LayerImpl* result_layer = 5465 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5466 test_point, render_surface_layer_list); 5467 EXPECT_FALSE(result_layer); 5468 5469 root->SetTouchEventHandlerRegion(touch_handler_region); 5470 // Hit checking for a point outside the layer should return a null pointer. 5471 test_point = gfx::Point(101, 101); 5472 result_layer = 5473 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5474 test_point, render_surface_layer_list); 5475 EXPECT_FALSE(result_layer); 5476 5477 test_point = gfx::Point(-1, -1); 5478 result_layer = 5479 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5480 test_point, render_surface_layer_list); 5481 EXPECT_FALSE(result_layer); 5482 5483 // Hit checking for a point inside the layer, but outside the touch handler 5484 // region should return a null pointer. 5485 test_point = gfx::Point(1, 1); 5486 result_layer = 5487 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5488 test_point, render_surface_layer_list); 5489 EXPECT_FALSE(result_layer); 5490 5491 test_point = gfx::Point(99, 99); 5492 result_layer = 5493 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5494 test_point, render_surface_layer_list); 5495 EXPECT_FALSE(result_layer); 5496 5497 // Hit checking for a point inside the touch event handler region should 5498 // return the root layer. 5499 test_point = gfx::Point(11, 11); 5500 result_layer = 5501 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5502 test_point, render_surface_layer_list); 5503 ASSERT_TRUE(result_layer); 5504 EXPECT_EQ(12345, result_layer->id()); 5505 5506 test_point = gfx::Point(59, 59); 5507 result_layer = 5508 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5509 test_point, render_surface_layer_list); 5510 ASSERT_TRUE(result_layer); 5511 EXPECT_EQ(12345, result_layer->id()); 5512 } 5513 5514 TEST_F(LayerTreeHostCommonTest, 5515 HitCheckingTouchHandlerRegionsForUninvertibleTransform) { 5516 FakeImplProxy proxy; 5517 FakeLayerTreeHostImpl host_impl(&proxy); 5518 scoped_ptr<LayerImpl> root = 5519 LayerImpl::Create(host_impl.active_tree(), 12345); 5520 5521 gfx::Transform uninvertible_transform; 5522 uninvertible_transform.matrix().setDouble(0, 0, 0.0); 5523 uninvertible_transform.matrix().setDouble(1, 1, 0.0); 5524 uninvertible_transform.matrix().setDouble(2, 2, 0.0); 5525 uninvertible_transform.matrix().setDouble(3, 3, 0.0); 5526 ASSERT_FALSE(uninvertible_transform.IsInvertible()); 5527 5528 gfx::Transform identity_matrix; 5529 Region touch_handler_region(gfx::Rect(10, 10, 50, 50)); 5530 gfx::PointF anchor; 5531 gfx::PointF position; 5532 gfx::Size bounds(100, 100); 5533 SetLayerPropertiesForTesting(root.get(), 5534 uninvertible_transform, 5535 identity_matrix, 5536 anchor, 5537 position, 5538 bounds, 5539 false); 5540 root->SetDrawsContent(true); 5541 root->SetTouchEventHandlerRegion(touch_handler_region); 5542 5543 LayerImplList render_surface_layer_list; 5544 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 5545 root.get(), root->bounds(), &render_surface_layer_list); 5546 inputs.can_adjust_raster_scales = true; 5547 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 5548 5549 // Sanity check the scenario we just created. 5550 ASSERT_EQ(1u, render_surface_layer_list.size()); 5551 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 5552 ASSERT_FALSE(root->screen_space_transform().IsInvertible()); 5553 5554 // Hit checking any point should not hit the touch handler region on the 5555 // layer. If the invertible matrix is accidentally ignored and treated like an 5556 // identity, then the hit testing will incorrectly hit the layer when it 5557 // shouldn't. 5558 gfx::Point test_point(1, 1); 5559 LayerImpl* result_layer = 5560 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5561 test_point, render_surface_layer_list); 5562 EXPECT_FALSE(result_layer); 5563 5564 test_point = gfx::Point(10, 10); 5565 result_layer = 5566 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5567 test_point, render_surface_layer_list); 5568 EXPECT_FALSE(result_layer); 5569 5570 test_point = gfx::Point(10, 30); 5571 result_layer = 5572 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5573 test_point, render_surface_layer_list); 5574 EXPECT_FALSE(result_layer); 5575 5576 test_point = gfx::Point(50, 50); 5577 result_layer = 5578 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5579 test_point, render_surface_layer_list); 5580 EXPECT_FALSE(result_layer); 5581 5582 test_point = gfx::Point(67, 48); 5583 result_layer = 5584 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5585 test_point, render_surface_layer_list); 5586 EXPECT_FALSE(result_layer); 5587 5588 test_point = gfx::Point(99, 99); 5589 result_layer = 5590 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5591 test_point, render_surface_layer_list); 5592 EXPECT_FALSE(result_layer); 5593 5594 test_point = gfx::Point(-1, -1); 5595 result_layer = 5596 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5597 test_point, render_surface_layer_list); 5598 EXPECT_FALSE(result_layer); 5599 } 5600 5601 TEST_F(LayerTreeHostCommonTest, 5602 HitCheckingTouchHandlerRegionsForSinglePositionedLayer) { 5603 FakeImplProxy proxy; 5604 FakeLayerTreeHostImpl host_impl(&proxy); 5605 scoped_ptr<LayerImpl> root = 5606 LayerImpl::Create(host_impl.active_tree(), 12345); 5607 5608 gfx::Transform identity_matrix; 5609 Region touch_handler_region(gfx::Rect(10, 10, 50, 50)); 5610 gfx::PointF anchor; 5611 // this layer is positioned, and hit testing should correctly know where the 5612 // layer is located. 5613 gfx::PointF position(50.f, 50.f); 5614 gfx::Size bounds(100, 100); 5615 SetLayerPropertiesForTesting(root.get(), 5616 identity_matrix, 5617 identity_matrix, 5618 anchor, 5619 position, 5620 bounds, 5621 false); 5622 root->SetDrawsContent(true); 5623 root->SetTouchEventHandlerRegion(touch_handler_region); 5624 5625 LayerImplList render_surface_layer_list; 5626 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 5627 root.get(), root->bounds(), &render_surface_layer_list); 5628 inputs.can_adjust_raster_scales = true; 5629 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 5630 5631 // Sanity check the scenario we just created. 5632 ASSERT_EQ(1u, render_surface_layer_list.size()); 5633 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 5634 5635 // Hit checking for a point outside the layer should return a null pointer. 5636 gfx::Point test_point(49, 49); 5637 LayerImpl* result_layer = 5638 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5639 test_point, render_surface_layer_list); 5640 EXPECT_FALSE(result_layer); 5641 5642 // Even though the layer has a touch handler region containing (101, 101), it 5643 // should not be visible there since the root render surface would clamp it. 5644 test_point = gfx::Point(101, 101); 5645 result_layer = 5646 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5647 test_point, render_surface_layer_list); 5648 EXPECT_FALSE(result_layer); 5649 5650 // Hit checking for a point inside the layer, but outside the touch handler 5651 // region should return a null pointer. 5652 test_point = gfx::Point(51, 51); 5653 result_layer = 5654 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5655 test_point, render_surface_layer_list); 5656 EXPECT_FALSE(result_layer); 5657 5658 // Hit checking for a point inside the touch event handler region should 5659 // return the root layer. 5660 test_point = gfx::Point(61, 61); 5661 result_layer = 5662 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5663 test_point, render_surface_layer_list); 5664 ASSERT_TRUE(result_layer); 5665 EXPECT_EQ(12345, result_layer->id()); 5666 5667 test_point = gfx::Point(99, 99); 5668 result_layer = 5669 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5670 test_point, render_surface_layer_list); 5671 ASSERT_TRUE(result_layer); 5672 EXPECT_EQ(12345, result_layer->id()); 5673 } 5674 5675 TEST_F(LayerTreeHostCommonTest, 5676 HitCheckingTouchHandlerRegionsForSingleLayerWithScaledContents) { 5677 // A layer's visible content rect is actually in the layer's content space. 5678 // The screen space transform converts from the layer's origin space to screen 5679 // space. This test makes sure that hit testing works correctly accounts for 5680 // the contents scale. A contents scale that is not 1 effectively forces a 5681 // non-identity transform between layer's content space and layer's origin 5682 // space. The hit testing code must take this into account. 5683 // 5684 // To test this, the layer is positioned at (25, 25), and is size (50, 50). If 5685 // contents scale is ignored, then hit checking will mis-interpret the visible 5686 // content rect as being larger than the actual bounds of the layer. 5687 // 5688 FakeImplProxy proxy; 5689 FakeLayerTreeHostImpl host_impl(&proxy); 5690 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); 5691 5692 gfx::Transform identity_matrix; 5693 gfx::PointF anchor; 5694 5695 SetLayerPropertiesForTesting(root.get(), 5696 identity_matrix, 5697 identity_matrix, 5698 anchor, 5699 gfx::PointF(), 5700 gfx::Size(100, 100), 5701 false); 5702 { 5703 Region touch_handler_region(gfx::Rect(10, 10, 30, 30)); 5704 gfx::PointF position(25.f, 25.f); 5705 gfx::Size bounds(50, 50); 5706 scoped_ptr<LayerImpl> test_layer = 5707 LayerImpl::Create(host_impl.active_tree(), 12345); 5708 SetLayerPropertiesForTesting(test_layer.get(), 5709 identity_matrix, 5710 identity_matrix, 5711 anchor, 5712 position, 5713 bounds, 5714 false); 5715 5716 // override content bounds and contents scale 5717 test_layer->SetContentBounds(gfx::Size(100, 100)); 5718 test_layer->SetContentsScale(2, 2); 5719 5720 test_layer->SetDrawsContent(true); 5721 test_layer->SetTouchEventHandlerRegion(touch_handler_region); 5722 root->AddChild(test_layer.Pass()); 5723 } 5724 5725 LayerImplList render_surface_layer_list; 5726 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 5727 root.get(), root->bounds(), &render_surface_layer_list); 5728 inputs.can_adjust_raster_scales = true; 5729 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 5730 5731 // Sanity check the scenario we just created. 5732 // The visible content rect for test_layer is actually 100x100, even though 5733 // its layout size is 50x50, positioned at 25x25. 5734 LayerImpl* test_layer = root->children()[0]; 5735 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), test_layer->visible_content_rect()); 5736 ASSERT_EQ(1u, render_surface_layer_list.size()); 5737 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 5738 5739 // Hit checking for a point outside the layer should return a null pointer 5740 // (the root layer does not draw content, so it will not be tested either). 5741 gfx::Point test_point(76, 76); 5742 LayerImpl* result_layer = 5743 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5744 test_point, render_surface_layer_list); 5745 EXPECT_FALSE(result_layer); 5746 5747 // Hit checking for a point inside the layer, but outside the touch handler 5748 // region should return a null pointer. 5749 test_point = gfx::Point(26, 26); 5750 result_layer = 5751 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5752 test_point, render_surface_layer_list); 5753 EXPECT_FALSE(result_layer); 5754 5755 test_point = gfx::Point(34, 34); 5756 result_layer = 5757 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5758 test_point, render_surface_layer_list); 5759 EXPECT_FALSE(result_layer); 5760 5761 test_point = gfx::Point(65, 65); 5762 result_layer = 5763 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5764 test_point, render_surface_layer_list); 5765 EXPECT_FALSE(result_layer); 5766 5767 test_point = gfx::Point(74, 74); 5768 result_layer = 5769 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5770 test_point, render_surface_layer_list); 5771 EXPECT_FALSE(result_layer); 5772 5773 // Hit checking for a point inside the touch event handler region should 5774 // return the root layer. 5775 test_point = gfx::Point(35, 35); 5776 result_layer = 5777 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5778 test_point, render_surface_layer_list); 5779 ASSERT_TRUE(result_layer); 5780 EXPECT_EQ(12345, result_layer->id()); 5781 5782 test_point = gfx::Point(64, 64); 5783 result_layer = 5784 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5785 test_point, render_surface_layer_list); 5786 ASSERT_TRUE(result_layer); 5787 EXPECT_EQ(12345, result_layer->id()); 5788 } 5789 5790 TEST_F(LayerTreeHostCommonTest, 5791 HitCheckingTouchHandlerRegionsForSingleLayerWithDeviceScale) { 5792 // The layer's device_scale_factor and page_scale_factor should scale the 5793 // content rect and we should be able to hit the touch handler region by 5794 // scaling the points accordingly. 5795 FakeImplProxy proxy; 5796 FakeLayerTreeHostImpl host_impl(&proxy); 5797 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); 5798 5799 gfx::Transform identity_matrix; 5800 gfx::PointF anchor; 5801 // Set the bounds of the root layer big enough to fit the child when scaled. 5802 SetLayerPropertiesForTesting(root.get(), 5803 identity_matrix, 5804 identity_matrix, 5805 anchor, 5806 gfx::PointF(), 5807 gfx::Size(100, 100), 5808 false); 5809 { 5810 Region touch_handler_region(gfx::Rect(10, 10, 30, 30)); 5811 gfx::PointF position(25.f, 25.f); 5812 gfx::Size bounds(50, 50); 5813 scoped_ptr<LayerImpl> test_layer = 5814 LayerImpl::Create(host_impl.active_tree(), 12345); 5815 SetLayerPropertiesForTesting(test_layer.get(), 5816 identity_matrix, 5817 identity_matrix, 5818 anchor, 5819 position, 5820 bounds, 5821 false); 5822 5823 test_layer->SetDrawsContent(true); 5824 test_layer->SetTouchEventHandlerRegion(touch_handler_region); 5825 root->AddChild(test_layer.Pass()); 5826 } 5827 5828 LayerImplList render_surface_layer_list; 5829 float device_scale_factor = 3.f; 5830 float page_scale_factor = 5.f; 5831 gfx::Size scaled_bounds_for_root = gfx::ToCeiledSize( 5832 gfx::ScaleSize(root->bounds(), device_scale_factor * page_scale_factor)); 5833 5834 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 5835 root.get(), scaled_bounds_for_root, &render_surface_layer_list); 5836 inputs.device_scale_factor = device_scale_factor; 5837 inputs.page_scale_factor = page_scale_factor; 5838 inputs.page_scale_application_layer = root.get(); 5839 inputs.can_adjust_raster_scales = true; 5840 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 5841 5842 // Sanity check the scenario we just created. 5843 // The visible content rect for test_layer is actually 100x100, even though 5844 // its layout size is 50x50, positioned at 25x25. 5845 LayerImpl* test_layer = root->children()[0]; 5846 ASSERT_EQ(1u, render_surface_layer_list.size()); 5847 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 5848 5849 // Check whether the child layer fits into the root after scaled. 5850 EXPECT_RECT_EQ(gfx::Rect(test_layer->content_bounds()), 5851 test_layer->visible_content_rect()); 5852 5853 // Hit checking for a point outside the layer should return a null pointer 5854 // (the root layer does not draw content, so it will not be tested either). 5855 gfx::PointF test_point(76.f, 76.f); 5856 test_point = 5857 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor); 5858 LayerImpl* result_layer = 5859 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5860 test_point, render_surface_layer_list); 5861 EXPECT_FALSE(result_layer); 5862 5863 // Hit checking for a point inside the layer, but outside the touch handler 5864 // region should return a null pointer. 5865 test_point = gfx::Point(26, 26); 5866 test_point = 5867 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor); 5868 result_layer = 5869 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5870 test_point, render_surface_layer_list); 5871 EXPECT_FALSE(result_layer); 5872 5873 test_point = gfx::Point(34, 34); 5874 test_point = 5875 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor); 5876 result_layer = 5877 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5878 test_point, render_surface_layer_list); 5879 EXPECT_FALSE(result_layer); 5880 5881 test_point = gfx::Point(65, 65); 5882 test_point = 5883 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor); 5884 result_layer = 5885 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5886 test_point, render_surface_layer_list); 5887 EXPECT_FALSE(result_layer); 5888 5889 test_point = gfx::Point(74, 74); 5890 test_point = 5891 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor); 5892 result_layer = 5893 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5894 test_point, render_surface_layer_list); 5895 EXPECT_FALSE(result_layer); 5896 5897 // Hit checking for a point inside the touch event handler region should 5898 // return the root layer. 5899 test_point = gfx::Point(35, 35); 5900 test_point = 5901 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor); 5902 result_layer = 5903 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5904 test_point, render_surface_layer_list); 5905 ASSERT_TRUE(result_layer); 5906 EXPECT_EQ(12345, result_layer->id()); 5907 5908 test_point = gfx::Point(64, 64); 5909 test_point = 5910 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor); 5911 result_layer = 5912 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5913 test_point, render_surface_layer_list); 5914 ASSERT_TRUE(result_layer); 5915 EXPECT_EQ(12345, result_layer->id()); 5916 } 5917 5918 TEST_F(LayerTreeHostCommonTest, 5919 HitCheckingTouchHandlerRegionsForSimpleClippedLayer) { 5920 // Test that hit-checking will only work for the visible portion of a layer, 5921 // and not the entire layer bounds. Here we just test the simple axis-aligned 5922 // case. 5923 gfx::Transform identity_matrix; 5924 gfx::PointF anchor; 5925 5926 FakeImplProxy proxy; 5927 FakeLayerTreeHostImpl host_impl(&proxy); 5928 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); 5929 SetLayerPropertiesForTesting(root.get(), 5930 identity_matrix, 5931 identity_matrix, 5932 anchor, 5933 gfx::PointF(), 5934 gfx::Size(100, 100), 5935 false); 5936 { 5937 scoped_ptr<LayerImpl> clipping_layer = 5938 LayerImpl::Create(host_impl.active_tree(), 123); 5939 // this layer is positioned, and hit testing should correctly know where the 5940 // layer is located. 5941 gfx::PointF position(25.f, 25.f); 5942 gfx::Size bounds(50, 50); 5943 SetLayerPropertiesForTesting(clipping_layer.get(), 5944 identity_matrix, 5945 identity_matrix, 5946 anchor, 5947 position, 5948 bounds, 5949 false); 5950 clipping_layer->SetMasksToBounds(true); 5951 5952 scoped_ptr<LayerImpl> child = 5953 LayerImpl::Create(host_impl.active_tree(), 456); 5954 Region touch_handler_region(gfx::Rect(10, 10, 50, 50)); 5955 position = gfx::PointF(-50.f, -50.f); 5956 bounds = gfx::Size(300, 300); 5957 SetLayerPropertiesForTesting(child.get(), 5958 identity_matrix, 5959 identity_matrix, 5960 anchor, 5961 position, 5962 bounds, 5963 false); 5964 child->SetDrawsContent(true); 5965 child->SetTouchEventHandlerRegion(touch_handler_region); 5966 clipping_layer->AddChild(child.Pass()); 5967 root->AddChild(clipping_layer.Pass()); 5968 } 5969 5970 LayerImplList render_surface_layer_list; 5971 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 5972 root.get(), root->bounds(), &render_surface_layer_list); 5973 inputs.can_adjust_raster_scales = true; 5974 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 5975 5976 // Sanity check the scenario we just created. 5977 ASSERT_EQ(1u, render_surface_layer_list.size()); 5978 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 5979 ASSERT_EQ(456, root->render_surface()->layer_list().at(0)->id()); 5980 5981 // Hit checking for a point outside the layer should return a null pointer. 5982 // Despite the child layer being very large, it should be clipped to the root 5983 // layer's bounds. 5984 gfx::Point test_point(24, 24); 5985 LayerImpl* result_layer = 5986 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5987 test_point, render_surface_layer_list); 5988 EXPECT_FALSE(result_layer); 5989 5990 // Hit checking for a point inside the layer, but outside the touch handler 5991 // region should return a null pointer. 5992 test_point = gfx::Point(35, 35); 5993 result_layer = 5994 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 5995 test_point, render_surface_layer_list); 5996 EXPECT_FALSE(result_layer); 5997 5998 test_point = gfx::Point(74, 74); 5999 result_layer = 6000 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 6001 test_point, render_surface_layer_list); 6002 EXPECT_FALSE(result_layer); 6003 6004 // Hit checking for a point inside the touch event handler region should 6005 // return the root layer. 6006 test_point = gfx::Point(25, 25); 6007 result_layer = 6008 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 6009 test_point, render_surface_layer_list); 6010 ASSERT_TRUE(result_layer); 6011 EXPECT_EQ(456, result_layer->id()); 6012 6013 test_point = gfx::Point(34, 34); 6014 result_layer = 6015 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( 6016 test_point, render_surface_layer_list); 6017 ASSERT_TRUE(result_layer); 6018 EXPECT_EQ(456, result_layer->id()); 6019 } 6020 6021 class NoScaleContentLayer : public ContentLayer { 6022 public: 6023 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) { 6024 return make_scoped_refptr(new NoScaleContentLayer(client)); 6025 } 6026 6027 virtual void CalculateContentsScale(float ideal_contents_scale, 6028 float device_scale_factor, 6029 float page_scale_factor, 6030 bool animating_transform_to_screen, 6031 float* contents_scale_x, 6032 float* contents_scale_y, 6033 gfx::Size* content_bounds) OVERRIDE { 6034 // Skip over the ContentLayer to the base Layer class. 6035 Layer::CalculateContentsScale(ideal_contents_scale, 6036 device_scale_factor, 6037 page_scale_factor, 6038 animating_transform_to_screen, 6039 contents_scale_x, 6040 contents_scale_y, 6041 content_bounds); 6042 } 6043 6044 protected: 6045 explicit NoScaleContentLayer(ContentLayerClient* client) 6046 : ContentLayer(client) {} 6047 virtual ~NoScaleContentLayer() {} 6048 }; 6049 6050 scoped_refptr<NoScaleContentLayer> CreateNoScaleDrawableContentLayer( 6051 ContentLayerClient* delegate) { 6052 scoped_refptr<NoScaleContentLayer> to_return = 6053 NoScaleContentLayer::Create(delegate); 6054 to_return->SetIsDrawable(true); 6055 return to_return; 6056 } 6057 6058 TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) { 6059 // Verify draw and screen space transforms of layers not in a surface. 6060 MockContentLayerClient delegate; 6061 gfx::Transform identity_matrix; 6062 6063 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); 6064 SetLayerPropertiesForTesting(parent.get(), 6065 identity_matrix, 6066 identity_matrix, 6067 gfx::PointF(), 6068 gfx::PointF(), 6069 gfx::Size(100, 100), 6070 true); 6071 6072 scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate); 6073 SetLayerPropertiesForTesting(child.get(), 6074 identity_matrix, 6075 identity_matrix, 6076 gfx::PointF(), 6077 gfx::PointF(2.f, 2.f), 6078 gfx::Size(10, 10), 6079 true); 6080 6081 scoped_refptr<ContentLayer> child_empty = 6082 CreateDrawableContentLayer(&delegate); 6083 SetLayerPropertiesForTesting(child_empty.get(), 6084 identity_matrix, 6085 identity_matrix, 6086 gfx::PointF(), 6087 gfx::PointF(2.f, 2.f), 6088 gfx::Size(), 6089 true); 6090 6091 scoped_refptr<NoScaleContentLayer> child_no_scale = 6092 CreateNoScaleDrawableContentLayer(&delegate); 6093 SetLayerPropertiesForTesting(child_no_scale.get(), 6094 identity_matrix, 6095 identity_matrix, 6096 gfx::PointF(), 6097 gfx::PointF(2.f, 2.f), 6098 gfx::Size(10, 10), 6099 true); 6100 6101 parent->AddChild(child); 6102 parent->AddChild(child_empty); 6103 parent->AddChild(child_no_scale); 6104 6105 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 6106 host->SetRootLayer(parent); 6107 6108 float device_scale_factor = 2.5f; 6109 float page_scale_factor = 1.f; 6110 6111 RenderSurfaceLayerList render_surface_layer_list; 6112 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 6113 parent.get(), parent->bounds(), &render_surface_layer_list); 6114 inputs.device_scale_factor = device_scale_factor; 6115 inputs.page_scale_factor = page_scale_factor; 6116 inputs.can_adjust_raster_scales = true; 6117 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 6118 6119 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent); 6120 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, child); 6121 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 6122 child_empty); 6123 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale); 6124 6125 EXPECT_EQ(1u, render_surface_layer_list.size()); 6126 6127 // Verify parent transforms 6128 gfx::Transform expected_parent_transform; 6129 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform, 6130 parent->screen_space_transform()); 6131 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform, 6132 parent->draw_transform()); 6133 6134 // Verify results of transformed parent rects 6135 gfx::RectF parent_content_bounds(parent->content_bounds()); 6136 6137 gfx::RectF parent_draw_rect = 6138 MathUtil::MapClippedRect(parent->draw_transform(), parent_content_bounds); 6139 gfx::RectF parent_screen_space_rect = MathUtil::MapClippedRect( 6140 parent->screen_space_transform(), parent_content_bounds); 6141 6142 gfx::RectF expected_parent_draw_rect(parent->bounds()); 6143 expected_parent_draw_rect.Scale(device_scale_factor); 6144 EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_draw_rect); 6145 EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_screen_space_rect); 6146 6147 // Verify child and child_empty transforms. They should match. 6148 gfx::Transform expected_child_transform; 6149 expected_child_transform.Translate( 6150 device_scale_factor * child->position().x(), 6151 device_scale_factor * child->position().y()); 6152 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 6153 child->draw_transform()); 6154 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 6155 child->screen_space_transform()); 6156 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 6157 child_empty->draw_transform()); 6158 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 6159 child_empty->screen_space_transform()); 6160 6161 // Verify results of transformed child and child_empty rects. They should 6162 // match. 6163 gfx::RectF child_content_bounds(child->content_bounds()); 6164 6165 gfx::RectF child_draw_rect = 6166 MathUtil::MapClippedRect(child->draw_transform(), child_content_bounds); 6167 gfx::RectF child_screen_space_rect = MathUtil::MapClippedRect( 6168 child->screen_space_transform(), child_content_bounds); 6169 6170 gfx::RectF child_empty_draw_rect = MathUtil::MapClippedRect( 6171 child_empty->draw_transform(), child_content_bounds); 6172 gfx::RectF child_empty_screen_space_rect = MathUtil::MapClippedRect( 6173 child_empty->screen_space_transform(), child_content_bounds); 6174 6175 gfx::RectF expected_child_draw_rect(child->position(), child->bounds()); 6176 expected_child_draw_rect.Scale(device_scale_factor); 6177 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_draw_rect); 6178 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_screen_space_rect); 6179 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_empty_draw_rect); 6180 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_empty_screen_space_rect); 6181 6182 // Verify child_no_scale transforms 6183 gfx::Transform expected_child_no_scale_transform = child->draw_transform(); 6184 // All transforms operate on content rects. The child's content rect 6185 // incorporates device scale, but the child_no_scale does not; add it here. 6186 expected_child_no_scale_transform.Scale(device_scale_factor, 6187 device_scale_factor); 6188 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform, 6189 child_no_scale->draw_transform()); 6190 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform, 6191 child_no_scale->screen_space_transform()); 6192 } 6193 6194 TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) { 6195 // Verify draw and screen space transforms of layers in a surface. 6196 MockContentLayerClient delegate; 6197 gfx::Transform identity_matrix; 6198 6199 gfx::Transform perspective_matrix; 6200 perspective_matrix.ApplyPerspectiveDepth(2.0); 6201 6202 gfx::Transform scale_small_matrix; 6203 scale_small_matrix.Scale(1.0 / 10.0, 1.0 / 12.0); 6204 6205 scoped_refptr<Layer> root = Layer::Create(); 6206 6207 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); 6208 SetLayerPropertiesForTesting(parent.get(), 6209 identity_matrix, 6210 identity_matrix, 6211 gfx::PointF(), 6212 gfx::PointF(), 6213 gfx::Size(100, 100), 6214 true); 6215 6216 scoped_refptr<ContentLayer> perspective_surface = 6217 CreateDrawableContentLayer(&delegate); 6218 SetLayerPropertiesForTesting(perspective_surface.get(), 6219 perspective_matrix * scale_small_matrix, 6220 identity_matrix, 6221 gfx::PointF(), 6222 gfx::PointF(2.f, 2.f), 6223 gfx::Size(10, 10), 6224 true); 6225 6226 scoped_refptr<ContentLayer> scale_surface = 6227 CreateDrawableContentLayer(&delegate); 6228 SetLayerPropertiesForTesting(scale_surface.get(), 6229 scale_small_matrix, 6230 identity_matrix, 6231 gfx::PointF(), 6232 gfx::PointF(2.f, 2.f), 6233 gfx::Size(10, 10), 6234 true); 6235 6236 perspective_surface->SetForceRenderSurface(true); 6237 scale_surface->SetForceRenderSurface(true); 6238 6239 parent->AddChild(perspective_surface); 6240 parent->AddChild(scale_surface); 6241 root->AddChild(parent); 6242 6243 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 6244 host->SetRootLayer(root); 6245 6246 float device_scale_factor = 2.5f; 6247 float page_scale_factor = 3.f; 6248 6249 RenderSurfaceLayerList render_surface_layer_list; 6250 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 6251 root.get(), parent->bounds(), &render_surface_layer_list); 6252 inputs.device_scale_factor = device_scale_factor; 6253 inputs.page_scale_factor = page_scale_factor; 6254 inputs.page_scale_application_layer = root; 6255 inputs.can_adjust_raster_scales = true; 6256 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 6257 6258 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent); 6259 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 6260 perspective_surface); 6261 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 6262 scale_surface); 6263 6264 EXPECT_EQ(3u, render_surface_layer_list.size()); 6265 6266 gfx::Transform expected_parent_draw_transform; 6267 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_draw_transform, 6268 parent->draw_transform()); 6269 6270 // The scaled surface is rendered at its appropriate scale, and drawn 1:1 6271 // into its target. 6272 gfx::Transform expected_scale_surface_draw_transform; 6273 expected_scale_surface_draw_transform.Translate( 6274 device_scale_factor * page_scale_factor * scale_surface->position().x(), 6275 device_scale_factor * page_scale_factor * scale_surface->position().y()); 6276 EXPECT_TRANSFORMATION_MATRIX_EQ( 6277 expected_scale_surface_draw_transform, 6278 scale_surface->render_surface()->draw_transform()); 6279 gfx::Transform expected_scale_surface_layer_draw_transform = 6280 scale_small_matrix; 6281 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scale_surface_layer_draw_transform, 6282 scale_surface->draw_transform()); 6283 6284 // The scale for the perspective surface is not known, so it is rendered 1:1 6285 // with the screen, and then scaled during drawing. 6286 gfx::Transform expected_perspective_surface_draw_transform; 6287 expected_perspective_surface_draw_transform.Translate( 6288 device_scale_factor * page_scale_factor * 6289 perspective_surface->position().x(), 6290 device_scale_factor * page_scale_factor * 6291 perspective_surface->position().y()); 6292 expected_perspective_surface_draw_transform.PreconcatTransform( 6293 perspective_matrix); 6294 expected_perspective_surface_draw_transform.PreconcatTransform( 6295 scale_small_matrix); 6296 gfx::Transform expected_perspective_surface_layer_draw_transform; 6297 EXPECT_TRANSFORMATION_MATRIX_EQ( 6298 expected_perspective_surface_draw_transform, 6299 perspective_surface->render_surface()->draw_transform()); 6300 EXPECT_TRANSFORMATION_MATRIX_EQ( 6301 expected_perspective_surface_layer_draw_transform, 6302 perspective_surface->draw_transform()); 6303 } 6304 6305 TEST_F(LayerTreeHostCommonTest, 6306 LayerTransformsInHighDPIAccurateScaleZeroChildPosition) { 6307 // Verify draw and screen space transforms of layers not in a surface. 6308 MockContentLayerClient delegate; 6309 gfx::Transform identity_matrix; 6310 6311 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); 6312 SetLayerPropertiesForTesting(parent.get(), 6313 identity_matrix, 6314 identity_matrix, 6315 gfx::PointF(), 6316 gfx::PointF(), 6317 gfx::Size(133, 133), 6318 true); 6319 6320 scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate); 6321 SetLayerPropertiesForTesting(child.get(), 6322 identity_matrix, 6323 identity_matrix, 6324 gfx::PointF(), 6325 gfx::PointF(), 6326 gfx::Size(13, 13), 6327 true); 6328 6329 scoped_refptr<NoScaleContentLayer> child_no_scale = 6330 CreateNoScaleDrawableContentLayer(&delegate); 6331 SetLayerPropertiesForTesting(child_no_scale.get(), 6332 identity_matrix, 6333 identity_matrix, 6334 gfx::PointF(), 6335 gfx::PointF(), 6336 gfx::Size(13, 13), 6337 true); 6338 6339 parent->AddChild(child); 6340 parent->AddChild(child_no_scale); 6341 6342 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 6343 host->SetRootLayer(parent); 6344 6345 float device_scale_factor = 1.7f; 6346 float page_scale_factor = 1.f; 6347 6348 RenderSurfaceLayerList render_surface_layer_list; 6349 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 6350 parent.get(), parent->bounds(), &render_surface_layer_list); 6351 inputs.device_scale_factor = device_scale_factor; 6352 inputs.page_scale_factor = page_scale_factor; 6353 inputs.page_scale_application_layer = parent.get(); 6354 inputs.can_adjust_raster_scales = true; 6355 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 6356 6357 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent); 6358 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, child); 6359 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale); 6360 6361 EXPECT_EQ(1u, render_surface_layer_list.size()); 6362 6363 // Verify parent transforms 6364 gfx::Transform expected_parent_transform; 6365 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform, 6366 parent->screen_space_transform()); 6367 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform, 6368 parent->draw_transform()); 6369 6370 // Verify results of transformed parent rects 6371 gfx::RectF parent_content_bounds(parent->content_bounds()); 6372 6373 gfx::RectF parent_draw_rect = 6374 MathUtil::MapClippedRect(parent->draw_transform(), parent_content_bounds); 6375 gfx::RectF parent_screen_space_rect = MathUtil::MapClippedRect( 6376 parent->screen_space_transform(), parent_content_bounds); 6377 6378 gfx::RectF expected_parent_draw_rect(parent->bounds()); 6379 expected_parent_draw_rect.Scale(device_scale_factor); 6380 expected_parent_draw_rect.set_width(ceil(expected_parent_draw_rect.width())); 6381 expected_parent_draw_rect.set_height( 6382 ceil(expected_parent_draw_rect.height())); 6383 EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_draw_rect); 6384 EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_screen_space_rect); 6385 6386 // Verify child transforms 6387 gfx::Transform expected_child_transform; 6388 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 6389 child->draw_transform()); 6390 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 6391 child->screen_space_transform()); 6392 6393 // Verify results of transformed child rects 6394 gfx::RectF child_content_bounds(child->content_bounds()); 6395 6396 gfx::RectF child_draw_rect = 6397 MathUtil::MapClippedRect(child->draw_transform(), child_content_bounds); 6398 gfx::RectF child_screen_space_rect = MathUtil::MapClippedRect( 6399 child->screen_space_transform(), child_content_bounds); 6400 6401 gfx::RectF expected_child_draw_rect(child->bounds()); 6402 expected_child_draw_rect.Scale(device_scale_factor); 6403 expected_child_draw_rect.set_width(ceil(expected_child_draw_rect.width())); 6404 expected_child_draw_rect.set_height(ceil(expected_child_draw_rect.height())); 6405 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_draw_rect); 6406 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_screen_space_rect); 6407 6408 // Verify child_no_scale transforms 6409 gfx::Transform expected_child_no_scale_transform = child->draw_transform(); 6410 // All transforms operate on content rects. The child's content rect 6411 // incorporates device scale, but the child_no_scale does not; add it here. 6412 expected_child_no_scale_transform.Scale(device_scale_factor, 6413 device_scale_factor); 6414 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform, 6415 child_no_scale->draw_transform()); 6416 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform, 6417 child_no_scale->screen_space_transform()); 6418 } 6419 6420 TEST_F(LayerTreeHostCommonTest, ContentsScale) { 6421 MockContentLayerClient delegate; 6422 gfx::Transform identity_matrix; 6423 6424 gfx::Transform parent_scale_matrix; 6425 double initial_parent_scale = 1.75; 6426 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale); 6427 6428 gfx::Transform child_scale_matrix; 6429 double initial_child_scale = 1.25; 6430 child_scale_matrix.Scale(initial_child_scale, initial_child_scale); 6431 6432 scoped_refptr<Layer> root = Layer::Create(); 6433 root->SetBounds(gfx::Size(100, 100)); 6434 6435 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); 6436 SetLayerPropertiesForTesting(parent.get(), 6437 parent_scale_matrix, 6438 identity_matrix, 6439 gfx::PointF(), 6440 gfx::PointF(), 6441 gfx::Size(100, 100), 6442 true); 6443 6444 scoped_refptr<ContentLayer> child_scale = 6445 CreateDrawableContentLayer(&delegate); 6446 SetLayerPropertiesForTesting(child_scale.get(), 6447 child_scale_matrix, 6448 identity_matrix, 6449 gfx::PointF(), 6450 gfx::PointF(2.f, 2.f), 6451 gfx::Size(10, 10), 6452 true); 6453 6454 scoped_refptr<ContentLayer> child_empty = 6455 CreateDrawableContentLayer(&delegate); 6456 SetLayerPropertiesForTesting(child_empty.get(), 6457 child_scale_matrix, 6458 identity_matrix, 6459 gfx::PointF(), 6460 gfx::PointF(2.f, 2.f), 6461 gfx::Size(), 6462 true); 6463 6464 scoped_refptr<NoScaleContentLayer> child_no_scale = 6465 CreateNoScaleDrawableContentLayer(&delegate); 6466 SetLayerPropertiesForTesting(child_no_scale.get(), 6467 child_scale_matrix, 6468 identity_matrix, 6469 gfx::PointF(), 6470 gfx::PointF(12.f, 12.f), 6471 gfx::Size(10, 10), 6472 true); 6473 6474 root->AddChild(parent); 6475 6476 parent->AddChild(child_scale); 6477 parent->AddChild(child_empty); 6478 parent->AddChild(child_no_scale); 6479 6480 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 6481 host->SetRootLayer(root); 6482 6483 float device_scale_factor = 2.5f; 6484 float page_scale_factor = 1.f; 6485 6486 { 6487 RenderSurfaceLayerList render_surface_layer_list; 6488 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 6489 root.get(), root->bounds(), &render_surface_layer_list); 6490 inputs.device_scale_factor = device_scale_factor; 6491 inputs.page_scale_factor = page_scale_factor; 6492 inputs.page_scale_application_layer = root.get(); 6493 inputs.can_adjust_raster_scales = true; 6494 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 6495 6496 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 6497 initial_parent_scale, parent); 6498 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 6499 initial_parent_scale * initial_child_scale, 6500 child_scale); 6501 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 6502 initial_parent_scale * initial_child_scale, 6503 child_empty); 6504 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale); 6505 6506 // The parent is scaled up and shouldn't need to scale during draw. The 6507 // child that can scale its contents should also not need to scale during 6508 // draw. This shouldn't change if the child has empty bounds. The other 6509 // children should. 6510 EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().getDouble(0, 0)); 6511 EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().getDouble(1, 1)); 6512 EXPECT_FLOAT_EQ(1.0, 6513 child_scale->draw_transform().matrix().getDouble(0, 0)); 6514 EXPECT_FLOAT_EQ(1.0, 6515 child_scale->draw_transform().matrix().getDouble(1, 1)); 6516 EXPECT_FLOAT_EQ(1.0, 6517 child_empty->draw_transform().matrix().getDouble(0, 0)); 6518 EXPECT_FLOAT_EQ(1.0, 6519 child_empty->draw_transform().matrix().getDouble(1, 1)); 6520 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor * 6521 initial_parent_scale * initial_child_scale, 6522 child_no_scale->draw_transform().matrix().getDouble(0, 0)); 6523 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor * 6524 initial_parent_scale * initial_child_scale, 6525 child_no_scale->draw_transform().matrix().getDouble(1, 1)); 6526 } 6527 6528 // If the device_scale_factor or page_scale_factor changes, then it should be 6529 // updated using the initial transform as the raster scale. 6530 device_scale_factor = 2.25f; 6531 page_scale_factor = 1.25f; 6532 6533 { 6534 RenderSurfaceLayerList render_surface_layer_list; 6535 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 6536 root.get(), root->bounds(), &render_surface_layer_list); 6537 inputs.device_scale_factor = device_scale_factor; 6538 inputs.page_scale_factor = page_scale_factor; 6539 inputs.page_scale_application_layer = root.get(); 6540 inputs.can_adjust_raster_scales = true; 6541 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 6542 6543 EXPECT_CONTENTS_SCALE_EQ( 6544 device_scale_factor * page_scale_factor * initial_parent_scale, parent); 6545 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 6546 initial_parent_scale * initial_child_scale, 6547 child_scale); 6548 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 6549 initial_parent_scale * initial_child_scale, 6550 child_empty); 6551 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale); 6552 } 6553 6554 // If the transform changes, we expect the raster scale to be reset to 1.0. 6555 double second_child_scale = 1.75; 6556 child_scale_matrix.Scale(second_child_scale / initial_child_scale, 6557 second_child_scale / initial_child_scale); 6558 child_scale->SetTransform(child_scale_matrix); 6559 child_empty->SetTransform(child_scale_matrix); 6560 6561 { 6562 RenderSurfaceLayerList render_surface_layer_list; 6563 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 6564 root.get(), root->bounds(), &render_surface_layer_list); 6565 inputs.device_scale_factor = device_scale_factor; 6566 inputs.page_scale_factor = page_scale_factor; 6567 inputs.page_scale_application_layer = root.get(); 6568 inputs.can_adjust_raster_scales = true; 6569 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 6570 6571 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 6572 initial_parent_scale, 6573 parent); 6574 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 6575 child_scale); 6576 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 6577 child_empty); 6578 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale); 6579 } 6580 6581 // If the device_scale_factor or page_scale_factor changes, then it should be 6582 // updated, but still using 1.0 as the raster scale. 6583 device_scale_factor = 2.75f; 6584 page_scale_factor = 1.75f; 6585 6586 { 6587 RenderSurfaceLayerList render_surface_layer_list; 6588 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 6589 root.get(), root->bounds(), &render_surface_layer_list); 6590 inputs.device_scale_factor = device_scale_factor; 6591 inputs.page_scale_factor = page_scale_factor; 6592 inputs.page_scale_application_layer = root.get(); 6593 inputs.can_adjust_raster_scales = true; 6594 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 6595 6596 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 6597 initial_parent_scale, 6598 parent); 6599 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 6600 child_scale); 6601 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 6602 child_empty); 6603 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale); 6604 } 6605 } 6606 6607 TEST_F(LayerTreeHostCommonTest, 6608 ContentsScale_LayerTransformsDontAffectContentsScale) { 6609 MockContentLayerClient delegate; 6610 gfx::Transform identity_matrix; 6611 6612 gfx::Transform parent_scale_matrix; 6613 double initial_parent_scale = 1.75; 6614 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale); 6615 6616 gfx::Transform child_scale_matrix; 6617 double initial_child_scale = 1.25; 6618 child_scale_matrix.Scale(initial_child_scale, initial_child_scale); 6619 6620 scoped_refptr<Layer> root = Layer::Create(); 6621 root->SetBounds(gfx::Size(100, 100)); 6622 6623 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); 6624 SetLayerPropertiesForTesting(parent.get(), 6625 parent_scale_matrix, 6626 identity_matrix, 6627 gfx::PointF(), 6628 gfx::PointF(), 6629 gfx::Size(100, 100), 6630 true); 6631 6632 scoped_refptr<ContentLayer> child_scale = 6633 CreateDrawableContentLayer(&delegate); 6634 SetLayerPropertiesForTesting(child_scale.get(), 6635 child_scale_matrix, 6636 identity_matrix, 6637 gfx::PointF(), 6638 gfx::PointF(2.f, 2.f), 6639 gfx::Size(10, 10), 6640 true); 6641 6642 scoped_refptr<ContentLayer> child_empty = 6643 CreateDrawableContentLayer(&delegate); 6644 SetLayerPropertiesForTesting(child_empty.get(), 6645 child_scale_matrix, 6646 identity_matrix, 6647 gfx::PointF(), 6648 gfx::PointF(2.f, 2.f), 6649 gfx::Size(), 6650 true); 6651 6652 scoped_refptr<NoScaleContentLayer> child_no_scale = 6653 CreateNoScaleDrawableContentLayer(&delegate); 6654 SetLayerPropertiesForTesting(child_no_scale.get(), 6655 child_scale_matrix, 6656 identity_matrix, 6657 gfx::PointF(), 6658 gfx::PointF(12.f, 12.f), 6659 gfx::Size(10, 10), 6660 true); 6661 6662 root->AddChild(parent); 6663 6664 parent->AddChild(child_scale); 6665 parent->AddChild(child_empty); 6666 parent->AddChild(child_no_scale); 6667 6668 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 6669 host->SetRootLayer(root); 6670 6671 RenderSurfaceLayerList render_surface_layer_list; 6672 6673 float device_scale_factor = 2.5f; 6674 float page_scale_factor = 1.f; 6675 6676 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 6677 root.get(), root->bounds(), &render_surface_layer_list); 6678 inputs.device_scale_factor = device_scale_factor; 6679 inputs.page_scale_factor = page_scale_factor; 6680 inputs.page_scale_application_layer = root.get(), 6681 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 6682 6683 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent); 6684 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 6685 child_scale); 6686 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 6687 child_empty); 6688 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale); 6689 6690 // Since the transform scale does not affect contents scale, it should affect 6691 // the draw transform instead. 6692 EXPECT_FLOAT_EQ(initial_parent_scale, 6693 parent->draw_transform().matrix().getDouble(0, 0)); 6694 EXPECT_FLOAT_EQ(initial_parent_scale, 6695 parent->draw_transform().matrix().getDouble(1, 1)); 6696 EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale, 6697 child_scale->draw_transform().matrix().getDouble(0, 0)); 6698 EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale, 6699 child_scale->draw_transform().matrix().getDouble(1, 1)); 6700 EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale, 6701 child_empty->draw_transform().matrix().getDouble(0, 0)); 6702 EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale, 6703 child_empty->draw_transform().matrix().getDouble(1, 1)); 6704 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor * 6705 initial_parent_scale * initial_child_scale, 6706 child_no_scale->draw_transform().matrix().getDouble(0, 0)); 6707 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor * 6708 initial_parent_scale * initial_child_scale, 6709 child_no_scale->draw_transform().matrix().getDouble(1, 1)); 6710 } 6711 6712 TEST_F(LayerTreeHostCommonTest, SmallContentsScale) { 6713 MockContentLayerClient delegate; 6714 gfx::Transform identity_matrix; 6715 6716 gfx::Transform parent_scale_matrix; 6717 double initial_parent_scale = 1.75; 6718 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale); 6719 6720 gfx::Transform child_scale_matrix; 6721 double initial_child_scale = 0.25; 6722 child_scale_matrix.Scale(initial_child_scale, initial_child_scale); 6723 6724 scoped_refptr<Layer> root = Layer::Create(); 6725 root->SetBounds(gfx::Size(100, 100)); 6726 6727 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); 6728 SetLayerPropertiesForTesting(parent.get(), 6729 parent_scale_matrix, 6730 identity_matrix, 6731 gfx::PointF(), 6732 gfx::PointF(), 6733 gfx::Size(100, 100), 6734 true); 6735 6736 scoped_refptr<ContentLayer> child_scale = 6737 CreateDrawableContentLayer(&delegate); 6738 SetLayerPropertiesForTesting(child_scale.get(), 6739 child_scale_matrix, 6740 identity_matrix, 6741 gfx::PointF(), 6742 gfx::PointF(2.f, 2.f), 6743 gfx::Size(10, 10), 6744 true); 6745 6746 root->AddChild(parent); 6747 6748 parent->AddChild(child_scale); 6749 6750 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 6751 host->SetRootLayer(root); 6752 6753 float device_scale_factor = 2.5f; 6754 float page_scale_factor = 0.01f; 6755 6756 { 6757 RenderSurfaceLayerList render_surface_layer_list; 6758 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 6759 root.get(), root->bounds(), &render_surface_layer_list); 6760 inputs.device_scale_factor = device_scale_factor; 6761 inputs.page_scale_factor = page_scale_factor; 6762 inputs.page_scale_application_layer = root.get(); 6763 inputs.can_adjust_raster_scales = true; 6764 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 6765 6766 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 6767 initial_parent_scale, 6768 parent); 6769 // The child's scale is < 1, so we should not save and use that scale 6770 // factor. 6771 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 1, 6772 child_scale); 6773 } 6774 6775 // When chilld's total scale becomes >= 1, we should save and use that scale 6776 // factor. 6777 child_scale_matrix.MakeIdentity(); 6778 double final_child_scale = 0.75; 6779 child_scale_matrix.Scale(final_child_scale, final_child_scale); 6780 child_scale->SetTransform(child_scale_matrix); 6781 6782 { 6783 RenderSurfaceLayerList render_surface_layer_list; 6784 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 6785 root.get(), root->bounds(), &render_surface_layer_list); 6786 inputs.device_scale_factor = device_scale_factor; 6787 inputs.page_scale_factor = page_scale_factor; 6788 inputs.page_scale_application_layer = root.get(); 6789 inputs.can_adjust_raster_scales = true; 6790 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 6791 6792 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 6793 initial_parent_scale, 6794 parent); 6795 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 6796 initial_parent_scale * final_child_scale, 6797 child_scale); 6798 } 6799 } 6800 6801 TEST_F(LayerTreeHostCommonTest, ContentsScaleForSurfaces) { 6802 MockContentLayerClient delegate; 6803 gfx::Transform identity_matrix; 6804 6805 gfx::Transform parent_scale_matrix; 6806 double initial_parent_scale = 2.0; 6807 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale); 6808 6809 gfx::Transform child_scale_matrix; 6810 double initial_child_scale = 3.0; 6811 child_scale_matrix.Scale(initial_child_scale, initial_child_scale); 6812 6813 scoped_refptr<Layer> root = Layer::Create(); 6814 root->SetBounds(gfx::Size(100, 100)); 6815 6816 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); 6817 SetLayerPropertiesForTesting(parent.get(), 6818 parent_scale_matrix, 6819 identity_matrix, 6820 gfx::PointF(), 6821 gfx::PointF(), 6822 gfx::Size(100, 100), 6823 true); 6824 6825 scoped_refptr<ContentLayer> surface_scale = 6826 CreateDrawableContentLayer(&delegate); 6827 SetLayerPropertiesForTesting(surface_scale.get(), 6828 child_scale_matrix, 6829 identity_matrix, 6830 gfx::PointF(), 6831 gfx::PointF(2.f, 2.f), 6832 gfx::Size(10, 10), 6833 true); 6834 6835 scoped_refptr<ContentLayer> surface_scale_child_scale = 6836 CreateDrawableContentLayer(&delegate); 6837 SetLayerPropertiesForTesting(surface_scale_child_scale.get(), 6838 child_scale_matrix, 6839 identity_matrix, 6840 gfx::PointF(), 6841 gfx::PointF(), 6842 gfx::Size(10, 10), 6843 true); 6844 6845 scoped_refptr<NoScaleContentLayer> surface_scale_child_no_scale = 6846 CreateNoScaleDrawableContentLayer(&delegate); 6847 SetLayerPropertiesForTesting(surface_scale_child_no_scale.get(), 6848 child_scale_matrix, 6849 identity_matrix, 6850 gfx::PointF(), 6851 gfx::PointF(), 6852 gfx::Size(10, 10), 6853 true); 6854 6855 scoped_refptr<NoScaleContentLayer> surface_no_scale = 6856 CreateNoScaleDrawableContentLayer(&delegate); 6857 SetLayerPropertiesForTesting(surface_no_scale.get(), 6858 child_scale_matrix, 6859 identity_matrix, 6860 gfx::PointF(), 6861 gfx::PointF(12.f, 12.f), 6862 gfx::Size(10, 10), 6863 true); 6864 6865 scoped_refptr<ContentLayer> surface_no_scale_child_scale = 6866 CreateDrawableContentLayer(&delegate); 6867 SetLayerPropertiesForTesting(surface_no_scale_child_scale.get(), 6868 child_scale_matrix, 6869 identity_matrix, 6870 gfx::PointF(), 6871 gfx::PointF(), 6872 gfx::Size(10, 10), 6873 true); 6874 6875 scoped_refptr<NoScaleContentLayer> surface_no_scale_child_no_scale = 6876 CreateNoScaleDrawableContentLayer(&delegate); 6877 SetLayerPropertiesForTesting(surface_no_scale_child_no_scale.get(), 6878 child_scale_matrix, 6879 identity_matrix, 6880 gfx::PointF(), 6881 gfx::PointF(), 6882 gfx::Size(10, 10), 6883 true); 6884 6885 root->AddChild(parent); 6886 6887 parent->AddChild(surface_scale); 6888 parent->AddChild(surface_no_scale); 6889 6890 surface_scale->SetForceRenderSurface(true); 6891 surface_scale->AddChild(surface_scale_child_scale); 6892 surface_scale->AddChild(surface_scale_child_no_scale); 6893 6894 surface_no_scale->SetForceRenderSurface(true); 6895 surface_no_scale->AddChild(surface_no_scale_child_scale); 6896 surface_no_scale->AddChild(surface_no_scale_child_no_scale); 6897 6898 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 6899 host->SetRootLayer(root); 6900 6901 double device_scale_factor = 5; 6902 double page_scale_factor = 7; 6903 6904 RenderSurfaceLayerList render_surface_layer_list; 6905 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 6906 root.get(), root->bounds(), &render_surface_layer_list); 6907 inputs.device_scale_factor = device_scale_factor; 6908 inputs.page_scale_factor = page_scale_factor; 6909 inputs.page_scale_application_layer = root.get(); 6910 inputs.can_adjust_raster_scales = true; 6911 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 6912 6913 EXPECT_CONTENTS_SCALE_EQ( 6914 device_scale_factor * page_scale_factor * initial_parent_scale, parent); 6915 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 6916 initial_parent_scale * initial_child_scale, 6917 surface_scale); 6918 EXPECT_CONTENTS_SCALE_EQ(1, surface_no_scale); 6919 EXPECT_CONTENTS_SCALE_EQ( 6920 device_scale_factor * page_scale_factor * initial_parent_scale * 6921 initial_child_scale * initial_child_scale, 6922 surface_scale_child_scale); 6923 EXPECT_CONTENTS_SCALE_EQ(1, surface_scale_child_no_scale); 6924 EXPECT_CONTENTS_SCALE_EQ( 6925 device_scale_factor * page_scale_factor * initial_parent_scale * 6926 initial_child_scale * initial_child_scale, 6927 surface_no_scale_child_scale); 6928 EXPECT_CONTENTS_SCALE_EQ(1, surface_no_scale_child_no_scale); 6929 6930 // The parent is scaled up and shouldn't need to scale during draw. 6931 EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().getDouble(0, 0)); 6932 EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().getDouble(1, 1)); 6933 6934 // RenderSurfaces should always be 1:1 with their target. 6935 EXPECT_FLOAT_EQ( 6936 1.0, 6937 surface_scale->render_surface()->draw_transform().matrix().getDouble(0, 6938 0)); 6939 EXPECT_FLOAT_EQ( 6940 1.0, 6941 surface_scale->render_surface()->draw_transform().matrix().getDouble(1, 6942 1)); 6943 6944 // The surface_scale can apply contents scale so the layer shouldn't need to 6945 // scale during draw. 6946 EXPECT_FLOAT_EQ(1.0, 6947 surface_scale->draw_transform().matrix().getDouble(0, 0)); 6948 EXPECT_FLOAT_EQ(1.0, 6949 surface_scale->draw_transform().matrix().getDouble(1, 1)); 6950 6951 // The surface_scale_child_scale can apply contents scale so it shouldn't need 6952 // to scale during draw. 6953 EXPECT_FLOAT_EQ( 6954 1.0, 6955 surface_scale_child_scale->draw_transform().matrix().getDouble(0, 0)); 6956 EXPECT_FLOAT_EQ( 6957 1.0, 6958 surface_scale_child_scale->draw_transform().matrix().getDouble(1, 1)); 6959 6960 // The surface_scale_child_no_scale can not apply contents scale, so it needs 6961 // to be scaled during draw. 6962 EXPECT_FLOAT_EQ( 6963 device_scale_factor * page_scale_factor * initial_parent_scale * 6964 initial_child_scale * initial_child_scale, 6965 surface_scale_child_no_scale->draw_transform().matrix().getDouble(0, 0)); 6966 EXPECT_FLOAT_EQ( 6967 device_scale_factor * page_scale_factor * initial_parent_scale * 6968 initial_child_scale * initial_child_scale, 6969 surface_scale_child_no_scale->draw_transform().matrix().getDouble(1, 1)); 6970 6971 // RenderSurfaces should always be 1:1 with their target. 6972 EXPECT_FLOAT_EQ( 6973 1.0, 6974 surface_no_scale->render_surface()->draw_transform().matrix().getDouble( 6975 0, 0)); 6976 EXPECT_FLOAT_EQ( 6977 1.0, 6978 surface_no_scale->render_surface()->draw_transform().matrix().getDouble( 6979 1, 1)); 6980 6981 // The surface_no_scale layer can not apply contents scale, so it needs to be 6982 // scaled during draw. 6983 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor * 6984 initial_parent_scale * initial_child_scale, 6985 surface_no_scale->draw_transform().matrix().getDouble(0, 0)); 6986 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor * 6987 initial_parent_scale * initial_child_scale, 6988 surface_no_scale->draw_transform().matrix().getDouble(1, 1)); 6989 6990 // The surface_scale_child_scale can apply contents scale so it shouldn't need 6991 // to scale during draw. 6992 EXPECT_FLOAT_EQ( 6993 1.0, 6994 surface_no_scale_child_scale->draw_transform().matrix().getDouble(0, 0)); 6995 EXPECT_FLOAT_EQ( 6996 1.0, 6997 surface_no_scale_child_scale->draw_transform().matrix().getDouble(1, 1)); 6998 6999 // The surface_scale_child_no_scale can not apply contents scale, so it needs 7000 // to be scaled during draw. 7001 EXPECT_FLOAT_EQ( 7002 device_scale_factor * page_scale_factor * initial_parent_scale * 7003 initial_child_scale * initial_child_scale, 7004 surface_no_scale_child_no_scale->draw_transform().matrix().getDouble(0, 7005 0)); 7006 EXPECT_FLOAT_EQ( 7007 device_scale_factor * page_scale_factor * initial_parent_scale * 7008 initial_child_scale * initial_child_scale, 7009 surface_no_scale_child_no_scale->draw_transform().matrix().getDouble(1, 7010 1)); 7011 } 7012 7013 TEST_F(LayerTreeHostCommonTest, 7014 ContentsScaleForSurfaces_LayerTransformsDontAffectContentsScale) { 7015 MockContentLayerClient delegate; 7016 gfx::Transform identity_matrix; 7017 7018 gfx::Transform parent_scale_matrix; 7019 double initial_parent_scale = 2.0; 7020 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale); 7021 7022 gfx::Transform child_scale_matrix; 7023 double initial_child_scale = 3.0; 7024 child_scale_matrix.Scale(initial_child_scale, initial_child_scale); 7025 7026 scoped_refptr<Layer> root = Layer::Create(); 7027 root->SetBounds(gfx::Size(100, 100)); 7028 7029 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); 7030 SetLayerPropertiesForTesting(parent.get(), 7031 parent_scale_matrix, 7032 identity_matrix, 7033 gfx::PointF(), 7034 gfx::PointF(), 7035 gfx::Size(100, 100), 7036 true); 7037 7038 scoped_refptr<ContentLayer> surface_scale = 7039 CreateDrawableContentLayer(&delegate); 7040 SetLayerPropertiesForTesting(surface_scale.get(), 7041 child_scale_matrix, 7042 identity_matrix, 7043 gfx::PointF(), 7044 gfx::PointF(2.f, 2.f), 7045 gfx::Size(10, 10), 7046 true); 7047 7048 scoped_refptr<ContentLayer> surface_scale_child_scale = 7049 CreateDrawableContentLayer(&delegate); 7050 SetLayerPropertiesForTesting(surface_scale_child_scale.get(), 7051 child_scale_matrix, 7052 identity_matrix, 7053 gfx::PointF(), 7054 gfx::PointF(), 7055 gfx::Size(10, 10), 7056 true); 7057 7058 scoped_refptr<NoScaleContentLayer> surface_scale_child_no_scale = 7059 CreateNoScaleDrawableContentLayer(&delegate); 7060 SetLayerPropertiesForTesting(surface_scale_child_no_scale.get(), 7061 child_scale_matrix, 7062 identity_matrix, 7063 gfx::PointF(), 7064 gfx::PointF(), 7065 gfx::Size(10, 10), 7066 true); 7067 7068 scoped_refptr<NoScaleContentLayer> surface_no_scale = 7069 CreateNoScaleDrawableContentLayer(&delegate); 7070 SetLayerPropertiesForTesting(surface_no_scale.get(), 7071 child_scale_matrix, 7072 identity_matrix, 7073 gfx::PointF(), 7074 gfx::PointF(12.f, 12.f), 7075 gfx::Size(10, 10), 7076 true); 7077 7078 scoped_refptr<ContentLayer> surface_no_scale_child_scale = 7079 CreateDrawableContentLayer(&delegate); 7080 SetLayerPropertiesForTesting(surface_no_scale_child_scale.get(), 7081 child_scale_matrix, 7082 identity_matrix, 7083 gfx::PointF(), 7084 gfx::PointF(), 7085 gfx::Size(10, 10), 7086 true); 7087 7088 scoped_refptr<NoScaleContentLayer> surface_no_scale_child_no_scale = 7089 CreateNoScaleDrawableContentLayer(&delegate); 7090 SetLayerPropertiesForTesting(surface_no_scale_child_no_scale.get(), 7091 child_scale_matrix, 7092 identity_matrix, 7093 gfx::PointF(), 7094 gfx::PointF(), 7095 gfx::Size(10, 10), 7096 true); 7097 7098 root->AddChild(parent); 7099 7100 parent->AddChild(surface_scale); 7101 parent->AddChild(surface_no_scale); 7102 7103 surface_scale->SetForceRenderSurface(true); 7104 surface_scale->AddChild(surface_scale_child_scale); 7105 surface_scale->AddChild(surface_scale_child_no_scale); 7106 7107 surface_no_scale->SetForceRenderSurface(true); 7108 surface_no_scale->AddChild(surface_no_scale_child_scale); 7109 surface_no_scale->AddChild(surface_no_scale_child_no_scale); 7110 7111 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 7112 host->SetRootLayer(root); 7113 7114 RenderSurfaceLayerList render_surface_layer_list; 7115 7116 double device_scale_factor = 5.0; 7117 double page_scale_factor = 7.0; 7118 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 7119 root.get(), root->bounds(), &render_surface_layer_list); 7120 inputs.device_scale_factor = device_scale_factor; 7121 inputs.page_scale_factor = page_scale_factor; 7122 inputs.page_scale_application_layer = root.get(); 7123 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 7124 7125 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 7126 parent); 7127 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 7128 surface_scale); 7129 EXPECT_CONTENTS_SCALE_EQ(1.f, surface_no_scale); 7130 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 7131 surface_scale_child_scale); 7132 EXPECT_CONTENTS_SCALE_EQ(1.f, surface_scale_child_no_scale); 7133 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, 7134 surface_no_scale_child_scale); 7135 EXPECT_CONTENTS_SCALE_EQ(1.f, surface_no_scale_child_no_scale); 7136 7137 // The parent is scaled up during draw, since its contents are not scaled by 7138 // the transform hierarchy. 7139 EXPECT_FLOAT_EQ(initial_parent_scale, 7140 parent->draw_transform().matrix().getDouble(0, 0)); 7141 EXPECT_FLOAT_EQ(initial_parent_scale, 7142 parent->draw_transform().matrix().getDouble(1, 1)); 7143 7144 // The child surface is scaled up during draw since its subtree is not scaled 7145 // by the transform hierarchy. 7146 EXPECT_FLOAT_EQ( 7147 initial_parent_scale * initial_child_scale, 7148 surface_scale->render_surface()->draw_transform().matrix().getDouble(0, 7149 0)); 7150 EXPECT_FLOAT_EQ( 7151 initial_parent_scale * initial_child_scale, 7152 surface_scale->render_surface()->draw_transform().matrix().getDouble(1, 7153 1)); 7154 7155 // The surface_scale's RenderSurface is scaled during draw, so the layer does 7156 // not need to be scaled when drawing into its surface. 7157 EXPECT_FLOAT_EQ(1.0, 7158 surface_scale->draw_transform().matrix().getDouble(0, 0)); 7159 EXPECT_FLOAT_EQ(1.0, 7160 surface_scale->draw_transform().matrix().getDouble(1, 1)); 7161 7162 // The surface_scale_child_scale is scaled when drawing into its surface, 7163 // since its content bounds are not scaled by the transform hierarchy. 7164 EXPECT_FLOAT_EQ( 7165 initial_child_scale, 7166 surface_scale_child_scale->draw_transform().matrix().getDouble(0, 0)); 7167 EXPECT_FLOAT_EQ( 7168 initial_child_scale, 7169 surface_scale_child_scale->draw_transform().matrix().getDouble(1, 1)); 7170 7171 // The surface_scale_child_no_scale has a fixed contents scale of 1, so it 7172 // needs to be scaled by the device and page scale factors, along with the 7173 // transform hierarchy. 7174 EXPECT_FLOAT_EQ( 7175 device_scale_factor * page_scale_factor * initial_child_scale, 7176 surface_scale_child_no_scale->draw_transform().matrix().getDouble(0, 0)); 7177 EXPECT_FLOAT_EQ( 7178 device_scale_factor * page_scale_factor * initial_child_scale, 7179 surface_scale_child_no_scale->draw_transform().matrix().getDouble(1, 1)); 7180 7181 // The child surface is scaled up during draw since its subtree is not scaled 7182 // by the transform hierarchy. 7183 EXPECT_FLOAT_EQ( 7184 initial_parent_scale * initial_child_scale, 7185 surface_no_scale->render_surface()->draw_transform().matrix().getDouble( 7186 0, 0)); 7187 EXPECT_FLOAT_EQ( 7188 initial_parent_scale * initial_child_scale, 7189 surface_no_scale->render_surface()->draw_transform().matrix().getDouble( 7190 1, 1)); 7191 7192 // The surface_no_scale layer has a fixed contents scale of 1, so it needs to 7193 // be scaled by the device and page scale factors. Its surface is already 7194 // scaled by the transform hierarchy so those don't need to scale the layer's 7195 // drawing. 7196 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor, 7197 surface_no_scale->draw_transform().matrix().getDouble(0, 0)); 7198 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor, 7199 surface_no_scale->draw_transform().matrix().getDouble(1, 1)); 7200 7201 // The surface_no_scale_child_scale has its contents scaled by the page and 7202 // device scale factors, but needs to be scaled by the transform hierarchy 7203 // when drawing. 7204 EXPECT_FLOAT_EQ( 7205 initial_child_scale, 7206 surface_no_scale_child_scale->draw_transform().matrix().getDouble(0, 0)); 7207 EXPECT_FLOAT_EQ( 7208 initial_child_scale, 7209 surface_no_scale_child_scale->draw_transform().matrix().getDouble(1, 1)); 7210 7211 // The surface_no_scale_child_no_scale has a fixed contents scale of 1, so it 7212 // needs to be scaled by the device and page scale factors. It also needs to 7213 // be scaled by any transform heirarchy below its target surface. 7214 EXPECT_FLOAT_EQ( 7215 device_scale_factor * page_scale_factor * initial_child_scale, 7216 surface_no_scale_child_no_scale->draw_transform().matrix().getDouble(0, 7217 0)); 7218 EXPECT_FLOAT_EQ( 7219 device_scale_factor * page_scale_factor * initial_child_scale, 7220 surface_no_scale_child_no_scale->draw_transform().matrix().getDouble(1, 7221 1)); 7222 } 7223 7224 TEST_F(LayerTreeHostCommonTest, ContentsScaleForAnimatingLayer) { 7225 MockContentLayerClient delegate; 7226 gfx::Transform identity_matrix; 7227 7228 gfx::Transform parent_scale_matrix; 7229 double initial_parent_scale = 1.75; 7230 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale); 7231 7232 gfx::Transform child_scale_matrix; 7233 double initial_child_scale = 1.25; 7234 child_scale_matrix.Scale(initial_child_scale, initial_child_scale); 7235 7236 scoped_refptr<Layer> root = Layer::Create(); 7237 root->SetBounds(gfx::Size(100, 100)); 7238 7239 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); 7240 SetLayerPropertiesForTesting(parent.get(), 7241 parent_scale_matrix, 7242 identity_matrix, 7243 gfx::PointF(), 7244 gfx::PointF(), 7245 gfx::Size(100, 100), 7246 true); 7247 7248 scoped_refptr<ContentLayer> child_scale = 7249 CreateDrawableContentLayer(&delegate); 7250 SetLayerPropertiesForTesting(child_scale.get(), 7251 child_scale_matrix, 7252 identity_matrix, 7253 gfx::PointF(), 7254 gfx::PointF(2.f, 2.f), 7255 gfx::Size(10, 10), 7256 true); 7257 7258 root->AddChild(parent); 7259 7260 parent->AddChild(child_scale); 7261 7262 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 7263 host->SetRootLayer(root); 7264 7265 // Now put an animating transform on child. 7266 int animation_id = AddAnimatedTransformToController( 7267 child_scale->layer_animation_controller(), 10.0, 30, 0); 7268 7269 { 7270 RenderSurfaceLayerList render_surface_layer_list; 7271 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 7272 root.get(), root->bounds(), &render_surface_layer_list); 7273 inputs.can_adjust_raster_scales = true; 7274 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 7275 7276 EXPECT_CONTENTS_SCALE_EQ(initial_parent_scale, parent); 7277 // The layers with animating transforms should not compute a contents scale 7278 // other than 1 until they finish animating. 7279 EXPECT_CONTENTS_SCALE_EQ(1, child_scale); 7280 } 7281 7282 // Remove the animation, now it can save a raster scale. 7283 child_scale->layer_animation_controller()->RemoveAnimation(animation_id); 7284 7285 { 7286 RenderSurfaceLayerList render_surface_layer_list; 7287 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 7288 root.get(), root->bounds(), &render_surface_layer_list); 7289 inputs.can_adjust_raster_scales = true; 7290 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 7291 7292 EXPECT_CONTENTS_SCALE_EQ(initial_parent_scale, parent); 7293 // The layers with animating transforms should not compute a contents scale 7294 // other than 1 until they finish animating. 7295 EXPECT_CONTENTS_SCALE_EQ(initial_parent_scale * initial_child_scale, 7296 child_scale); 7297 } 7298 } 7299 7300 TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { 7301 MockContentLayerClient delegate; 7302 gfx::Transform identity_matrix; 7303 7304 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); 7305 SetLayerPropertiesForTesting(parent.get(), 7306 identity_matrix, 7307 identity_matrix, 7308 gfx::PointF(), 7309 gfx::PointF(), 7310 gfx::Size(30, 30), 7311 true); 7312 7313 scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate); 7314 SetLayerPropertiesForTesting(child.get(), 7315 identity_matrix, 7316 identity_matrix, 7317 gfx::PointF(), 7318 gfx::PointF(2.f, 2.f), 7319 gfx::Size(10, 10), 7320 true); 7321 7322 gfx::Transform replica_transform; 7323 replica_transform.Scale(1.0, -1.0); 7324 scoped_refptr<ContentLayer> replica = CreateDrawableContentLayer(&delegate); 7325 SetLayerPropertiesForTesting(replica.get(), 7326 replica_transform, 7327 identity_matrix, 7328 gfx::PointF(), 7329 gfx::PointF(2.f, 2.f), 7330 gfx::Size(10, 10), 7331 true); 7332 7333 // This layer should end up in the same surface as child, with the same draw 7334 // and screen space transforms. 7335 scoped_refptr<ContentLayer> duplicate_child_non_owner = 7336 CreateDrawableContentLayer(&delegate); 7337 SetLayerPropertiesForTesting(duplicate_child_non_owner.get(), 7338 identity_matrix, 7339 identity_matrix, 7340 gfx::PointF(), 7341 gfx::PointF(), 7342 gfx::Size(10, 10), 7343 true); 7344 7345 parent->AddChild(child); 7346 child->AddChild(duplicate_child_non_owner); 7347 child->SetReplicaLayer(replica.get()); 7348 7349 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 7350 host->SetRootLayer(parent); 7351 7352 RenderSurfaceLayerList render_surface_layer_list; 7353 7354 float device_scale_factor = 1.5f; 7355 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 7356 parent.get(), parent->bounds(), &render_surface_layer_list); 7357 inputs.device_scale_factor = device_scale_factor; 7358 inputs.can_adjust_raster_scales = true; 7359 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 7360 7361 // We should have two render surfaces. The root's render surface and child's 7362 // render surface (it needs one because it has a replica layer). 7363 EXPECT_EQ(2u, render_surface_layer_list.size()); 7364 7365 gfx::Transform expected_parent_transform; 7366 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform, 7367 parent->screen_space_transform()); 7368 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform, 7369 parent->draw_transform()); 7370 7371 gfx::Transform expected_draw_transform; 7372 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_draw_transform, 7373 child->draw_transform()); 7374 7375 gfx::Transform expected_screen_space_transform; 7376 expected_screen_space_transform.Translate( 7377 device_scale_factor * child->position().x(), 7378 device_scale_factor * child->position().y()); 7379 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_screen_space_transform, 7380 child->screen_space_transform()); 7381 7382 gfx::Transform expected_duplicate_child_draw_transform = 7383 child->draw_transform(); 7384 EXPECT_TRANSFORMATION_MATRIX_EQ(child->draw_transform(), 7385 duplicate_child_non_owner->draw_transform()); 7386 EXPECT_TRANSFORMATION_MATRIX_EQ( 7387 child->screen_space_transform(), 7388 duplicate_child_non_owner->screen_space_transform()); 7389 EXPECT_RECT_EQ(child->drawable_content_rect(), 7390 duplicate_child_non_owner->drawable_content_rect()); 7391 EXPECT_EQ(child->content_bounds(), 7392 duplicate_child_non_owner->content_bounds()); 7393 7394 gfx::Transform expected_render_surface_draw_transform; 7395 expected_render_surface_draw_transform.Translate( 7396 device_scale_factor * child->position().x(), 7397 device_scale_factor * child->position().y()); 7398 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_render_surface_draw_transform, 7399 child->render_surface()->draw_transform()); 7400 7401 gfx::Transform expected_surface_draw_transform; 7402 expected_surface_draw_transform.Translate(device_scale_factor * 2.f, 7403 device_scale_factor * 2.f); 7404 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform, 7405 child->render_surface()->draw_transform()); 7406 7407 gfx::Transform expected_surface_screen_space_transform; 7408 expected_surface_screen_space_transform.Translate(device_scale_factor * 2.f, 7409 device_scale_factor * 2.f); 7410 EXPECT_TRANSFORMATION_MATRIX_EQ( 7411 expected_surface_screen_space_transform, 7412 child->render_surface()->screen_space_transform()); 7413 7414 gfx::Transform expected_replica_draw_transform; 7415 expected_replica_draw_transform.matrix().setDouble(1, 1, -1.0); 7416 expected_replica_draw_transform.matrix().setDouble(0, 3, 6.0); 7417 expected_replica_draw_transform.matrix().setDouble(1, 3, 6.0); 7418 EXPECT_TRANSFORMATION_MATRIX_EQ( 7419 expected_replica_draw_transform, 7420 child->render_surface()->replica_draw_transform()); 7421 7422 gfx::Transform expected_replica_screen_space_transform; 7423 expected_replica_screen_space_transform.matrix().setDouble(1, 1, -1.0); 7424 expected_replica_screen_space_transform.matrix().setDouble(0, 3, 6.0); 7425 expected_replica_screen_space_transform.matrix().setDouble(1, 3, 6.0); 7426 EXPECT_TRANSFORMATION_MATRIX_EQ( 7427 expected_replica_screen_space_transform, 7428 child->render_surface()->replica_screen_space_transform()); 7429 EXPECT_TRANSFORMATION_MATRIX_EQ( 7430 expected_replica_screen_space_transform, 7431 child->render_surface()->replica_screen_space_transform()); 7432 } 7433 7434 TEST_F(LayerTreeHostCommonTest, 7435 RenderSurfaceTransformsInHighDPIAccurateScaleZeroPosition) { 7436 MockContentLayerClient delegate; 7437 gfx::Transform identity_matrix; 7438 7439 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); 7440 SetLayerPropertiesForTesting(parent.get(), 7441 identity_matrix, 7442 identity_matrix, 7443 gfx::PointF(), 7444 gfx::PointF(), 7445 gfx::Size(33, 31), 7446 true); 7447 7448 scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate); 7449 SetLayerPropertiesForTesting(child.get(), 7450 identity_matrix, 7451 identity_matrix, 7452 gfx::PointF(), 7453 gfx::PointF(), 7454 gfx::Size(13, 11), 7455 true); 7456 7457 gfx::Transform replica_transform; 7458 replica_transform.Scale(1.0, -1.0); 7459 scoped_refptr<ContentLayer> replica = CreateDrawableContentLayer(&delegate); 7460 SetLayerPropertiesForTesting(replica.get(), 7461 replica_transform, 7462 identity_matrix, 7463 gfx::PointF(), 7464 gfx::PointF(), 7465 gfx::Size(13, 11), 7466 true); 7467 7468 // This layer should end up in the same surface as child, with the same draw 7469 // and screen space transforms. 7470 scoped_refptr<ContentLayer> duplicate_child_non_owner = 7471 CreateDrawableContentLayer(&delegate); 7472 SetLayerPropertiesForTesting(duplicate_child_non_owner.get(), 7473 identity_matrix, 7474 identity_matrix, 7475 gfx::PointF(), 7476 gfx::PointF(), 7477 gfx::Size(13, 11), 7478 true); 7479 7480 parent->AddChild(child); 7481 child->AddChild(duplicate_child_non_owner); 7482 child->SetReplicaLayer(replica.get()); 7483 7484 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 7485 host->SetRootLayer(parent); 7486 7487 float device_scale_factor = 1.7f; 7488 7489 RenderSurfaceLayerList render_surface_layer_list; 7490 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 7491 parent.get(), parent->bounds(), &render_surface_layer_list); 7492 inputs.device_scale_factor = device_scale_factor; 7493 inputs.can_adjust_raster_scales = true; 7494 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 7495 7496 // We should have two render surfaces. The root's render surface and child's 7497 // render surface (it needs one because it has a replica layer). 7498 EXPECT_EQ(2u, render_surface_layer_list.size()); 7499 7500 gfx::Transform identity_transform; 7501 7502 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, 7503 parent->screen_space_transform()); 7504 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, parent->draw_transform()); 7505 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, child->draw_transform()); 7506 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, 7507 child->screen_space_transform()); 7508 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, 7509 duplicate_child_non_owner->draw_transform()); 7510 EXPECT_TRANSFORMATION_MATRIX_EQ( 7511 identity_transform, duplicate_child_non_owner->screen_space_transform()); 7512 EXPECT_RECT_EQ(child->drawable_content_rect(), 7513 duplicate_child_non_owner->drawable_content_rect()); 7514 EXPECT_EQ(child->content_bounds(), 7515 duplicate_child_non_owner->content_bounds()); 7516 7517 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, 7518 child->render_surface()->draw_transform()); 7519 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, 7520 child->render_surface()->draw_transform()); 7521 EXPECT_TRANSFORMATION_MATRIX_EQ( 7522 identity_transform, child->render_surface()->screen_space_transform()); 7523 7524 gfx::Transform expected_replica_draw_transform; 7525 expected_replica_draw_transform.matrix().setDouble(1, 1, -1.0); 7526 EXPECT_TRANSFORMATION_MATRIX_EQ( 7527 expected_replica_draw_transform, 7528 child->render_surface()->replica_draw_transform()); 7529 7530 gfx::Transform expected_replica_screen_space_transform; 7531 expected_replica_screen_space_transform.matrix().setDouble(1, 1, -1.0); 7532 EXPECT_TRANSFORMATION_MATRIX_EQ( 7533 expected_replica_screen_space_transform, 7534 child->render_surface()->replica_screen_space_transform()); 7535 } 7536 7537 TEST_F(LayerTreeHostCommonTest, SubtreeSearch) { 7538 scoped_refptr<Layer> root = Layer::Create(); 7539 scoped_refptr<Layer> child = Layer::Create(); 7540 scoped_refptr<Layer> grand_child = Layer::Create(); 7541 scoped_refptr<Layer> mask_layer = Layer::Create(); 7542 scoped_refptr<Layer> replica_layer = Layer::Create(); 7543 7544 grand_child->SetReplicaLayer(replica_layer.get()); 7545 child->AddChild(grand_child.get()); 7546 child->SetMaskLayer(mask_layer.get()); 7547 root->AddChild(child.get()); 7548 7549 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 7550 host->SetRootLayer(root); 7551 7552 int nonexistent_id = -1; 7553 EXPECT_EQ(root, 7554 LayerTreeHostCommon::FindLayerInSubtree(root.get(), root->id())); 7555 EXPECT_EQ(child, 7556 LayerTreeHostCommon::FindLayerInSubtree(root.get(), child->id())); 7557 EXPECT_EQ( 7558 grand_child, 7559 LayerTreeHostCommon::FindLayerInSubtree(root.get(), grand_child->id())); 7560 EXPECT_EQ( 7561 mask_layer, 7562 LayerTreeHostCommon::FindLayerInSubtree(root.get(), mask_layer->id())); 7563 EXPECT_EQ( 7564 replica_layer, 7565 LayerTreeHostCommon::FindLayerInSubtree(root.get(), replica_layer->id())); 7566 EXPECT_EQ( 7567 0, LayerTreeHostCommon::FindLayerInSubtree(root.get(), nonexistent_id)); 7568 } 7569 7570 TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) { 7571 scoped_refptr<Layer> root = Layer::Create(); 7572 scoped_refptr<Layer> child = Layer::Create(); 7573 scoped_refptr<LayerWithForcedDrawsContent> grand_child = 7574 make_scoped_refptr(new LayerWithForcedDrawsContent()); 7575 7576 const gfx::Transform identity_matrix; 7577 SetLayerPropertiesForTesting(root.get(), 7578 identity_matrix, 7579 identity_matrix, 7580 gfx::PointF(), 7581 gfx::PointF(), 7582 gfx::Size(100, 100), 7583 false); 7584 SetLayerPropertiesForTesting(child.get(), 7585 identity_matrix, 7586 identity_matrix, 7587 gfx::PointF(), 7588 gfx::PointF(), 7589 gfx::Size(10, 10), 7590 false); 7591 SetLayerPropertiesForTesting(grand_child.get(), 7592 identity_matrix, 7593 identity_matrix, 7594 gfx::PointF(), 7595 gfx::PointF(), 7596 gfx::Size(10, 10), 7597 false); 7598 7599 root->AddChild(child); 7600 child->AddChild(grand_child); 7601 child->SetOpacity(0.5f); 7602 7603 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 7604 host->SetRootLayer(root); 7605 7606 ExecuteCalculateDrawProperties(root.get()); 7607 7608 EXPECT_FALSE(child->render_surface()); 7609 } 7610 7611 TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { 7612 FakeImplProxy proxy; 7613 FakeLayerTreeHostImpl host_impl(&proxy); 7614 host_impl.CreatePendingTree(); 7615 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1); 7616 7617 const gfx::Transform identity_matrix; 7618 SetLayerPropertiesForTesting(root.get(), 7619 identity_matrix, 7620 identity_matrix, 7621 gfx::PointF(), 7622 gfx::PointF(), 7623 gfx::Size(100, 100), 7624 false); 7625 root->SetDrawsContent(true); 7626 7627 scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2); 7628 SetLayerPropertiesForTesting(child.get(), 7629 identity_matrix, 7630 identity_matrix, 7631 gfx::PointF(), 7632 gfx::PointF(), 7633 gfx::Size(50, 50), 7634 false); 7635 child->SetDrawsContent(true); 7636 child->SetOpacity(0.0f); 7637 7638 // Add opacity animation. 7639 AddOpacityTransitionToController( 7640 child->layer_animation_controller(), 10.0, 0.0f, 1.0f, false); 7641 7642 root->AddChild(child.Pass()); 7643 7644 LayerImplList render_surface_layer_list; 7645 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 7646 root.get(), root->bounds(), &render_surface_layer_list); 7647 inputs.can_adjust_raster_scales = true; 7648 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 7649 7650 // We should have one render surface and two layers. The child 7651 // layer should be included even though it is transparent. 7652 ASSERT_EQ(1u, render_surface_layer_list.size()); 7653 ASSERT_EQ(2u, root->render_surface()->layer_list().size()); 7654 } 7655 7656 typedef std::tr1::tuple<bool, bool> LCDTextTestParam; 7657 class LCDTextTest 7658 : public LayerTreeHostCommonTestBase, 7659 public testing::TestWithParam<LCDTextTestParam> { 7660 protected: 7661 virtual void SetUp() { 7662 can_use_lcd_text_ = std::tr1::get<0>(GetParam()); 7663 7664 root_ = Layer::Create(); 7665 child_ = Layer::Create(); 7666 grand_child_ = Layer::Create(); 7667 child_->AddChild(grand_child_.get()); 7668 root_->AddChild(child_.get()); 7669 7670 gfx::Transform identity_matrix; 7671 SetLayerPropertiesForTesting(root_.get(), 7672 identity_matrix, 7673 identity_matrix, 7674 gfx::PointF(), 7675 gfx::PointF(), 7676 gfx::Size(1, 1), 7677 false); 7678 SetLayerPropertiesForTesting(child_.get(), 7679 identity_matrix, 7680 identity_matrix, 7681 gfx::PointF(), 7682 gfx::PointF(), 7683 gfx::Size(1, 1), 7684 false); 7685 SetLayerPropertiesForTesting(grand_child_.get(), 7686 identity_matrix, 7687 identity_matrix, 7688 gfx::PointF(), 7689 gfx::PointF(), 7690 gfx::Size(1, 1), 7691 false); 7692 7693 child_->SetForceRenderSurface(std::tr1::get<1>(GetParam())); 7694 7695 host_ = FakeLayerTreeHost::Create(); 7696 host_->SetRootLayer(root_); 7697 } 7698 7699 bool can_use_lcd_text_; 7700 scoped_ptr<FakeLayerTreeHost> host_; 7701 scoped_refptr<Layer> root_; 7702 scoped_refptr<Layer> child_; 7703 scoped_refptr<Layer> grand_child_; 7704 }; 7705 7706 TEST_P(LCDTextTest, CanUseLCDText) { 7707 // Case 1: Identity transform. 7708 gfx::Transform identity_matrix; 7709 ExecuteCalculateDrawProperties( 7710 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); 7711 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); 7712 EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text()); 7713 EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text()); 7714 7715 // Case 2: Integral translation. 7716 gfx::Transform integral_translation; 7717 integral_translation.Translate(1.0, 2.0); 7718 child_->SetTransform(integral_translation); 7719 ExecuteCalculateDrawProperties( 7720 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); 7721 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); 7722 EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text()); 7723 EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text()); 7724 7725 // Case 3: Non-integral translation. 7726 gfx::Transform non_integral_translation; 7727 non_integral_translation.Translate(1.5, 2.5); 7728 child_->SetTransform(non_integral_translation); 7729 ExecuteCalculateDrawProperties( 7730 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); 7731 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); 7732 EXPECT_FALSE(child_->can_use_lcd_text()); 7733 EXPECT_FALSE(grand_child_->can_use_lcd_text()); 7734 7735 // Case 4: Rotation. 7736 gfx::Transform rotation; 7737 rotation.Rotate(10.0); 7738 child_->SetTransform(rotation); 7739 ExecuteCalculateDrawProperties( 7740 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); 7741 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); 7742 EXPECT_FALSE(child_->can_use_lcd_text()); 7743 EXPECT_FALSE(grand_child_->can_use_lcd_text()); 7744 7745 // Case 5: Scale. 7746 gfx::Transform scale; 7747 scale.Scale(2.0, 2.0); 7748 child_->SetTransform(scale); 7749 ExecuteCalculateDrawProperties( 7750 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); 7751 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); 7752 EXPECT_FALSE(child_->can_use_lcd_text()); 7753 EXPECT_FALSE(grand_child_->can_use_lcd_text()); 7754 7755 // Case 6: Skew. 7756 gfx::Transform skew; 7757 skew.SkewX(10.0); 7758 child_->SetTransform(skew); 7759 ExecuteCalculateDrawProperties( 7760 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); 7761 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); 7762 EXPECT_FALSE(child_->can_use_lcd_text()); 7763 EXPECT_FALSE(grand_child_->can_use_lcd_text()); 7764 7765 // Case 7: Translucent. 7766 child_->SetTransform(identity_matrix); 7767 child_->SetOpacity(0.5f); 7768 ExecuteCalculateDrawProperties( 7769 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); 7770 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); 7771 EXPECT_FALSE(child_->can_use_lcd_text()); 7772 EXPECT_FALSE(grand_child_->can_use_lcd_text()); 7773 7774 // Case 8: Sanity check: restore transform and opacity. 7775 child_->SetTransform(identity_matrix); 7776 child_->SetOpacity(1.f); 7777 ExecuteCalculateDrawProperties( 7778 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); 7779 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); 7780 EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text()); 7781 EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text()); 7782 } 7783 7784 TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) { 7785 // Sanity check: Make sure can_use_lcd_text_ is set on each node. 7786 ExecuteCalculateDrawProperties( 7787 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); 7788 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); 7789 EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text()); 7790 EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text()); 7791 7792 // Add opacity animation. 7793 child_->SetOpacity(0.9f); 7794 AddOpacityTransitionToController( 7795 child_->layer_animation_controller(), 10.0, 0.9f, 0.1f, false); 7796 7797 ExecuteCalculateDrawProperties( 7798 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_); 7799 // Text AA should not be adjusted while animation is active. 7800 // Make sure LCD text AA setting remains unchanged. 7801 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text()); 7802 EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text()); 7803 EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text()); 7804 } 7805 7806 INSTANTIATE_TEST_CASE_P(LayerTreeHostCommonTest, 7807 LCDTextTest, 7808 testing::Combine(testing::Bool(), testing::Bool())); 7809 7810 TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayer) { 7811 FakeImplProxy proxy; 7812 FakeLayerTreeHostImpl host_impl(&proxy); 7813 host_impl.CreatePendingTree(); 7814 const gfx::Transform identity_matrix; 7815 7816 scoped_refptr<Layer> root = Layer::Create(); 7817 SetLayerPropertiesForTesting(root.get(), 7818 identity_matrix, 7819 identity_matrix, 7820 gfx::PointF(), 7821 gfx::PointF(), 7822 gfx::Size(50, 50), 7823 false); 7824 root->SetIsDrawable(true); 7825 7826 scoped_refptr<Layer> child = Layer::Create(); 7827 SetLayerPropertiesForTesting(child.get(), 7828 identity_matrix, 7829 identity_matrix, 7830 gfx::PointF(), 7831 gfx::PointF(), 7832 gfx::Size(40, 40), 7833 false); 7834 child->SetIsDrawable(true); 7835 7836 scoped_refptr<Layer> grand_child = Layer::Create(); 7837 SetLayerPropertiesForTesting(grand_child.get(), 7838 identity_matrix, 7839 identity_matrix, 7840 gfx::PointF(), 7841 gfx::PointF(), 7842 gfx::Size(30, 30), 7843 false); 7844 grand_child->SetIsDrawable(true); 7845 grand_child->SetHideLayerAndSubtree(true); 7846 7847 child->AddChild(grand_child); 7848 root->AddChild(child); 7849 7850 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 7851 host->SetRootLayer(root); 7852 7853 RenderSurfaceLayerList render_surface_layer_list; 7854 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 7855 root.get(), root->bounds(), &render_surface_layer_list); 7856 inputs.can_adjust_raster_scales = true; 7857 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 7858 7859 // We should have one render surface and two layers. The grand child has 7860 // hidden itself. 7861 ASSERT_EQ(1u, render_surface_layer_list.size()); 7862 ASSERT_EQ(2u, root->render_surface()->layer_list().size()); 7863 EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id()); 7864 EXPECT_EQ(child->id(), root->render_surface()->layer_list().at(1)->id()); 7865 } 7866 7867 TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayerImpl) { 7868 FakeImplProxy proxy; 7869 FakeLayerTreeHostImpl host_impl(&proxy); 7870 host_impl.CreatePendingTree(); 7871 const gfx::Transform identity_matrix; 7872 7873 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1); 7874 SetLayerPropertiesForTesting(root.get(), 7875 identity_matrix, 7876 identity_matrix, 7877 gfx::PointF(), 7878 gfx::PointF(), 7879 gfx::Size(50, 50), 7880 false); 7881 root->SetDrawsContent(true); 7882 7883 scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2); 7884 SetLayerPropertiesForTesting(child.get(), 7885 identity_matrix, 7886 identity_matrix, 7887 gfx::PointF(), 7888 gfx::PointF(), 7889 gfx::Size(40, 40), 7890 false); 7891 child->SetDrawsContent(true); 7892 7893 scoped_ptr<LayerImpl> grand_child = 7894 LayerImpl::Create(host_impl.pending_tree(), 3); 7895 SetLayerPropertiesForTesting(grand_child.get(), 7896 identity_matrix, 7897 identity_matrix, 7898 gfx::PointF(), 7899 gfx::PointF(), 7900 gfx::Size(30, 30), 7901 false); 7902 grand_child->SetDrawsContent(true); 7903 grand_child->SetHideLayerAndSubtree(true); 7904 7905 child->AddChild(grand_child.Pass()); 7906 root->AddChild(child.Pass()); 7907 7908 LayerImplList render_surface_layer_list; 7909 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 7910 root.get(), root->bounds(), &render_surface_layer_list); 7911 inputs.can_adjust_raster_scales = true; 7912 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 7913 7914 // We should have one render surface and two layers. The grand child has 7915 // hidden itself. 7916 ASSERT_EQ(1u, render_surface_layer_list.size()); 7917 ASSERT_EQ(2u, root->render_surface()->layer_list().size()); 7918 EXPECT_EQ(1, root->render_surface()->layer_list().at(0)->id()); 7919 EXPECT_EQ(2, root->render_surface()->layer_list().at(1)->id()); 7920 } 7921 7922 TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayers) { 7923 FakeImplProxy proxy; 7924 FakeLayerTreeHostImpl host_impl(&proxy); 7925 host_impl.CreatePendingTree(); 7926 const gfx::Transform identity_matrix; 7927 7928 scoped_refptr<Layer> root = Layer::Create(); 7929 SetLayerPropertiesForTesting(root.get(), 7930 identity_matrix, 7931 identity_matrix, 7932 gfx::PointF(), 7933 gfx::PointF(), 7934 gfx::Size(50, 50), 7935 false); 7936 root->SetIsDrawable(true); 7937 7938 scoped_refptr<Layer> child = Layer::Create(); 7939 SetLayerPropertiesForTesting(child.get(), 7940 identity_matrix, 7941 identity_matrix, 7942 gfx::PointF(), 7943 gfx::PointF(), 7944 gfx::Size(40, 40), 7945 false); 7946 child->SetIsDrawable(true); 7947 child->SetHideLayerAndSubtree(true); 7948 7949 scoped_refptr<Layer> grand_child = Layer::Create(); 7950 SetLayerPropertiesForTesting(grand_child.get(), 7951 identity_matrix, 7952 identity_matrix, 7953 gfx::PointF(), 7954 gfx::PointF(), 7955 gfx::Size(30, 30), 7956 false); 7957 grand_child->SetIsDrawable(true); 7958 7959 child->AddChild(grand_child); 7960 root->AddChild(child); 7961 7962 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 7963 host->SetRootLayer(root); 7964 7965 RenderSurfaceLayerList render_surface_layer_list; 7966 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 7967 root.get(), root->bounds(), &render_surface_layer_list); 7968 inputs.can_adjust_raster_scales = true; 7969 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 7970 7971 // We should have one render surface and one layers. The child has 7972 // hidden itself and the grand child. 7973 ASSERT_EQ(1u, render_surface_layer_list.size()); 7974 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 7975 EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id()); 7976 } 7977 7978 TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayersImpl) { 7979 FakeImplProxy proxy; 7980 FakeLayerTreeHostImpl host_impl(&proxy); 7981 host_impl.CreatePendingTree(); 7982 const gfx::Transform identity_matrix; 7983 7984 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1); 7985 SetLayerPropertiesForTesting(root.get(), 7986 identity_matrix, 7987 identity_matrix, 7988 gfx::PointF(), 7989 gfx::PointF(), 7990 gfx::Size(50, 50), 7991 false); 7992 root->SetDrawsContent(true); 7993 7994 scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2); 7995 SetLayerPropertiesForTesting(child.get(), 7996 identity_matrix, 7997 identity_matrix, 7998 gfx::PointF(), 7999 gfx::PointF(), 8000 gfx::Size(40, 40), 8001 false); 8002 child->SetDrawsContent(true); 8003 child->SetHideLayerAndSubtree(true); 8004 8005 scoped_ptr<LayerImpl> grand_child = 8006 LayerImpl::Create(host_impl.pending_tree(), 3); 8007 SetLayerPropertiesForTesting(grand_child.get(), 8008 identity_matrix, 8009 identity_matrix, 8010 gfx::PointF(), 8011 gfx::PointF(), 8012 gfx::Size(30, 30), 8013 false); 8014 grand_child->SetDrawsContent(true); 8015 8016 child->AddChild(grand_child.Pass()); 8017 root->AddChild(child.Pass()); 8018 8019 LayerImplList render_surface_layer_list; 8020 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 8021 root.get(), root->bounds(), &render_surface_layer_list); 8022 inputs.can_adjust_raster_scales = true; 8023 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 8024 8025 // We should have one render surface and one layers. The child has 8026 // hidden itself and the grand child. 8027 ASSERT_EQ(1u, render_surface_layer_list.size()); 8028 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 8029 EXPECT_EQ(1, root->render_surface()->layer_list().at(0)->id()); 8030 } 8031 8032 void EmptyCopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} 8033 8034 TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { 8035 FakeImplProxy proxy; 8036 FakeLayerTreeHostImpl host_impl(&proxy); 8037 host_impl.CreatePendingTree(); 8038 const gfx::Transform identity_matrix; 8039 8040 scoped_refptr<Layer> root = Layer::Create(); 8041 SetLayerPropertiesForTesting(root.get(), 8042 identity_matrix, 8043 identity_matrix, 8044 gfx::PointF(), 8045 gfx::PointF(), 8046 gfx::Size(50, 50), 8047 false); 8048 root->SetIsDrawable(true); 8049 8050 scoped_refptr<Layer> copy_grand_parent = Layer::Create(); 8051 SetLayerPropertiesForTesting(copy_grand_parent.get(), 8052 identity_matrix, 8053 identity_matrix, 8054 gfx::PointF(), 8055 gfx::PointF(), 8056 gfx::Size(40, 40), 8057 false); 8058 copy_grand_parent->SetIsDrawable(true); 8059 8060 scoped_refptr<Layer> copy_parent = Layer::Create(); 8061 SetLayerPropertiesForTesting(copy_parent.get(), 8062 identity_matrix, 8063 identity_matrix, 8064 gfx::PointF(), 8065 gfx::PointF(), 8066 gfx::Size(30, 30), 8067 false); 8068 copy_parent->SetIsDrawable(true); 8069 copy_parent->SetForceRenderSurface(true); 8070 8071 scoped_refptr<Layer> copy_layer = Layer::Create(); 8072 SetLayerPropertiesForTesting(copy_layer.get(), 8073 identity_matrix, 8074 identity_matrix, 8075 gfx::PointF(), 8076 gfx::PointF(), 8077 gfx::Size(20, 20), 8078 false); 8079 copy_layer->SetIsDrawable(true); 8080 8081 scoped_refptr<Layer> copy_child = Layer::Create(); 8082 SetLayerPropertiesForTesting(copy_child.get(), 8083 identity_matrix, 8084 identity_matrix, 8085 gfx::PointF(), 8086 gfx::PointF(), 8087 gfx::Size(20, 20), 8088 false); 8089 copy_child->SetIsDrawable(true); 8090 8091 scoped_refptr<Layer> copy_grand_parent_sibling_before = Layer::Create(); 8092 SetLayerPropertiesForTesting(copy_grand_parent_sibling_before.get(), 8093 identity_matrix, 8094 identity_matrix, 8095 gfx::PointF(), 8096 gfx::PointF(), 8097 gfx::Size(40, 40), 8098 false); 8099 copy_grand_parent_sibling_before->SetIsDrawable(true); 8100 8101 scoped_refptr<Layer> copy_grand_parent_sibling_after = Layer::Create(); 8102 SetLayerPropertiesForTesting(copy_grand_parent_sibling_after.get(), 8103 identity_matrix, 8104 identity_matrix, 8105 gfx::PointF(), 8106 gfx::PointF(), 8107 gfx::Size(40, 40), 8108 false); 8109 copy_grand_parent_sibling_after->SetIsDrawable(true); 8110 8111 copy_layer->AddChild(copy_child); 8112 copy_parent->AddChild(copy_layer); 8113 copy_grand_parent->AddChild(copy_parent); 8114 root->AddChild(copy_grand_parent_sibling_before); 8115 root->AddChild(copy_grand_parent); 8116 root->AddChild(copy_grand_parent_sibling_after); 8117 8118 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 8119 host->SetRootLayer(root); 8120 8121 // Hide the copy_grand_parent and its subtree. But make a copy request in that 8122 // hidden subtree on copy_layer. 8123 copy_grand_parent->SetHideLayerAndSubtree(true); 8124 copy_grand_parent_sibling_before->SetHideLayerAndSubtree(true); 8125 copy_grand_parent_sibling_after->SetHideLayerAndSubtree(true); 8126 copy_layer->RequestCopyOfOutput(CopyOutputRequest::CreateRequest( 8127 base::Bind(&EmptyCopyOutputCallback))); 8128 EXPECT_TRUE(copy_layer->HasCopyRequest()); 8129 8130 RenderSurfaceLayerList render_surface_layer_list; 8131 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 8132 root.get(), root->bounds(), &render_surface_layer_list); 8133 inputs.can_adjust_raster_scales = true; 8134 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 8135 8136 EXPECT_TRUE(root->draw_properties().layer_or_descendant_has_copy_request); 8137 EXPECT_TRUE(copy_grand_parent->draw_properties(). 8138 layer_or_descendant_has_copy_request); 8139 EXPECT_TRUE(copy_parent->draw_properties(). 8140 layer_or_descendant_has_copy_request); 8141 EXPECT_TRUE(copy_layer->draw_properties(). 8142 layer_or_descendant_has_copy_request); 8143 EXPECT_FALSE(copy_child->draw_properties(). 8144 layer_or_descendant_has_copy_request); 8145 EXPECT_FALSE(copy_grand_parent_sibling_before->draw_properties(). 8146 layer_or_descendant_has_copy_request); 8147 EXPECT_FALSE(copy_grand_parent_sibling_after->draw_properties(). 8148 layer_or_descendant_has_copy_request); 8149 8150 // We should have three render surfaces, one for the root, one for the parent 8151 // since it owns a surface, and one for the copy_layer. 8152 ASSERT_EQ(3u, render_surface_layer_list.size()); 8153 EXPECT_EQ(root->id(), render_surface_layer_list.at(0)->id()); 8154 EXPECT_EQ(copy_parent->id(), render_surface_layer_list.at(1)->id()); 8155 EXPECT_EQ(copy_layer->id(), render_surface_layer_list.at(2)->id()); 8156 8157 // The root render surface should have 2 contributing layers. The 8158 // copy_grand_parent is hidden along with its siblings, but the copy_parent 8159 // will appear since something in its subtree needs to be drawn for a copy 8160 // request. 8161 ASSERT_EQ(2u, root->render_surface()->layer_list().size()); 8162 EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id()); 8163 EXPECT_EQ(copy_parent->id(), 8164 root->render_surface()->layer_list().at(1)->id()); 8165 8166 // Nothing actually drawns into the copy parent, so only the copy_layer will 8167 // appear in its list, since it needs to be drawn for the copy request. 8168 ASSERT_EQ(1u, copy_parent->render_surface()->layer_list().size()); 8169 EXPECT_EQ(copy_layer->id(), 8170 copy_parent->render_surface()->layer_list().at(0)->id()); 8171 8172 // The copy_layer's render surface should have two contributing layers. 8173 ASSERT_EQ(2u, copy_layer->render_surface()->layer_list().size()); 8174 EXPECT_EQ(copy_layer->id(), 8175 copy_layer->render_surface()->layer_list().at(0)->id()); 8176 EXPECT_EQ(copy_child->id(), 8177 copy_layer->render_surface()->layer_list().at(1)->id()); 8178 } 8179 8180 TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) { 8181 FakeImplProxy proxy; 8182 FakeLayerTreeHostImpl host_impl(&proxy); 8183 host_impl.CreatePendingTree(); 8184 const gfx::Transform identity_matrix; 8185 8186 scoped_refptr<Layer> root = Layer::Create(); 8187 SetLayerPropertiesForTesting(root.get(), 8188 identity_matrix, 8189 identity_matrix, 8190 gfx::PointF(), 8191 gfx::PointF(), 8192 gfx::Size(50, 50), 8193 false); 8194 root->SetIsDrawable(true); 8195 8196 scoped_refptr<Layer> copy_parent = Layer::Create(); 8197 SetLayerPropertiesForTesting(copy_parent.get(), 8198 identity_matrix, 8199 identity_matrix, 8200 gfx::PointF(), 8201 gfx::PointF(), 8202 gfx::Size(), 8203 false); 8204 copy_parent->SetIsDrawable(true); 8205 copy_parent->SetMasksToBounds(true); 8206 8207 scoped_refptr<Layer> copy_layer = Layer::Create(); 8208 SetLayerPropertiesForTesting(copy_layer.get(), 8209 identity_matrix, 8210 identity_matrix, 8211 gfx::PointF(), 8212 gfx::PointF(), 8213 gfx::Size(30, 30), 8214 false); 8215 copy_layer->SetIsDrawable(true); 8216 8217 scoped_refptr<Layer> copy_child = Layer::Create(); 8218 SetLayerPropertiesForTesting(copy_child.get(), 8219 identity_matrix, 8220 identity_matrix, 8221 gfx::PointF(), 8222 gfx::PointF(), 8223 gfx::Size(20, 20), 8224 false); 8225 copy_child->SetIsDrawable(true); 8226 8227 copy_layer->AddChild(copy_child); 8228 copy_parent->AddChild(copy_layer); 8229 root->AddChild(copy_parent); 8230 8231 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 8232 host->SetRootLayer(root); 8233 8234 copy_layer->RequestCopyOfOutput(CopyOutputRequest::CreateRequest( 8235 base::Bind(&EmptyCopyOutputCallback))); 8236 EXPECT_TRUE(copy_layer->HasCopyRequest()); 8237 8238 RenderSurfaceLayerList render_surface_layer_list; 8239 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 8240 root.get(), root->bounds(), &render_surface_layer_list); 8241 inputs.can_adjust_raster_scales = true; 8242 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 8243 8244 // We should have one render surface, as the others are clipped out. 8245 ASSERT_EQ(1u, render_surface_layer_list.size()); 8246 EXPECT_EQ(root->id(), render_surface_layer_list.at(0)->id()); 8247 8248 // The root render surface should only have 1 contributing layer, since the 8249 // other layers are empty/clipped away. 8250 ASSERT_EQ(1u, root->render_surface()->layer_list().size()); 8251 EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id()); 8252 } 8253 8254 TEST_F(LayerTreeHostCommonTest, VisibleContentRectInsideSurface) { 8255 FakeImplProxy proxy; 8256 FakeLayerTreeHostImpl host_impl(&proxy); 8257 host_impl.CreatePendingTree(); 8258 const gfx::Transform identity_matrix; 8259 8260 scoped_refptr<Layer> root = Layer::Create(); 8261 SetLayerPropertiesForTesting(root.get(), 8262 identity_matrix, 8263 identity_matrix, 8264 gfx::PointF(), 8265 gfx::PointF(), 8266 gfx::Size(50, 50), 8267 false); 8268 root->SetIsDrawable(true); 8269 8270 // The surface is moved slightly outside of the viewport. 8271 scoped_refptr<Layer> surface = Layer::Create(); 8272 SetLayerPropertiesForTesting(surface.get(), 8273 identity_matrix, 8274 identity_matrix, 8275 gfx::PointF(), 8276 gfx::PointF(-10, -20), 8277 gfx::Size(), 8278 false); 8279 surface->SetForceRenderSurface(true); 8280 8281 scoped_refptr<Layer> surface_child = Layer::Create(); 8282 SetLayerPropertiesForTesting(surface_child.get(), 8283 identity_matrix, 8284 identity_matrix, 8285 gfx::PointF(), 8286 gfx::PointF(), 8287 gfx::Size(50, 50), 8288 false); 8289 surface_child->SetIsDrawable(true); 8290 8291 surface->AddChild(surface_child); 8292 root->AddChild(surface); 8293 8294 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); 8295 host->SetRootLayer(root); 8296 8297 RenderSurfaceLayerList render_surface_layer_list; 8298 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( 8299 root.get(), root->bounds(), &render_surface_layer_list); 8300 inputs.can_adjust_raster_scales = true; 8301 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 8302 8303 // The visible_content_rect for the |surface_child| should not be clipped by 8304 // the viewport. 8305 EXPECT_EQ(gfx::Rect(50, 50).ToString(), 8306 surface_child->visible_content_rect().ToString()); 8307 } 8308 8309 } // namespace 8310 } // namespace cc 8311