| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/graphics/compositing/PaintArtifactCompositor.h" | 5 #include "platform/graphics/compositing/PaintArtifactCompositor.h" |
| 6 | 6 |
| 7 #include "base/test/test_simple_task_runner.h" | 7 #include "base/test/test_simple_task_runner.h" |
| 8 #include "base/threading/thread_task_runner_handle.h" | 8 #include "base/threading/thread_task_runner_handle.h" |
| 9 #include "cc/layers/layer.h" | 9 #include "cc/layers/layer.h" |
| 10 #include "cc/test/fake_output_surface.h" | 10 #include "cc/test/fake_output_surface.h" |
| 11 #include "cc/test/geometry_test_utils.h" |
| 11 #include "cc/trees/clip_node.h" | 12 #include "cc/trees/clip_node.h" |
| 12 #include "cc/trees/layer_tree_host.h" | 13 #include "cc/trees/layer_tree_host.h" |
| 13 #include "cc/trees/layer_tree_settings.h" | 14 #include "cc/trees/layer_tree_settings.h" |
| 15 #include "cc/trees/transform_node.h" |
| 14 #include "platform/RuntimeEnabledFeatures.h" | 16 #include "platform/RuntimeEnabledFeatures.h" |
| 15 #include "platform/graphics/paint/PaintArtifact.h" | 17 #include "platform/graphics/paint/PaintArtifact.h" |
| 16 #include "platform/testing/PictureMatchers.h" | 18 #include "platform/testing/PictureMatchers.h" |
| 17 #include "platform/testing/TestPaintArtifact.h" | 19 #include "platform/testing/TestPaintArtifact.h" |
| 18 #include "platform/testing/WebLayerTreeViewImplForTesting.h" | 20 #include "platform/testing/WebLayerTreeViewImplForTesting.h" |
| 19 #include "testing/gmock/include/gmock/gmock.h" | 21 #include "testing/gmock/include/gmock/gmock.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 21 #include "wtf/PtrUtil.h" | 23 #include "wtf/PtrUtil.h" |
| 22 #include <memory> | 24 #include <memory> |
| 23 | 25 |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 settings.use_layer_lists = true; | 403 settings.use_layer_lists = true; |
| 402 m_webLayerTreeView = wrapUnique(new WebLayerTreeViewWithOutputSurface(se
ttings)); | 404 m_webLayerTreeView = wrapUnique(new WebLayerTreeViewWithOutputSurface(se
ttings)); |
| 403 m_webLayerTreeView->setRootLayer(*getPaintArtifactCompositor().getWebLay
er()); | 405 m_webLayerTreeView->setRootLayer(*getPaintArtifactCompositor().getWebLay
er()); |
| 404 } | 406 } |
| 405 | 407 |
| 406 const cc::PropertyTrees& propertyTrees() | 408 const cc::PropertyTrees& propertyTrees() |
| 407 { | 409 { |
| 408 return *m_webLayerTreeView->layerTreeHost()->property_trees(); | 410 return *m_webLayerTreeView->layerTreeHost()->property_trees(); |
| 409 } | 411 } |
| 410 | 412 |
| 413 const cc::TransformNode& transformNode(const cc::Layer* layer) |
| 414 { |
| 415 return *propertyTrees().transform_tree.Node(layer->transform_tree_index(
)); |
| 416 } |
| 417 |
| 411 void update(const PaintArtifact& artifact) | 418 void update(const PaintArtifact& artifact) |
| 412 { | 419 { |
| 413 PaintArtifactCompositorTest::update(artifact); | 420 PaintArtifactCompositorTest::update(artifact); |
| 414 m_webLayerTreeView->layerTreeHost()->LayoutAndUpdateLayers(); | 421 m_webLayerTreeView->layerTreeHost()->LayoutAndUpdateLayers(); |
| 415 } | 422 } |
| 416 | 423 |
| 417 private: | 424 private: |
| 418 scoped_refptr<base::TestSimpleTaskRunner> m_taskRunner; | 425 scoped_refptr<base::TestSimpleTaskRunner> m_taskRunner; |
| 419 base::ThreadTaskRunnerHandle m_taskRunnerHandle; | 426 base::ThreadTaskRunnerHandle m_taskRunnerHandle; |
| 420 std::unique_ptr<WebLayerTreeViewWithOutputSurface> m_webLayerTreeView; | 427 std::unique_ptr<WebLayerTreeViewWithOutputSurface> m_webLayerTreeView; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::black))); | 519 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::black))); |
| 513 gfx::RectF mappedRect(0, 0, 300, 200); | 520 gfx::RectF mappedRect(0, 0, 300, 200); |
| 514 layer->screen_space_transform().TransformRect(&mappedRect); | 521 layer->screen_space_transform().TransformRect(&mappedRect); |
| 515 EXPECT_EQ(gfx::RectF(0, 0, 600, 400), mappedRect); | 522 EXPECT_EQ(gfx::RectF(0, 0, 600, 400), mappedRect); |
| 516 } | 523 } |
| 517 EXPECT_NE( | 524 EXPECT_NE( |
| 518 contentLayerAt(0)->transform_tree_index(), | 525 contentLayerAt(0)->transform_tree_index(), |
| 519 contentLayerAt(1)->transform_tree_index()); | 526 contentLayerAt(1)->transform_tree_index()); |
| 520 } | 527 } |
| 521 | 528 |
| 529 TEST_F(PaintArtifactCompositorTestWithPropertyTrees, FlattensInheritedTransform) |
| 530 { |
| 531 for (auto transformStyle : { TransformPaintPropertyNode::FlattenTransform, T
ransformPaintPropertyNode::Preserve3D }) { |
| 532 SCOPED_TRACE(transformStyle); |
| 533 |
| 534 // The flattens_inherited_transform bit corresponds to whether the _pare
nt_ |
| 535 // transform node flattens the transform. This is because Blink's notion
of |
| 536 // flattening determines whether content within the node's local transfo
rm |
| 537 // is flattened, while cc's notion applies in the parent's coordinate sp
ace. |
| 538 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNo
de::create( |
| 539 TransformationMatrix(), FloatPoint3D(), nullptr, |
| 540 TransformPaintPropertyNode::DontEstablishNewRenderingContext, nullpt
r, |
| 541 TransformPaintPropertyNode::FlattenTransform); |
| 542 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNo
de::create( |
| 543 TransformationMatrix().rotate3d(0, 45, 0), FloatPoint3D(), transform
1, |
| 544 transformStyle == TransformPaintPropertyNode::Preserve3D |
| 545 ? TransformPaintPropertyNode::EstablishNewRenderingContext |
| 546 : TransformPaintPropertyNode::DontEstablishNewRenderingContext, |
| 547 nullptr, transformStyle); |
| 548 RefPtr<TransformPaintPropertyNode> transform3 = TransformPaintPropertyNo
de::create( |
| 549 TransformationMatrix().rotate3d(0, 45, 0), FloatPoint3D(), transform
2, |
| 550 TransformPaintPropertyNode::DontEstablishNewRenderingContext, nullpt
r, |
| 551 TransformPaintPropertyNode::FlattenTransform); |
| 552 |
| 553 TestPaintArtifact artifact; |
| 554 artifact.chunk(transform3, nullptr, nullptr) |
| 555 .rectDrawing(FloatRect(0, 0, 300, 200), Color::white); |
| 556 update(artifact.build()); |
| 557 |
| 558 ASSERT_EQ(1u, contentLayerCount()); |
| 559 const cc::Layer* layer = contentLayerAt(0); |
| 560 EXPECT_THAT(layer->GetPicture(), |
| 561 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::white))); |
| 562 |
| 563 // The leaf transform node should flatten its inherited transform node |
| 564 // if and only if the intermediate rotation transform in the Blink tree |
| 565 // flattens. |
| 566 const cc::TransformNode* transformNode3 = propertyTrees().transform_tree
.Node(layer->transform_tree_index()); |
| 567 EXPECT_EQ(transform2->flattensTransform(), transformNode3->flattens_inhe
rited_transform); |
| 568 |
| 569 // Whereas its ancestors always flatten. |
| 570 const cc::TransformNode* transformNode2 = propertyTrees().transform_tree
.parent(transformNode3); |
| 571 EXPECT_TRUE(transformNode2->flattens_inherited_transform); |
| 572 const cc::TransformNode* transformNode1 = propertyTrees().transform_tree
.parent(transformNode2); |
| 573 EXPECT_TRUE(transformNode1->flattens_inherited_transform); |
| 574 |
| 575 // Given this, we should expect the correct screen space transform for |
| 576 // each case. If the transform was flattened, we should see it getting |
| 577 // an effective horizontal scale of 1/sqrt(2) each time, thus it gets |
| 578 // half as wide. If the transform was not flattened, we should see an |
| 579 // empty rectangle (as the total 90 degree rotation makes it |
| 580 // perpendicular to the viewport). |
| 581 gfx::RectF rect(0, 0, 100, 100); |
| 582 layer->screen_space_transform().TransformRect(&rect); |
| 583 switch (transformStyle) { |
| 584 case TransformPaintPropertyNode::FlattenTransform: |
| 585 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 50, 100), rect); |
| 586 break; |
| 587 case TransformPaintPropertyNode::Preserve3D: |
| 588 EXPECT_TRUE(rect.IsEmpty()); |
| 589 break; |
| 590 } |
| 591 } |
| 592 } |
| 593 |
| 594 TEST_F(PaintArtifactCompositorTestWithPropertyTrees, SortingContextID) |
| 595 { |
| 596 // Has no 3D rendering context. |
| 597 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::
create( |
| 598 TransformationMatrix(), FloatPoint3D(), nullptr, |
| 599 TransformPaintPropertyNode::DontEstablishNewRenderingContext, nullptr, |
| 600 TransformPaintPropertyNode::FlattenTransform); |
| 601 // Establishes a 3D rendering context. |
| 602 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::
create( |
| 603 TransformationMatrix(), FloatPoint3D(), transform1, |
| 604 TransformPaintPropertyNode::EstablishNewRenderingContext, nullptr, |
| 605 TransformPaintPropertyNode::Preserve3D); |
| 606 // Extends the 3D rendering context of transform2. |
| 607 RefPtr<TransformPaintPropertyNode> transform3 = TransformPaintPropertyNode::
create( |
| 608 TransformationMatrix(), FloatPoint3D(), transform2, |
| 609 TransformPaintPropertyNode::DontEstablishNewRenderingContext, transform2
.get(), |
| 610 TransformPaintPropertyNode::Preserve3D); |
| 611 // Establishes a 3D rendering context distinct from transform2. |
| 612 RefPtr<TransformPaintPropertyNode> transform4 = TransformPaintPropertyNode::
create( |
| 613 TransformationMatrix(), FloatPoint3D(), transform2, |
| 614 TransformPaintPropertyNode::EstablishNewRenderingContext, nullptr, |
| 615 TransformPaintPropertyNode::Preserve3D); |
| 616 |
| 617 TestPaintArtifact artifact; |
| 618 artifact.chunk(transform1, nullptr, nullptr) |
| 619 .rectDrawing(FloatRect(0, 0, 300, 200), Color::white); |
| 620 artifact.chunk(transform2, nullptr, nullptr) |
| 621 .rectDrawing(FloatRect(0, 0, 300, 200), Color::lightGray); |
| 622 artifact.chunk(transform3, nullptr, nullptr) |
| 623 .rectDrawing(FloatRect(0, 0, 300, 200), Color::darkGray); |
| 624 artifact.chunk(transform4, nullptr, nullptr) |
| 625 .rectDrawing(FloatRect(0, 0, 300, 200), Color::black); |
| 626 update(artifact.build()); |
| 627 |
| 628 ASSERT_EQ(4u, contentLayerCount()); |
| 629 |
| 630 // The white layer is not 3D sorted. |
| 631 const cc::Layer* whiteLayer = contentLayerAt(0); |
| 632 EXPECT_THAT(whiteLayer->GetPicture(), |
| 633 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::white))); |
| 634 int whiteSortingContextId = transformNode(whiteLayer).sorting_context_id; |
| 635 EXPECT_EQ(whiteLayer->sorting_context_id(), whiteSortingContextId); |
| 636 EXPECT_EQ(0, whiteSortingContextId); |
| 637 |
| 638 // The light gray layer is 3D sorted. |
| 639 const cc::Layer* lightGrayLayer = contentLayerAt(1); |
| 640 EXPECT_THAT(lightGrayLayer->GetPicture(), |
| 641 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::lightGray))); |
| 642 int lightGraySortingContextId = transformNode(lightGrayLayer).sorting_contex
t_id; |
| 643 EXPECT_EQ(lightGrayLayer->sorting_context_id(), lightGraySortingContextId); |
| 644 EXPECT_NE(0, lightGraySortingContextId); |
| 645 |
| 646 // The dark gray layer is 3D sorted with the light gray layer, but has a |
| 647 // separate transform node. |
| 648 const cc::Layer* darkGrayLayer = contentLayerAt(2); |
| 649 EXPECT_THAT(darkGrayLayer->GetPicture(), |
| 650 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::darkGray))); |
| 651 int darkGraySortingContextId = transformNode(darkGrayLayer).sorting_context_
id; |
| 652 EXPECT_EQ(darkGrayLayer->sorting_context_id(), darkGraySortingContextId); |
| 653 EXPECT_EQ(lightGraySortingContextId, darkGraySortingContextId); |
| 654 EXPECT_NE(lightGrayLayer->transform_tree_index(), darkGrayLayer->transform_t
ree_index()); |
| 655 |
| 656 // The black layer is 3D sorted, but in a separate context from the previous |
| 657 // layers. |
| 658 const cc::Layer* blackLayer = contentLayerAt(3); |
| 659 EXPECT_THAT(blackLayer->GetPicture(), |
| 660 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::black))); |
| 661 int blackSortingContextId = transformNode(blackLayer).sorting_context_id; |
| 662 EXPECT_EQ(blackLayer->sorting_context_id(), blackSortingContextId); |
| 663 EXPECT_NE(0, blackSortingContextId); |
| 664 EXPECT_NE(lightGraySortingContextId, blackSortingContextId); |
| 665 } |
| 666 |
| 522 TEST_F(PaintArtifactCompositorTestWithPropertyTrees, OneClip) | 667 TEST_F(PaintArtifactCompositorTestWithPropertyTrees, OneClip) |
| 523 { | 668 { |
| 524 RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create( | 669 RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create( |
| 525 nullptr, FloatRoundedRect(100, 100, 300, 200)); | 670 nullptr, FloatRoundedRect(100, 100, 300, 200)); |
| 526 | 671 |
| 527 TestPaintArtifact artifact; | 672 TestPaintArtifact artifact; |
| 528 artifact.chunk(nullptr, clip, nullptr) | 673 artifact.chunk(nullptr, clip, nullptr) |
| 529 .rectDrawing(FloatRect(220, 80, 300, 200), Color::black); | 674 .rectDrawing(FloatRect(220, 80, 300, 200), Color::black); |
| 530 update(artifact.build()); | 675 update(artifact.build()); |
| 531 | 676 |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 680 update(artifact.build()); | 825 update(artifact.build()); |
| 681 | 826 |
| 682 ASSERT_EQ(1u, contentLayerCount()); | 827 ASSERT_EQ(1u, contentLayerCount()); |
| 683 EXPECT_EQ(layer, contentLayerAt(0)); | 828 EXPECT_EQ(layer, contentLayerAt(0)); |
| 684 EXPECT_EQ(gfx::Size(400, 300), layer->bounds()); | 829 EXPECT_EQ(gfx::Size(400, 300), layer->bounds()); |
| 685 EXPECT_EQ(translation(50, 100), layer->screen_space_transform()); | 830 EXPECT_EQ(translation(50, 100), layer->screen_space_transform()); |
| 686 } | 831 } |
| 687 | 832 |
| 688 } // namespace | 833 } // namespace |
| 689 } // namespace blink | 834 } // namespace blink |
| OLD | NEW |