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/effect_node.h" | 13 #include "cc/trees/effect_node.h" |
13 #include "cc/trees/layer_tree_host.h" | 14 #include "cc/trees/layer_tree_host.h" |
14 #include "cc/trees/layer_tree_settings.h" | 15 #include "cc/trees/layer_tree_settings.h" |
| 16 #include "cc/trees/transform_node.h" |
15 #include "platform/RuntimeEnabledFeatures.h" | 17 #include "platform/RuntimeEnabledFeatures.h" |
16 #include "platform/graphics/paint/EffectPaintPropertyNode.h" | 18 #include "platform/graphics/paint/EffectPaintPropertyNode.h" |
17 #include "platform/graphics/paint/PaintArtifact.h" | 19 #include "platform/graphics/paint/PaintArtifact.h" |
18 #include "platform/testing/PictureMatchers.h" | 20 #include "platform/testing/PictureMatchers.h" |
19 #include "platform/testing/TestPaintArtifact.h" | 21 #include "platform/testing/TestPaintArtifact.h" |
20 #include "platform/testing/WebLayerTreeViewImplForTesting.h" | 22 #include "platform/testing/WebLayerTreeViewImplForTesting.h" |
21 #include "testing/gmock/include/gmock/gmock.h" | 23 #include "testing/gmock/include/gmock/gmock.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
23 #include "wtf/PtrUtil.h" | 25 #include "wtf/PtrUtil.h" |
24 #include <memory> | 26 #include <memory> |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 settings.use_layer_lists = true; | 411 settings.use_layer_lists = true; |
410 m_webLayerTreeView = wrapUnique(new WebLayerTreeViewWithOutputSurface(se
ttings)); | 412 m_webLayerTreeView = wrapUnique(new WebLayerTreeViewWithOutputSurface(se
ttings)); |
411 m_webLayerTreeView->setRootLayer(*getPaintArtifactCompositor().getWebLay
er()); | 413 m_webLayerTreeView->setRootLayer(*getPaintArtifactCompositor().getWebLay
er()); |
412 } | 414 } |
413 | 415 |
414 const cc::PropertyTrees& propertyTrees() | 416 const cc::PropertyTrees& propertyTrees() |
415 { | 417 { |
416 return *m_webLayerTreeView->layerTreeHost()->property_trees(); | 418 return *m_webLayerTreeView->layerTreeHost()->property_trees(); |
417 } | 419 } |
418 | 420 |
| 421 const cc::TransformNode& transformNode(const cc::Layer* layer) |
| 422 { |
| 423 return *propertyTrees().transform_tree.Node(layer->transform_tree_index(
)); |
| 424 } |
| 425 |
419 void update(const PaintArtifact& artifact) | 426 void update(const PaintArtifact& artifact) |
420 { | 427 { |
421 PaintArtifactCompositorTest::update(artifact); | 428 PaintArtifactCompositorTest::update(artifact); |
422 m_webLayerTreeView->layerTreeHost()->LayoutAndUpdateLayers(); | 429 m_webLayerTreeView->layerTreeHost()->LayoutAndUpdateLayers(); |
423 } | 430 } |
424 | 431 |
425 private: | 432 private: |
426 scoped_refptr<base::TestSimpleTaskRunner> m_taskRunner; | 433 scoped_refptr<base::TestSimpleTaskRunner> m_taskRunner; |
427 base::ThreadTaskRunnerHandle m_taskRunnerHandle; | 434 base::ThreadTaskRunnerHandle m_taskRunnerHandle; |
428 std::unique_ptr<WebLayerTreeViewWithOutputSurface> m_webLayerTreeView; | 435 std::unique_ptr<WebLayerTreeViewWithOutputSurface> m_webLayerTreeView; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::black))); | 527 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::black))); |
521 gfx::RectF mappedRect(0, 0, 300, 200); | 528 gfx::RectF mappedRect(0, 0, 300, 200); |
522 layer->screen_space_transform().TransformRect(&mappedRect); | 529 layer->screen_space_transform().TransformRect(&mappedRect); |
523 EXPECT_EQ(gfx::RectF(0, 0, 600, 400), mappedRect); | 530 EXPECT_EQ(gfx::RectF(0, 0, 600, 400), mappedRect); |
524 } | 531 } |
525 EXPECT_NE( | 532 EXPECT_NE( |
526 contentLayerAt(0)->transform_tree_index(), | 533 contentLayerAt(0)->transform_tree_index(), |
527 contentLayerAt(1)->transform_tree_index()); | 534 contentLayerAt(1)->transform_tree_index()); |
528 } | 535 } |
529 | 536 |
| 537 TEST_F(PaintArtifactCompositorTestWithPropertyTrees, FlattensInheritedTransform) |
| 538 { |
| 539 for (bool transformIsFlattened : { true, false }) { |
| 540 SCOPED_TRACE(transformIsFlattened); |
| 541 |
| 542 // The flattens_inherited_transform bit corresponds to whether the _pare
nt_ |
| 543 // transform node flattens the transform. This is because Blink's notion
of |
| 544 // flattening determines whether content within the node's local transfo
rm |
| 545 // is flattened, while cc's notion applies in the parent's coordinate sp
ace. |
| 546 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNo
de::create( |
| 547 nullptr, TransformationMatrix(), FloatPoint3D()); |
| 548 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNo
de::create( |
| 549 transform1, TransformationMatrix().rotate3d(0, 45, 0), FloatPoint3D(
)); |
| 550 RefPtr<TransformPaintPropertyNode> transform3 = TransformPaintPropertyNo
de::create( |
| 551 transform2, TransformationMatrix().rotate3d(0, 45, 0), FloatPoint3D(
), |
| 552 transformIsFlattened); |
| 553 |
| 554 TestPaintArtifact artifact; |
| 555 artifact.chunk(transform3, nullptr, nullptr) |
| 556 .rectDrawing(FloatRect(0, 0, 300, 200), Color::white); |
| 557 update(artifact.build()); |
| 558 |
| 559 ASSERT_EQ(1u, contentLayerCount()); |
| 560 const cc::Layer* layer = contentLayerAt(0); |
| 561 EXPECT_THAT(layer->GetPicture(), |
| 562 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::white))); |
| 563 |
| 564 // The leaf transform node should flatten its inherited transform node |
| 565 // if and only if the intermediate rotation transform in the Blink tree |
| 566 // flattens. |
| 567 const cc::TransformNode* transformNode3 = propertyTrees().transform_tree
.Node(layer->transform_tree_index()); |
| 568 EXPECT_EQ(transformIsFlattened, transformNode3->flattens_inherited_trans
form); |
| 569 |
| 570 // Given this, we should expect the correct screen space transform for |
| 571 // each case. If the transform was flattened, we should see it getting |
| 572 // an effective horizontal scale of 1/sqrt(2) each time, thus it gets |
| 573 // half as wide. If the transform was not flattened, we should see an |
| 574 // empty rectangle (as the total 90 degree rotation makes it |
| 575 // perpendicular to the viewport). |
| 576 gfx::RectF rect(0, 0, 100, 100); |
| 577 layer->screen_space_transform().TransformRect(&rect); |
| 578 if (transformIsFlattened) |
| 579 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 50, 100), rect); |
| 580 else |
| 581 EXPECT_TRUE(rect.IsEmpty()); |
| 582 } |
| 583 } |
| 584 |
| 585 TEST_F(PaintArtifactCompositorTestWithPropertyTrees, SortingContextID) |
| 586 { |
| 587 // Has no 3D rendering context. |
| 588 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::
create( |
| 589 nullptr, TransformationMatrix(), FloatPoint3D()); |
| 590 // Establishes a 3D rendering context. |
| 591 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::
create( |
| 592 transform1, TransformationMatrix(), FloatPoint3D(), false, 1); |
| 593 // Extends the 3D rendering context of transform2. |
| 594 RefPtr<TransformPaintPropertyNode> transform3 = TransformPaintPropertyNode::
create( |
| 595 transform2, TransformationMatrix(), FloatPoint3D(), false, 1); |
| 596 // Establishes a 3D rendering context distinct from transform2. |
| 597 RefPtr<TransformPaintPropertyNode> transform4 = TransformPaintPropertyNode::
create( |
| 598 transform2, TransformationMatrix(), FloatPoint3D(), false, 2); |
| 599 |
| 600 TestPaintArtifact artifact; |
| 601 artifact.chunk(transform1, nullptr, dummyRootEffect()) |
| 602 .rectDrawing(FloatRect(0, 0, 300, 200), Color::white); |
| 603 artifact.chunk(transform2, nullptr, dummyRootEffect()) |
| 604 .rectDrawing(FloatRect(0, 0, 300, 200), Color::lightGray); |
| 605 artifact.chunk(transform3, nullptr, dummyRootEffect()) |
| 606 .rectDrawing(FloatRect(0, 0, 300, 200), Color::darkGray); |
| 607 artifact.chunk(transform4, nullptr, dummyRootEffect()) |
| 608 .rectDrawing(FloatRect(0, 0, 300, 200), Color::black); |
| 609 update(artifact.build()); |
| 610 |
| 611 ASSERT_EQ(4u, contentLayerCount()); |
| 612 |
| 613 // The white layer is not 3D sorted. |
| 614 const cc::Layer* whiteLayer = contentLayerAt(0); |
| 615 EXPECT_THAT(whiteLayer->GetPicture(), |
| 616 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::white))); |
| 617 int whiteSortingContextId = transformNode(whiteLayer).sorting_context_id; |
| 618 EXPECT_EQ(whiteLayer->sorting_context_id(), whiteSortingContextId); |
| 619 EXPECT_EQ(0, whiteSortingContextId); |
| 620 |
| 621 // The light gray layer is 3D sorted. |
| 622 const cc::Layer* lightGrayLayer = contentLayerAt(1); |
| 623 EXPECT_THAT(lightGrayLayer->GetPicture(), |
| 624 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::lightGray))); |
| 625 int lightGraySortingContextId = transformNode(lightGrayLayer).sorting_contex
t_id; |
| 626 EXPECT_EQ(lightGrayLayer->sorting_context_id(), lightGraySortingContextId); |
| 627 EXPECT_NE(0, lightGraySortingContextId); |
| 628 |
| 629 // The dark gray layer is 3D sorted with the light gray layer, but has a |
| 630 // separate transform node. |
| 631 const cc::Layer* darkGrayLayer = contentLayerAt(2); |
| 632 EXPECT_THAT(darkGrayLayer->GetPicture(), |
| 633 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::darkGray))); |
| 634 int darkGraySortingContextId = transformNode(darkGrayLayer).sorting_context_
id; |
| 635 EXPECT_EQ(darkGrayLayer->sorting_context_id(), darkGraySortingContextId); |
| 636 EXPECT_EQ(lightGraySortingContextId, darkGraySortingContextId); |
| 637 EXPECT_NE(lightGrayLayer->transform_tree_index(), darkGrayLayer->transform_t
ree_index()); |
| 638 |
| 639 // The black layer is 3D sorted, but in a separate context from the previous |
| 640 // layers. |
| 641 const cc::Layer* blackLayer = contentLayerAt(3); |
| 642 EXPECT_THAT(blackLayer->GetPicture(), |
| 643 Pointee(drawsRectangle(FloatRect(0, 0, 300, 200), Color::black))); |
| 644 int blackSortingContextId = transformNode(blackLayer).sorting_context_id; |
| 645 EXPECT_EQ(blackLayer->sorting_context_id(), blackSortingContextId); |
| 646 EXPECT_NE(0, blackSortingContextId); |
| 647 EXPECT_NE(lightGraySortingContextId, blackSortingContextId); |
| 648 } |
| 649 |
530 TEST_F(PaintArtifactCompositorTestWithPropertyTrees, OneClip) | 650 TEST_F(PaintArtifactCompositorTestWithPropertyTrees, OneClip) |
531 { | 651 { |
532 RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create( | 652 RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create( |
533 nullptr, nullptr, FloatRoundedRect(100, 100, 300, 200)); | 653 nullptr, nullptr, FloatRoundedRect(100, 100, 300, 200)); |
534 | 654 |
535 TestPaintArtifact artifact; | 655 TestPaintArtifact artifact; |
536 artifact.chunk(nullptr, clip, nullptr) | 656 artifact.chunk(nullptr, clip, nullptr) |
537 .rectDrawing(FloatRect(220, 80, 300, 200), Color::black); | 657 .rectDrawing(FloatRect(220, 80, 300, 200), Color::black); |
538 update(artifact.build()); | 658 update(artifact.build()); |
539 | 659 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 EXPECT_EQ(convertedDummyRootEffect.id, convertedEffect3.parent_id); | 850 EXPECT_EQ(convertedDummyRootEffect.id, convertedEffect3.parent_id); |
731 EXPECT_FLOAT_EQ(0.2, convertedEffect3.opacity); | 851 EXPECT_FLOAT_EQ(0.2, convertedEffect3.opacity); |
732 | 852 |
733 EXPECT_EQ(convertedEffect2.id, contentLayerAt(0)->effect_tree_index()); | 853 EXPECT_EQ(convertedEffect2.id, contentLayerAt(0)->effect_tree_index()); |
734 EXPECT_EQ(convertedEffect1.id, contentLayerAt(1)->effect_tree_index()); | 854 EXPECT_EQ(convertedEffect1.id, contentLayerAt(1)->effect_tree_index()); |
735 EXPECT_EQ(convertedEffect3.id, contentLayerAt(2)->effect_tree_index()); | 855 EXPECT_EQ(convertedEffect3.id, contentLayerAt(2)->effect_tree_index()); |
736 } | 856 } |
737 | 857 |
738 } // namespace | 858 } // namespace |
739 } // namespace blink | 859 } // namespace blink |
OLD | NEW |