| 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/paint/GeometryMapper.h" | 5 #include "platform/graphics/paint/GeometryMapper.h" |
| 6 | 6 |
| 7 #include "platform/geometry/GeometryTestHelpers.h" | 7 #include "platform/geometry/GeometryTestHelpers.h" |
| 8 #include "platform/geometry/LayoutRect.h" | 8 #include "platform/geometry/LayoutRect.h" |
| 9 #include "platform/graphics/paint/ClipPaintPropertyNode.h" | 9 #include "platform/graphics/paint/ClipPaintPropertyNode.h" |
| 10 #include "platform/graphics/paint/EffectPaintPropertyNode.h" | 10 #include "platform/graphics/paint/EffectPaintPropertyNode.h" |
| 11 #include "platform/graphics/paint/ScrollPaintPropertyNode.h" | 11 #include "platform/graphics/paint/ScrollPaintPropertyNode.h" |
| 12 #include "platform/graphics/paint/TransformPaintPropertyNode.h" | 12 #include "platform/graphics/paint/TransformPaintPropertyNode.h" |
| 13 #include "platform/testing/PaintPropertyTestHelpers.h" | 13 #include "platform/testing/PaintPropertyTestHelpers.h" |
| 14 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 16 |
| 16 namespace blink { | 17 namespace blink { |
| 17 | 18 |
| 18 class GeometryMapperTest : public ::testing::Test { | 19 class GeometryMapperTest : public ::testing::Test, |
| 20 public ScopedSlimmingPaintV2ForTest { |
| 19 public: | 21 public: |
| 22 GeometryMapperTest() : ScopedSlimmingPaintV2ForTest(true) {} |
| 23 |
| 20 std::unique_ptr<GeometryMapper> geometryMapper; | 24 std::unique_ptr<GeometryMapper> geometryMapper; |
| 21 | 25 |
| 22 PropertyTreeState rootPropertyTreeState() { | 26 PropertyTreeState rootPropertyTreeState() { |
| 23 PropertyTreeState state( | 27 PropertyTreeState state( |
| 24 TransformPaintPropertyNode::root(), ClipPaintPropertyNode::root(), | 28 TransformPaintPropertyNode::root(), ClipPaintPropertyNode::root(), |
| 25 EffectPaintPropertyNode::root(), ScrollPaintPropertyNode::root()); | 29 EffectPaintPropertyNode::root(), ScrollPaintPropertyNode::root()); |
| 26 return state; | 30 return state; |
| 27 } | 31 } |
| 28 | 32 |
| 29 PrecomputedDataForAncestor& getPrecomputedDataForAncestor( | 33 PrecomputedDataForAncestor& getPrecomputedDataForAncestor( |
| 30 const PropertyTreeState& propertyTreeState) { | 34 const PropertyTreeState& propertyTreeState) { |
| 31 return geometryMapper->getPrecomputedDataForAncestor(propertyTreeState); | 35 return geometryMapper->getPrecomputedDataForAncestor( |
| 36 propertyTreeState.transform()); |
| 32 } | 37 } |
| 33 | 38 |
| 34 const TransformPaintPropertyNode* leastCommonAncestor( | 39 const TransformPaintPropertyNode* leastCommonAncestor( |
| 35 const TransformPaintPropertyNode* a, | 40 const TransformPaintPropertyNode* a, |
| 36 const TransformPaintPropertyNode* b) { | 41 const TransformPaintPropertyNode* b) { |
| 37 return GeometryMapper::leastCommonAncestor(a, b); | 42 return GeometryMapper::leastCommonAncestor(a, b); |
| 38 } | 43 } |
| 39 | 44 |
| 40 private: | 45 private: |
| 41 void SetUp() override { | 46 void SetUp() override { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 66 << ", expected: " << expected.height(); \ | 71 << ", expected: " << expected.height(); \ |
| 67 } while (false) | 72 } while (false) |
| 68 | 73 |
| 69 #define CHECK_MAPPINGS(inputRect, expectedVisualRect, expectedTransformedRect, \ | 74 #define CHECK_MAPPINGS(inputRect, expectedVisualRect, expectedTransformedRect, \ |
| 70 expectedTransformToAncestor, \ | 75 expectedTransformToAncestor, \ |
| 71 expectedClipInAncestorSpace, localPropertyTreeState, \ | 76 expectedClipInAncestorSpace, localPropertyTreeState, \ |
| 72 ancestorPropertyTreeState) \ | 77 ancestorPropertyTreeState) \ |
| 73 do { \ | 78 do { \ |
| 74 bool success = false; \ | 79 bool success = false; \ |
| 75 EXPECT_RECT_EQ(expectedVisualRect, \ | 80 EXPECT_RECT_EQ(expectedVisualRect, \ |
| 76 geometryMapper->localToVisualRectInAncestorSpace( \ | 81 geometryMapper->localToAncestorVisualRect( \ |
| 77 inputRect, localPropertyTreeState, \ | 82 inputRect, localPropertyTreeState, \ |
| 78 ancestorPropertyTreeState, success)); \ | 83 ancestorPropertyTreeState, success)); \ |
| 79 EXPECT_TRUE(success); \ | 84 EXPECT_TRUE(success); \ |
| 80 FloatRect mappedClip = geometryMapper->localToAncestorClipRect( \ | 85 FloatRect mappedClip = geometryMapper->localToAncestorClipRect( \ |
| 81 localPropertyTreeState, ancestorPropertyTreeState, success); \ | 86 localPropertyTreeState, ancestorPropertyTreeState, success); \ |
| 82 EXPECT_TRUE(success); \ | 87 EXPECT_TRUE(success); \ |
| 83 EXPECT_RECT_EQ(expectedClipInAncestorSpace, mappedClip); \ | 88 EXPECT_RECT_EQ(expectedClipInAncestorSpace, mappedClip); \ |
| 84 EXPECT_RECT_EQ(expectedVisualRect, \ | 89 EXPECT_RECT_EQ(expectedVisualRect, \ |
| 85 geometryMapper->mapToVisualRectInDestinationSpace( \ | 90 geometryMapper->sourceToDestinationVisualRect( \ |
| 86 inputRect, localPropertyTreeState, \ | 91 inputRect, localPropertyTreeState, \ |
| 87 ancestorPropertyTreeState, success)); \ | 92 ancestorPropertyTreeState, success)); \ |
| 88 EXPECT_TRUE(success); \ | 93 EXPECT_TRUE(success); \ |
| 89 EXPECT_RECT_EQ(expectedTransformedRect, \ | 94 EXPECT_RECT_EQ(expectedTransformedRect, \ |
| 90 geometryMapper->localToAncestorRect( \ | 95 geometryMapper->localToAncestorRect( \ |
| 91 inputRect, localPropertyTreeState, \ | 96 inputRect, localPropertyTreeState.transform(), \ |
| 92 ancestorPropertyTreeState, success)); \ | 97 ancestorPropertyTreeState.transform(), success)); \ |
| 93 EXPECT_RECT_EQ(expectedTransformedRect, \ | 98 EXPECT_RECT_EQ(expectedTransformedRect, \ |
| 94 geometryMapper->mapRectToDestinationSpace( \ | 99 geometryMapper->sourceToDestinationRect( \ |
| 95 inputRect, localPropertyTreeState, \ | 100 inputRect, localPropertyTreeState.transform(), \ |
| 96 ancestorPropertyTreeState, success)); \ | 101 ancestorPropertyTreeState.transform(), success)); \ |
| 97 EXPECT_TRUE(success); \ | 102 EXPECT_TRUE(success); \ |
| 98 if (ancestorPropertyTreeState.transform() != \ | 103 if (ancestorPropertyTreeState.transform() != \ |
| 99 localPropertyTreeState.transform()) { \ | 104 localPropertyTreeState.transform()) { \ |
| 100 EXPECT_EQ( \ | 105 EXPECT_EQ( \ |
| 101 expectedTransformToAncestor, \ | 106 expectedTransformToAncestor, \ |
| 102 getPrecomputedDataForAncestor(ancestorPropertyTreeState) \ | 107 getPrecomputedDataForAncestor(ancestorPropertyTreeState) \ |
| 103 .toAncestorTransforms.get(localPropertyTreeState.transform())); \ | 108 .toAncestorTransforms.get(localPropertyTreeState.transform())); \ |
| 104 } \ | 109 } \ |
| 105 if (ancestorPropertyTreeState.clip() != localPropertyTreeState.clip()) { \ | 110 if (ancestorPropertyTreeState.clip() != localPropertyTreeState.clip()) { \ |
| 106 EXPECT_EQ(expectedClipInAncestorSpace, \ | 111 EXPECT_EQ(expectedClipInAncestorSpace, \ |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 localState.setTransform(transform.get()); | 148 localState.setTransform(transform.get()); |
| 144 | 149 |
| 145 FloatRect input(0, 0, 100, 100); | 150 FloatRect input(0, 0, 100, 100); |
| 146 FloatRect output = transformMatrix.mapRect(input); | 151 FloatRect output = transformMatrix.mapRect(input); |
| 147 | 152 |
| 148 CHECK_MAPPINGS(input, output, output, transform->matrix(), | 153 CHECK_MAPPINGS(input, output, output, transform->matrix(), |
| 149 ClipPaintPropertyNode::root()->clipRect().rect(), localState, | 154 ClipPaintPropertyNode::root()->clipRect().rect(), localState, |
| 150 rootPropertyTreeState()); | 155 rootPropertyTreeState()); |
| 151 | 156 |
| 152 bool success = false; | 157 bool success = false; |
| 153 EXPECT_RECT_EQ(input, | 158 EXPECT_RECT_EQ(input, geometryMapper->ancestorToLocalRect( |
| 154 geometryMapper->ancestorToLocalRect( | 159 output, rootPropertyTreeState().transform(), |
| 155 output, localState, rootPropertyTreeState(), success)); | 160 localState.transform(), success)); |
| 156 EXPECT_TRUE(success); | 161 EXPECT_TRUE(success); |
| 157 } | 162 } |
| 158 | 163 |
| 159 TEST_F(GeometryMapperTest, RotationAndScaleTransform) { | 164 TEST_F(GeometryMapperTest, RotationAndScaleTransform) { |
| 160 TransformationMatrix transformMatrix; | 165 TransformationMatrix transformMatrix; |
| 161 transformMatrix.rotate(45); | 166 transformMatrix.rotate(45); |
| 162 transformMatrix.scale(2); | 167 transformMatrix.scale(2); |
| 163 RefPtr<TransformPaintPropertyNode> transform = | 168 RefPtr<TransformPaintPropertyNode> transform = |
| 164 TransformPaintPropertyNode::create(rootPropertyTreeState().transform(), | 169 TransformPaintPropertyNode::create(rootPropertyTreeState().transform(), |
| 165 transformMatrix, | 170 transformMatrix, |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 TransformPaintPropertyNode::create(rootPropertyTreeState().transform(), | 446 TransformPaintPropertyNode::create(rootPropertyTreeState().transform(), |
| 442 rotateTransform2, FloatPoint3D()); | 447 rotateTransform2, FloatPoint3D()); |
| 443 | 448 |
| 444 PropertyTreeState transform1State = rootPropertyTreeState(); | 449 PropertyTreeState transform1State = rootPropertyTreeState(); |
| 445 transform1State.setTransform(transform1.get()); | 450 transform1State.setTransform(transform1.get()); |
| 446 PropertyTreeState transform2State = rootPropertyTreeState(); | 451 PropertyTreeState transform2State = rootPropertyTreeState(); |
| 447 transform2State.setTransform(transform2.get()); | 452 transform2State.setTransform(transform2.get()); |
| 448 | 453 |
| 449 bool success; | 454 bool success; |
| 450 FloatRect input(0, 0, 100, 100); | 455 FloatRect input(0, 0, 100, 100); |
| 451 FloatRect result = geometryMapper->localToVisualRectInAncestorSpace( | 456 FloatRect result = geometryMapper->localToAncestorVisualRect( |
| 452 input, transform1State, transform2State, success); | 457 input, transform1State, transform2State, success); |
| 453 // Fails, because the transform2state is not an ancestor of transform1State. | 458 // Fails, because the transform2state is not an ancestor of transform1State. |
| 454 EXPECT_FALSE(success); | 459 EXPECT_FALSE(success); |
| 455 EXPECT_RECT_EQ(input, result); | 460 EXPECT_RECT_EQ(input, result); |
| 456 | 461 |
| 457 result = geometryMapper->localToAncestorRect(input, transform1State, | 462 result = geometryMapper->localToAncestorRect(input, transform1.get(), |
| 458 transform2State, success); | 463 transform2.get(), success); |
| 459 // Fails, because the transform2state is not an ancestor of transform1State. | 464 // Fails, because the transform2state is not an ancestor of transform1State. |
| 460 EXPECT_FALSE(success); | 465 EXPECT_FALSE(success); |
| 461 EXPECT_RECT_EQ(input, result); | 466 EXPECT_RECT_EQ(input, result); |
| 462 | 467 |
| 463 result = geometryMapper->localToVisualRectInAncestorSpace( | 468 result = geometryMapper->localToAncestorVisualRect(input, transform2State, |
| 464 input, transform2State, transform1State, success); | 469 transform1State, success); |
| 465 // Fails, because the transform1state is not an ancestor of transform2State. | 470 // Fails, because the transform1state is not an ancestor of transform2State. |
| 466 EXPECT_FALSE(success); | 471 EXPECT_FALSE(success); |
| 467 EXPECT_RECT_EQ(input, result); | 472 EXPECT_RECT_EQ(input, result); |
| 468 | 473 |
| 469 result = geometryMapper->localToAncestorRect(input, transform2State, | 474 result = geometryMapper->localToAncestorRect(input, transform2.get(), |
| 470 transform1State, success); | 475 transform1.get(), success); |
| 471 // Fails, because the transform1state is not an ancestor of transform2State. | 476 // Fails, because the transform1state is not an ancestor of transform2State. |
| 472 EXPECT_FALSE(success); | 477 EXPECT_FALSE(success); |
| 473 EXPECT_RECT_EQ(input, result); | 478 EXPECT_RECT_EQ(input, result); |
| 474 | 479 |
| 475 FloatRect expected = | 480 FloatRect expected = |
| 476 rotateTransform2.inverse().mapRect(rotateTransform1.mapRect(input)); | 481 rotateTransform2.inverse().mapRect(rotateTransform1.mapRect(input)); |
| 477 result = geometryMapper->mapToVisualRectInDestinationSpace( | 482 result = geometryMapper->sourceToDestinationVisualRect( |
| 478 input, transform1State, transform2State, success); | 483 input, transform1State, transform2State, success); |
| 479 EXPECT_TRUE(success); | 484 EXPECT_TRUE(success); |
| 480 EXPECT_RECT_EQ(expected, result); | 485 EXPECT_RECT_EQ(expected, result); |
| 481 | 486 |
| 482 result = geometryMapper->mapRectToDestinationSpace(input, transform1State, | 487 result = geometryMapper->sourceToDestinationRect(input, transform1.get(), |
| 483 transform2State, success); | 488 transform2.get(), success); |
| 484 EXPECT_TRUE(success); | 489 EXPECT_TRUE(success); |
| 485 EXPECT_RECT_EQ(expected, result); | 490 EXPECT_RECT_EQ(expected, result); |
| 486 } | 491 } |
| 487 | 492 |
| 488 TEST_F(GeometryMapperTest, SiblingTransformsWithClip) { | 493 TEST_F(GeometryMapperTest, SiblingTransformsWithClip) { |
| 489 // These transforms are siblings. Thus mapping from one to the other requires | 494 // These transforms are siblings. Thus mapping from one to the other requires |
| 490 // going through the root. | 495 // going through the root. |
| 491 TransformationMatrix rotateTransform1; | 496 TransformationMatrix rotateTransform1; |
| 492 rotateTransform1.rotate(45); | 497 rotateTransform1.rotate(45); |
| 493 RefPtr<TransformPaintPropertyNode> transform1 = | 498 RefPtr<TransformPaintPropertyNode> transform1 = |
| (...skipping 16 matching lines...) Expand all Loading... |
| 510 transform2AndClipState.setTransform(transform2.get()); | 515 transform2AndClipState.setTransform(transform2.get()); |
| 511 transform2AndClipState.setClip(clip.get()); | 516 transform2AndClipState.setClip(clip.get()); |
| 512 | 517 |
| 513 bool success; | 518 bool success; |
| 514 FloatRect input(0, 0, 100, 100); | 519 FloatRect input(0, 0, 100, 100); |
| 515 | 520 |
| 516 // Test map from transform1State to transform2AndClipState. | 521 // Test map from transform1State to transform2AndClipState. |
| 517 FloatRect expected = | 522 FloatRect expected = |
| 518 rotateTransform2.inverse().mapRect(rotateTransform1.mapRect(input)); | 523 rotateTransform2.inverse().mapRect(rotateTransform1.mapRect(input)); |
| 519 | 524 |
| 520 // mapToVisualRectInDestinationSpace ignores clip from the common ancestor to | 525 // sourceToDestinationVisualRect ignores clip from the common ancestor to |
| 521 // destination. | 526 // destination. |
| 522 FloatRect result = geometryMapper->mapToVisualRectInDestinationSpace( | 527 FloatRect result = geometryMapper->sourceToDestinationVisualRect( |
| 523 input, transform1State, transform2AndClipState, success); | 528 input, transform1State, transform2AndClipState, success); |
| 524 // Fails, because the clip of the destination state is not an ancestor of the | 529 // Fails, because the clip of the destination state is not an ancestor of the |
| 525 // clip of the source state. | 530 // clip of the source state. |
| 526 EXPECT_FALSE(success); | 531 EXPECT_FALSE(success); |
| 527 | 532 |
| 528 // mapRectToDestinationSpace ignores clip. | 533 // sourceToDestinationRect applies transforms only. |
| 529 result = geometryMapper->mapRectToDestinationSpace( | 534 result = geometryMapper->sourceToDestinationRect(input, transform1.get(), |
| 530 input, transform1State, transform2AndClipState, success); | 535 transform2.get(), success); |
| 531 EXPECT_TRUE(success); | 536 EXPECT_TRUE(success); |
| 532 EXPECT_RECT_EQ(expected, result); | 537 EXPECT_RECT_EQ(expected, result); |
| 533 | 538 |
| 534 // Test map from transform2AndClipState to transform1State. | 539 // Test map from transform2AndClipState to transform1State. |
| 535 FloatRect expectedUnclipped = | 540 FloatRect expectedUnclipped = |
| 536 rotateTransform1.inverse().mapRect(rotateTransform2.mapRect(input)); | 541 rotateTransform1.inverse().mapRect(rotateTransform2.mapRect(input)); |
| 537 FloatRect expectedClipped = rotateTransform1.inverse().mapRect( | 542 FloatRect expectedClipped = rotateTransform1.inverse().mapRect( |
| 538 rotateTransform2.mapRect(FloatRect(10, 10, 70, 70))); | 543 rotateTransform2.mapRect(FloatRect(10, 10, 70, 70))); |
| 539 | 544 |
| 540 // mapToVisualRectInDestinationSpace ignores clip from the common ancestor to | 545 // sourceToDestinationVisualRect ignores clip from the common ancestor to |
| 541 // destination. | 546 // destination. |
| 542 result = geometryMapper->mapToVisualRectInDestinationSpace( | 547 result = geometryMapper->sourceToDestinationVisualRect( |
| 543 input, transform2AndClipState, transform1State, success); | 548 input, transform2AndClipState, transform1State, success); |
| 544 EXPECT_TRUE(success); | 549 EXPECT_TRUE(success); |
| 545 EXPECT_RECT_EQ(expectedClipped, result); | 550 EXPECT_RECT_EQ(expectedClipped, result); |
| 546 | 551 |
| 547 // mapRectToDestinationSpace ignores clip. | 552 // sourceToDestinationRect applies transforms only. |
| 548 result = geometryMapper->mapRectToDestinationSpace( | 553 result = geometryMapper->sourceToDestinationRect(input, transform2.get(), |
| 549 input, transform2AndClipState, transform1State, success); | 554 transform1.get(), success); |
| 550 EXPECT_TRUE(success); | 555 EXPECT_TRUE(success); |
| 551 EXPECT_RECT_EQ(expectedUnclipped, result); | 556 EXPECT_RECT_EQ(expectedUnclipped, result); |
| 552 } | 557 } |
| 553 | 558 |
| 554 TEST_F(GeometryMapperTest, LeastCommonAncestor) { | 559 TEST_F(GeometryMapperTest, LeastCommonAncestor) { |
| 555 TransformationMatrix matrix; | 560 TransformationMatrix matrix; |
| 556 RefPtr<TransformPaintPropertyNode> child1 = | 561 RefPtr<TransformPaintPropertyNode> child1 = |
| 557 TransformPaintPropertyNode::create(rootPropertyTreeState().transform(), | 562 TransformPaintPropertyNode::create(rootPropertyTreeState().transform(), |
| 558 matrix, FloatPoint3D()); | 563 matrix, FloatPoint3D()); |
| 559 RefPtr<TransformPaintPropertyNode> child2 = | 564 RefPtr<TransformPaintPropertyNode> child2 = |
| (...skipping 21 matching lines...) Expand all Loading... |
| 581 EXPECT_EQ(rootPropertyTreeState().transform(), | 586 EXPECT_EQ(rootPropertyTreeState().transform(), |
| 582 leastCommonAncestor(childOfChild2.get(), | 587 leastCommonAncestor(childOfChild2.get(), |
| 583 rootPropertyTreeState().transform())); | 588 rootPropertyTreeState().transform())); |
| 584 EXPECT_EQ(child2, leastCommonAncestor(childOfChild2.get(), child2.get())); | 589 EXPECT_EQ(child2, leastCommonAncestor(childOfChild2.get(), child2.get())); |
| 585 | 590 |
| 586 EXPECT_EQ(rootPropertyTreeState().transform(), | 591 EXPECT_EQ(rootPropertyTreeState().transform(), |
| 587 leastCommonAncestor(child1.get(), child2.get())); | 592 leastCommonAncestor(child1.get(), child2.get())); |
| 588 } | 593 } |
| 589 | 594 |
| 590 } // namespace blink | 595 } // namespace blink |
| OLD | NEW |