OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "core/layout/compositing/CompositedLayerMapping.h" | 5 #include "core/layout/compositing/CompositedLayerMapping.h" |
6 | 6 |
7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
8 #include "core/layout/LayoutBoxModelObject.h" | 8 #include "core/layout/LayoutBoxModelObject.h" |
9 #include "core/layout/LayoutTestHelper.h" | 9 #include "core/layout/LayoutTestHelper.h" |
10 #include "core/layout/api/LayoutViewItem.h" | 10 #include "core/layout/api/LayoutViewItem.h" |
11 #include "core/page/scrolling/TopDocumentRootScrollerController.h" | |
12 #include "core/paint/PaintLayer.h" | 11 #include "core/paint/PaintLayer.h" |
13 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" | 12 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" |
14 #include "public/platform/WebContentLayer.h" | 13 #include "public/platform/WebContentLayer.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
16 | 15 |
17 namespace blink { | 16 namespace blink { |
18 | 17 |
19 typedef bool TestParamRootLayerScrolling; | 18 typedef bool TestParamRootLayerScrolling; |
20 class CompositedLayerMappingTest | 19 class CompositedLayerMappingTest |
21 : public testing::WithParamInterface<TestParamRootLayerScrolling>, | 20 : public testing::WithParamInterface<TestParamRootLayerScrolling>, |
(...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 | 925 |
927 // We currently don't use composited scrolling when the container has a | 926 // We currently don't use composited scrolling when the container has a |
928 // border-radius so even though we can paint the background onto the scrolling | 927 // border-radius so even though we can paint the background onto the scrolling |
929 // contents layer we don't have a scrolling contents layer to paint into in | 928 // contents layer we don't have a scrolling contents layer to paint into in |
930 // this case. | 929 // this case. |
931 CompositedLayerMapping* mapping = layer->compositedLayerMapping(); | 930 CompositedLayerMapping* mapping = layer->compositedLayerMapping(); |
932 EXPECT_FALSE(mapping->hasScrollingLayer()); | 931 EXPECT_FALSE(mapping->hasScrollingLayer()); |
933 EXPECT_FALSE(mapping->backgroundPaintsOntoScrollingContentsLayer()); | 932 EXPECT_FALSE(mapping->backgroundPaintsOntoScrollingContentsLayer()); |
934 } | 933 } |
935 | 934 |
936 // Make sure that clipping layers are removed or their masking bit turned off | |
937 // when they're an ancestor of the root scroller element. | |
938 TEST_P(CompositedLayerMappingTest, RootScrollerAncestorsNotClipped) { | |
939 NonThrowableExceptionState nonThrow; | |
940 | |
941 TopDocumentRootScrollerController& rootScrollerController = | |
942 document().page()->globalRootScrollerController(); | |
943 | |
944 setBodyInnerHTML( | |
945 // The container DIV is composited with scrolling contents and a | |
946 // non-composited parent that clips it. | |
947 "<div id='clip' style='overflow: hidden; width: 200px; height: 200px; " | |
948 "position: absolute; left: 0px; top: 0px;'>" | |
949 " <div id='container' style='transform: translateZ(0); overflow: " | |
950 "scroll; width: 300px; height: 300px'>" | |
951 " <div style='width: 2000px; height: 2000px;'>lorem ipsum</div>" | |
952 " <div id='innerScroller' style='width: 800px; height: 600px; " | |
953 "left: 0px; top: 0px; position: absolute; overflow: scroll'>" | |
954 " <div style='height: 2000px; width: 2000px'></div>" | |
955 " </div>" | |
956 " </div>" | |
957 "</div>" | |
958 | |
959 // The container DIV is composited with scrolling contents and a | |
960 // composited parent that clips it. | |
961 "<div id='clip2' style='transform: translateZ(0); position: absolute; " | |
962 "left: 0px; top: 0px; overflow: hidden; width: 200px; height: 200px'>" | |
963 " <div id='container2' style='transform: translateZ(0); overflow: " | |
964 "scroll; width: 300px; height: 300px'>" | |
965 " <div style='width: 2000px; height: 2000px;'>lorem ipsum</div>" | |
966 " <div id='innerScroller2' style='width: 800px; height: 600px; " | |
967 "left: 0px; top: 0px; position: absolute; overflow: scroll'>" | |
968 " <div style='height: 2000px; width: 2000px'></div>" | |
969 " </div>" | |
970 " </div>" | |
971 "</div>" | |
972 | |
973 // The container DIV is composited without scrolling contents but | |
974 // composited children that it clips. | |
975 "<div id='container3' style='translateZ(0); position: absolute; left: " | |
976 "0px; top: 0px; z-index: 1; overflow: hidden; width: 300px; height: " | |
977 "300px'>" | |
978 " <div style='transform: translateZ(0); z-index: -1; width: 2000px; " | |
979 "height: 2000px;'>lorem ipsum</div>" | |
980 " <div id='innerScroller3' style='width: 800px; height: 600px; " | |
981 "left: 0px; top: 0px; position: absolute; overflow: scroll'>" | |
982 " <div style='height: 2000px; width: 2000px'></div>" | |
983 " </div>" | |
984 "</div>"); | |
985 | |
986 CompositedLayerMapping* mapping = | |
987 toLayoutBlock(getLayoutObjectByElementId("container")) | |
988 ->layer() | |
989 ->compositedLayerMapping(); | |
990 CompositedLayerMapping* mapping2 = | |
991 toLayoutBlock(getLayoutObjectByElementId("container2")) | |
992 ->layer() | |
993 ->compositedLayerMapping(); | |
994 CompositedLayerMapping* mapping3 = | |
995 toLayoutBlock(getLayoutObjectByElementId("container3")) | |
996 ->layer() | |
997 ->compositedLayerMapping(); | |
998 Element* innerScroller = document().getElementById("innerScroller"); | |
999 Element* innerScroller2 = document().getElementById("innerScroller2"); | |
1000 Element* innerScroller3 = document().getElementById("innerScroller3"); | |
1001 | |
1002 ASSERT_TRUE(mapping); | |
1003 ASSERT_TRUE(mapping2); | |
1004 ASSERT_TRUE(mapping3); | |
1005 ASSERT_TRUE(innerScroller); | |
1006 ASSERT_TRUE(innerScroller2); | |
1007 ASSERT_TRUE(innerScroller3); | |
1008 | |
1009 // Since there's no need to composite the clip and we prefer LCD text, the | |
1010 // mapping should create an ancestorClippingLayer. | |
1011 ASSERT_TRUE(mapping->scrollingLayer()); | |
1012 ASSERT_TRUE(mapping->ancestorClippingLayer()); | |
1013 | |
1014 // Since the clip has a transform it should be composited so there's no | |
1015 // need for an ancestor clipping layer. | |
1016 ASSERT_TRUE(mapping2->scrollingLayer()); | |
1017 | |
1018 // The third <div> should have a clipping layer since it's composited and | |
1019 // clips composited children. | |
1020 ASSERT_TRUE(mapping3->clippingLayer()); | |
1021 | |
1022 // All scrolling and clipping layers should have masksToBounds set on them. | |
1023 { | |
1024 EXPECT_TRUE(mapping->scrollingLayer()->platformLayer()->masksToBounds()); | |
1025 EXPECT_TRUE( | |
1026 mapping->ancestorClippingLayer()->platformLayer()->masksToBounds()); | |
1027 EXPECT_TRUE(mapping2->scrollingLayer()->platformLayer()->masksToBounds()); | |
1028 EXPECT_TRUE(mapping3->clippingLayer()->platformLayer()->masksToBounds()); | |
1029 } | |
1030 | |
1031 // Set the inner scroller in the first container as the root scroller. Its | |
1032 // clipping layer should be removed and the scrolling layer should not | |
1033 // mask. | |
1034 { | |
1035 document().setRootScroller(innerScroller, nonThrow); | |
1036 document().view()->updateAllLifecyclePhases(); | |
1037 ASSERT_EQ(innerScroller, rootScrollerController.globalRootScroller()); | |
1038 | |
1039 EXPECT_FALSE(mapping->ancestorClippingLayer()); | |
1040 EXPECT_FALSE(mapping->scrollingLayer()->platformLayer()->masksToBounds()); | |
1041 } | |
1042 | |
1043 // Set the inner scroller in the second container as the root scroller. Its | |
1044 // scrolling layer should no longer mask. The clipping and scrolling layers | |
1045 // on the first container should now reset back. | |
1046 { | |
1047 document().setRootScroller(innerScroller2, nonThrow); | |
1048 document().view()->updateAllLifecyclePhases(); | |
1049 ASSERT_EQ(innerScroller2, rootScrollerController.globalRootScroller()); | |
1050 | |
1051 EXPECT_TRUE(mapping->ancestorClippingLayer()); | |
1052 EXPECT_TRUE( | |
1053 mapping->ancestorClippingLayer()->platformLayer()->masksToBounds()); | |
1054 EXPECT_TRUE(mapping->scrollingLayer()->platformLayer()->masksToBounds()); | |
1055 | |
1056 EXPECT_FALSE(mapping2->scrollingLayer()->platformLayer()->masksToBounds()); | |
1057 } | |
1058 | |
1059 // Set the inner scroller in the third container as the root scroller. Its | |
1060 // clipping layer should be removed. | |
1061 { | |
1062 document().setRootScroller(innerScroller3, nonThrow); | |
1063 document().view()->updateAllLifecyclePhases(); | |
1064 ASSERT_EQ(innerScroller3, rootScrollerController.globalRootScroller()); | |
1065 | |
1066 EXPECT_TRUE(mapping2->scrollingLayer()->platformLayer()->masksToBounds()); | |
1067 | |
1068 EXPECT_FALSE(mapping3->clippingLayer()); | |
1069 } | |
1070 | |
1071 // Unset the root scroller. The clipping layer on the third container should | |
1072 // be restored. | |
1073 { | |
1074 document().setRootScroller(nullptr, nonThrow); | |
1075 document().view()->updateAllLifecyclePhases(); | |
1076 ASSERT_EQ(document().documentElement(), | |
1077 rootScrollerController.globalRootScroller()); | |
1078 | |
1079 EXPECT_TRUE(mapping3->clippingLayer()); | |
1080 EXPECT_TRUE(mapping3->clippingLayer()->platformLayer()->masksToBounds()); | |
1081 } | |
1082 } | |
1083 | |
1084 TEST_P(CompositedLayerMappingTest, | 935 TEST_P(CompositedLayerMappingTest, |
1085 ScrollingLayerWithPerspectivePositionedCorrectly) { | 936 ScrollingLayerWithPerspectivePositionedCorrectly) { |
1086 // Test positioning of a scrolling layer within an offset parent, both with | 937 // Test positioning of a scrolling layer within an offset parent, both with |
1087 // and without perspective. | 938 // and without perspective. |
1088 // | 939 // |
1089 // When a box shadow is used, the main graphics layer position is offset by | 940 // When a box shadow is used, the main graphics layer position is offset by |
1090 // the shadow. The scrolling contents then need to be offset in the other | 941 // the shadow. The scrolling contents then need to be offset in the other |
1091 // direction to compensate. To make this a little clearer, for the first | 942 // direction to compensate. To make this a little clearer, for the first |
1092 // example here the layer positions are calculated as: | 943 // example here the layer positions are calculated as: |
1093 // | 944 // |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1730 | 1581 |
1731 constraint = stickyMapping->mainGraphicsLayer() | 1582 constraint = stickyMapping->mainGraphicsLayer() |
1732 ->contentLayer() | 1583 ->contentLayer() |
1733 ->layer() | 1584 ->layer() |
1734 ->stickyPositionConstraint(); | 1585 ->stickyPositionConstraint(); |
1735 EXPECT_EQ(IntPoint(0, 10), | 1586 EXPECT_EQ(IntPoint(0, 10), |
1736 IntPoint(constraint.parentRelativeStickyBoxOffset)); | 1587 IntPoint(constraint.parentRelativeStickyBoxOffset)); |
1737 } | 1588 } |
1738 | 1589 |
1739 } // namespace blink | 1590 } // namespace blink |
OLD | NEW |