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