1 // Copyright 2018 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 "third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h"
6
7 #include "cc/layers/picture_layer.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
10 #include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
11 #include "third_party/blink/renderer/core/paint/paint_layer.h"
12 #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
13 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
14 #include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
15
16 namespace blink {
17
18 class CompositingLayerPropertyUpdaterTest : public RenderingTest {
19 private:
SetUp()20 void SetUp() override {
21 EnableCompositing();
22 RenderingTest::SetUp();
23 }
24 };
25
TEST_F(CompositingLayerPropertyUpdaterTest,MaskLayerState)26 TEST_F(CompositingLayerPropertyUpdaterTest, MaskLayerState) {
27 SetBodyInnerHTML(R"HTML(
28 <div id=target style="position: absolute;
29 clip-path: polygon(-1px -1px, 86px 400px);
30 clip: rect(9px, -1px, -1px, 96px); will-change: transform">
31 </div>
32 )HTML");
33
34 PaintLayer* target =
35 ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
36 EXPECT_EQ(kPaintsIntoOwnBacking, target->GetCompositingState());
37 auto* mapping = target->GetCompositedLayerMapping();
38 auto* mask_layer = mapping->MaskLayer();
39
40 auto* paint_properties =
41 target->GetLayoutObject().FirstFragment().PaintProperties();
42 EXPECT_TRUE(paint_properties->CssClip());
43 EXPECT_TRUE(paint_properties->MaskClip());
44 EXPECT_EQ(paint_properties->MaskClip(),
45 &mask_layer->layer_state_->state.Clip());
46 }
47
TEST_F(CompositingLayerPropertyUpdaterTest,EnsureOverlayScrollbarLayerHasEffectNode)48 TEST_F(CompositingLayerPropertyUpdaterTest,
49 EnsureOverlayScrollbarLayerHasEffectNode) {
50 GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled(
51 true);
52 ASSERT_TRUE(GetDocument()
53 .GetFrame()
54 ->GetPage()
55 ->GetScrollbarTheme()
56 .UsesOverlayScrollbars());
57 SetBodyInnerHTML(R"HTML(
58 <style>
59 #scroller {
60 width: 100px;
61 height: 100px;
62 overflow: scroll;
63 }
64 #big {
65 width: 200px;
66 height: 200px;
67 }
68 </style>
69 <div id='scroller'>
70 <div id='big'></div>
71 </div>
72 )HTML");
73
74 PaintLayer* scroller_layer =
75 ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"))->Layer();
76 PaintLayerScrollableArea* scrollable_area =
77 scroller_layer->GetScrollableArea();
78 ASSERT_TRUE(scrollable_area);
79
80 auto* horizontal_scrollbar_layer =
81 scrollable_area->GraphicsLayerForHorizontalScrollbar();
82 auto* vertical_scrollbar_layer =
83 scrollable_area->GraphicsLayerForVerticalScrollbar();
84 ASSERT_TRUE(horizontal_scrollbar_layer);
85 ASSERT_TRUE(vertical_scrollbar_layer);
86
87 auto* paint_properties =
88 scroller_layer->GetLayoutObject().FirstFragment().PaintProperties();
89
90 // Ensure each overlay scrollbar has its own effect node and effect node has
91 // correct element_id.
92 EXPECT_EQ(paint_properties->HorizontalScrollbarEffect(),
93 &horizontal_scrollbar_layer->GetPropertyTreeState().Effect());
94 EXPECT_EQ(paint_properties->VerticalScrollbarEffect(),
95 &vertical_scrollbar_layer->GetPropertyTreeState().Effect());
96 EXPECT_NE(&horizontal_scrollbar_layer->GetPropertyTreeState().Effect(),
97 &vertical_scrollbar_layer->GetPropertyTreeState().Effect());
98 EXPECT_NE(horizontal_scrollbar_layer->GetPropertyTreeState()
99 .Effect()
100 .GetCompositorElementId(),
101 vertical_scrollbar_layer->GetPropertyTreeState()
102 .Effect()
103 .GetCompositorElementId());
104 EXPECT_EQ(horizontal_scrollbar_layer->GetPropertyTreeState()
105 .Effect()
106 .GetCompositorElementId(),
107 horizontal_scrollbar_layer->ContentsLayer()->element_id());
108 EXPECT_EQ(vertical_scrollbar_layer->GetPropertyTreeState()
109 .Effect()
110 .GetCompositorElementId(),
111 vertical_scrollbar_layer->ContentsLayer()->element_id());
112 }
113
TEST_F(CompositingLayerPropertyUpdaterTest,RootScrollbarShouldUseParentOfOverscrollNodeAsTransformNode)114 TEST_F(CompositingLayerPropertyUpdaterTest,
115 RootScrollbarShouldUseParentOfOverscrollNodeAsTransformNode) {
116 auto& document = GetDocument();
117 document.GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled(
118 true);
119 document.SetBaseURLOverride(KURL("http://test.com"));
120 SetBodyInnerHTML(R"HTML(
121 <style>
122 ::-webkit-scrollbar {
123 width: 12px;
124 background: darkblue;
125 }
126 ::-webkit-scrollbar-thumb {
127 background: white;
128 }
129 #scroller {
130 height: 100px;
131 overflow-y: scroll;
132 }
133 .big {
134 height: 1000px;
135 }
136 </style>
137
138 <div class='big'></div>
139 <div id='scroller'>
140 <div class='big'></div>
141 </div>
142 )HTML");
143
144 {
145 const auto* root_scrollable = document.View()->LayoutViewport();
146 const auto& visual_viewport =
147 document.View()->GetPage()->GetVisualViewport();
148
149 auto* vertical_scrollbar_layer =
150 root_scrollable->GraphicsLayerForVerticalScrollbar();
151 ASSERT_TRUE(vertical_scrollbar_layer);
152 EXPECT_EQ(&vertical_scrollbar_layer->GetPropertyTreeState().Transform(),
153 visual_viewport.GetOverscrollElasticityTransformNode()->Parent());
154 }
155
156 // Non root scrollbar should use scroller's transform node.
157 {
158 PaintLayer* scroller_layer =
159 ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"))->Layer();
160 PaintLayerScrollableArea* scrollable_area =
161 scroller_layer->GetScrollableArea();
162 ASSERT_TRUE(scrollable_area);
163
164 auto* vertical_scrollbar_layer =
165 scrollable_area->GraphicsLayerForVerticalScrollbar();
166 ASSERT_TRUE(vertical_scrollbar_layer);
167
168 auto paint_properties = scroller_layer->GetLayoutObject()
169 .FirstFragment()
170 .LocalBorderBoxProperties();
171
172 EXPECT_EQ(&vertical_scrollbar_layer->GetPropertyTreeState().Transform(),
173 &paint_properties.Transform());
174 }
175 }
176
177 } // namespace blink
178