OLD | NEW |
| (Empty) |
1 // Copyright 2011 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 "cc/layers/layer_impl.h" | |
6 | |
7 #include "cc/layers/painted_scrollbar_layer_impl.h" | |
8 #include "cc/layers/solid_color_scrollbar_layer_impl.h" | |
9 #include "cc/output/filter_operation.h" | |
10 #include "cc/output/filter_operations.h" | |
11 #include "cc/test/fake_impl_proxy.h" | |
12 #include "cc/test/fake_layer_tree_host_impl.h" | |
13 #include "cc/test/fake_output_surface.h" | |
14 #include "cc/test/geometry_test_utils.h" | |
15 #include "cc/test/test_shared_bitmap_manager.h" | |
16 #include "cc/test/test_task_graph_runner.h" | |
17 #include "cc/trees/layer_tree_impl.h" | |
18 #include "cc/trees/single_thread_proxy.h" | |
19 #include "cc/trees/tree_synchronizer.h" | |
20 #include "testing/gmock/include/gmock/gmock.h" | |
21 #include "testing/gtest/include/gtest/gtest.h" | |
22 #include "third_party/skia/include/effects/SkBlurImageFilter.h" | |
23 | |
24 namespace cc { | |
25 namespace { | |
26 | |
27 #define EXECUTE_AND_VERIFY_SUBTREE_CHANGED(code_to_test) \ | |
28 root->ResetAllChangeTrackingForSubtree(); \ | |
29 code_to_test; \ | |
30 EXPECT_TRUE(root->needs_push_properties()); \ | |
31 EXPECT_FALSE(child->needs_push_properties()); \ | |
32 EXPECT_FALSE(grand_child->needs_push_properties()); \ | |
33 EXPECT_TRUE(root->LayerPropertyChanged()); \ | |
34 EXPECT_TRUE(child->LayerPropertyChanged()); \ | |
35 EXPECT_TRUE(grand_child->LayerPropertyChanged()); | |
36 | |
37 #define EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(code_to_test) \ | |
38 root->ResetAllChangeTrackingForSubtree(); \ | |
39 code_to_test; \ | |
40 EXPECT_FALSE(root->needs_push_properties()); \ | |
41 EXPECT_FALSE(child->needs_push_properties()); \ | |
42 EXPECT_FALSE(grand_child->needs_push_properties()); \ | |
43 EXPECT_FALSE(root->LayerPropertyChanged()); \ | |
44 EXPECT_FALSE(child->LayerPropertyChanged()); \ | |
45 EXPECT_FALSE(grand_child->LayerPropertyChanged()); | |
46 | |
47 #define EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( \ | |
48 code_to_test) \ | |
49 root->ResetAllChangeTrackingForSubtree(); \ | |
50 code_to_test; \ | |
51 EXPECT_TRUE(root->needs_push_properties()); \ | |
52 EXPECT_FALSE(child->needs_push_properties()); \ | |
53 EXPECT_FALSE(grand_child->needs_push_properties()); \ | |
54 EXPECT_FALSE(root->LayerPropertyChanged()); \ | |
55 EXPECT_FALSE(child->LayerPropertyChanged()); \ | |
56 EXPECT_FALSE(grand_child->LayerPropertyChanged()); | |
57 | |
58 #define EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(code_to_test) \ | |
59 root->ResetAllChangeTrackingForSubtree(); \ | |
60 code_to_test; \ | |
61 EXPECT_TRUE(root->needs_push_properties()); \ | |
62 EXPECT_FALSE(child->needs_push_properties()); \ | |
63 EXPECT_FALSE(grand_child->needs_push_properties()); \ | |
64 EXPECT_TRUE(root->LayerPropertyChanged()); \ | |
65 EXPECT_FALSE(child->LayerPropertyChanged()); \ | |
66 EXPECT_FALSE(grand_child->LayerPropertyChanged()); | |
67 | |
68 #define VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test) \ | |
69 root->ResetAllChangeTrackingForSubtree(); \ | |
70 host_impl.ForcePrepareToDraw(); \ | |
71 EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties()); \ | |
72 code_to_test; \ | |
73 EXPECT_TRUE(host_impl.active_tree()->needs_update_draw_properties()); | |
74 | |
75 #define VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test) \ | |
76 root->ResetAllChangeTrackingForSubtree(); \ | |
77 host_impl.ForcePrepareToDraw(); \ | |
78 EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties()); \ | |
79 code_to_test; \ | |
80 EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties()); | |
81 | |
82 TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { | |
83 // | |
84 // This test checks that layerPropertyChanged() has the correct behavior. | |
85 // | |
86 | |
87 // The constructor on this will fake that we are on the correct thread. | |
88 // Create a simple LayerImpl tree: | |
89 FakeImplProxy proxy; | |
90 TestSharedBitmapManager shared_bitmap_manager; | |
91 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr); | |
92 EXPECT_TRUE(host_impl.InitializeRenderer(FakeOutputSurface::Create3d())); | |
93 scoped_ptr<LayerImpl> root_clip = | |
94 LayerImpl::Create(host_impl.active_tree(), 1); | |
95 scoped_ptr<LayerImpl> root_ptr = | |
96 LayerImpl::Create(host_impl.active_tree(), 2); | |
97 LayerImpl* root = root_ptr.get(); | |
98 root_clip->AddChild(root_ptr.Pass()); | |
99 scoped_ptr<LayerImpl> scroll_parent = | |
100 LayerImpl::Create(host_impl.active_tree(), 3); | |
101 LayerImpl* scroll_child = LayerImpl::Create(host_impl.active_tree(), 4).get(); | |
102 std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>(); | |
103 scroll_children->insert(scroll_child); | |
104 scroll_children->insert(root); | |
105 root->SetHasRenderSurface(true); | |
106 | |
107 scoped_ptr<LayerImpl> clip_parent = | |
108 LayerImpl::Create(host_impl.active_tree(), 5); | |
109 LayerImpl* clip_child = LayerImpl::Create(host_impl.active_tree(), 6).get(); | |
110 std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>(); | |
111 clip_children->insert(clip_child); | |
112 clip_children->insert(root); | |
113 | |
114 root->AddChild(LayerImpl::Create(host_impl.active_tree(), 7)); | |
115 LayerImpl* child = root->children()[0]; | |
116 child->AddChild(LayerImpl::Create(host_impl.active_tree(), 8)); | |
117 LayerImpl* grand_child = child->children()[0]; | |
118 | |
119 root->SetScrollClipLayer(root_clip->id()); | |
120 | |
121 // Adding children is an internal operation and should not mark layers as | |
122 // changed. | |
123 EXPECT_FALSE(root->LayerPropertyChanged()); | |
124 EXPECT_FALSE(child->LayerPropertyChanged()); | |
125 EXPECT_FALSE(grand_child->LayerPropertyChanged()); | |
126 | |
127 gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f); | |
128 gfx::Point3F arbitrary_point_3f = gfx::Point3F(0.125f, 0.25f, 0.f); | |
129 float arbitrary_number = 0.352f; | |
130 gfx::Size arbitrary_size = gfx::Size(111, 222); | |
131 gfx::Point arbitrary_point = gfx::Point(333, 444); | |
132 gfx::Vector2d arbitrary_vector2d = gfx::Vector2d(111, 222); | |
133 gfx::Rect arbitrary_rect = gfx::Rect(arbitrary_point, arbitrary_size); | |
134 gfx::RectF arbitrary_rect_f = | |
135 gfx::RectF(arbitrary_point_f, gfx::SizeF(1.234f, 5.678f)); | |
136 SkColor arbitrary_color = SkColorSetRGB(10, 20, 30); | |
137 gfx::Transform arbitrary_transform; | |
138 arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f); | |
139 FilterOperations arbitrary_filters; | |
140 arbitrary_filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); | |
141 SkXfermode::Mode arbitrary_blend_mode = SkXfermode::kMultiply_Mode; | |
142 | |
143 // These properties are internal, and should not be considered "change" when | |
144 // they are used. | |
145 EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( | |
146 root->SetUpdateRect(arbitrary_rect)); | |
147 EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetBounds(arbitrary_size)); | |
148 | |
149 // Changing these properties affects the entire subtree of layers. | |
150 EXECUTE_AND_VERIFY_SUBTREE_CHANGED( | |
151 root->SetTransformOrigin(arbitrary_point_3f)); | |
152 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(arbitrary_filters)); | |
153 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(FilterOperations())); | |
154 EXECUTE_AND_VERIFY_SUBTREE_CHANGED( | |
155 root->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 9))); | |
156 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetMasksToBounds(true)); | |
157 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetContentsOpaque(true)); | |
158 EXECUTE_AND_VERIFY_SUBTREE_CHANGED( | |
159 root->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 10))); | |
160 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetPosition(arbitrary_point_f)); | |
161 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetShouldFlattenTransform(false)); | |
162 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->Set3dSortingContextId(1)); | |
163 EXECUTE_AND_VERIFY_SUBTREE_CHANGED( | |
164 root->SetDoubleSided(false)); // constructor initializes it to "true". | |
165 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->ScrollBy(arbitrary_vector2d)); | |
166 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetScrollDelta(gfx::Vector2d())); | |
167 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->PushScrollOffsetFromMainThread( | |
168 gfx::ScrollOffset(arbitrary_vector2d))); | |
169 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetHideLayerAndSubtree(true)); | |
170 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetOpacity(arbitrary_number)); | |
171 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBlendMode(arbitrary_blend_mode)); | |
172 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetTransform(arbitrary_transform)); | |
173 | |
174 // Changing these properties only affects the layer itself. | |
175 EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetContentBounds(arbitrary_size)); | |
176 EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED( | |
177 root->SetContentsScale(arbitrary_number, arbitrary_number)); | |
178 EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetDrawsContent(true)); | |
179 EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED( | |
180 root->SetBackgroundColor(arbitrary_color)); | |
181 EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED( | |
182 root->SetBackgroundFilters(arbitrary_filters)); | |
183 | |
184 // Special case: check that SetBounds changes behavior depending on | |
185 // masksToBounds. | |
186 root->SetMasksToBounds(false); | |
187 EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetBounds(gfx::Size(135, 246))); | |
188 root->SetMasksToBounds(true); | |
189 // Should be a different size than previous call, to ensure it marks tree | |
190 // changed. | |
191 EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBounds(arbitrary_size)); | |
192 | |
193 // Changing this property does not cause the layer to be marked as changed | |
194 // but does cause the layer to need to push properties. | |
195 EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( | |
196 root->SetIsRootForIsolatedGroup(true)); | |
197 | |
198 // Changing these properties should cause the layer to need to push properties | |
199 EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( | |
200 root->SetScrollParent(scroll_parent.get())); | |
201 EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( | |
202 root->SetScrollChildren(scroll_children)); | |
203 EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( | |
204 root->SetClipParent(clip_parent.get())); | |
205 EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( | |
206 root->SetClipChildren(clip_children)); | |
207 EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( | |
208 root->SetNumDescendantsThatDrawContent(10)); | |
209 | |
210 // After setting all these properties already, setting to the exact same | |
211 // values again should not cause any change. | |
212 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
213 root->SetTransformOrigin(arbitrary_point_3f)); | |
214 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetMasksToBounds(true)); | |
215 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
216 root->SetPosition(arbitrary_point_f)); | |
217 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
218 root->SetShouldFlattenTransform(false)); | |
219 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->Set3dSortingContextId(1)); | |
220 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
221 root->SetTransform(arbitrary_transform)); | |
222 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
223 root->SetDoubleSided(false)); // constructor initializes it to "true". | |
224 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
225 root->SetScrollDelta(gfx::Vector2d())); | |
226 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
227 root->PushScrollOffsetFromMainThread( | |
228 gfx::ScrollOffset(arbitrary_vector2d))); | |
229 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
230 root->SetContentBounds(arbitrary_size)); | |
231 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
232 root->SetContentsScale(arbitrary_number, arbitrary_number)); | |
233 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetContentsOpaque(true)); | |
234 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetOpacity(arbitrary_number)); | |
235 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
236 root->SetBlendMode(arbitrary_blend_mode)); | |
237 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
238 root->SetIsRootForIsolatedGroup(true)); | |
239 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetDrawsContent(true)); | |
240 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetBounds(arbitrary_size)); | |
241 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
242 root->SetScrollParent(scroll_parent.get())); | |
243 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
244 root->SetScrollChildren(scroll_children)); | |
245 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
246 root->SetClipParent(clip_parent.get())); | |
247 EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( | |
248 root->SetClipChildren(clip_children)); | |
249 } | |
250 | |
251 TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { | |
252 FakeImplProxy proxy; | |
253 TestSharedBitmapManager shared_bitmap_manager; | |
254 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr); | |
255 EXPECT_TRUE(host_impl.InitializeRenderer(FakeOutputSurface::Create3d())); | |
256 host_impl.active_tree()->SetRootLayer( | |
257 LayerImpl::Create(host_impl.active_tree(), 1)); | |
258 LayerImpl* root = host_impl.active_tree()->root_layer(); | |
259 root->SetHasRenderSurface(true); | |
260 scoped_ptr<LayerImpl> layer_ptr = | |
261 LayerImpl::Create(host_impl.active_tree(), 2); | |
262 LayerImpl* layer = layer_ptr.get(); | |
263 root->AddChild(layer_ptr.Pass()); | |
264 layer->SetScrollClipLayer(root->id()); | |
265 DCHECK(host_impl.CanDraw()); | |
266 | |
267 gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f); | |
268 float arbitrary_number = 0.352f; | |
269 gfx::Size arbitrary_size = gfx::Size(111, 222); | |
270 gfx::Point arbitrary_point = gfx::Point(333, 444); | |
271 gfx::Vector2d arbitrary_vector2d = gfx::Vector2d(111, 222); | |
272 gfx::Size large_size = gfx::Size(1000, 1000); | |
273 gfx::Rect arbitrary_rect = gfx::Rect(arbitrary_point, arbitrary_size); | |
274 gfx::RectF arbitrary_rect_f = | |
275 gfx::RectF(arbitrary_point_f, gfx::SizeF(1.234f, 5.678f)); | |
276 SkColor arbitrary_color = SkColorSetRGB(10, 20, 30); | |
277 gfx::Transform arbitrary_transform; | |
278 arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f); | |
279 FilterOperations arbitrary_filters; | |
280 arbitrary_filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); | |
281 SkXfermode::Mode arbitrary_blend_mode = SkXfermode::kMultiply_Mode; | |
282 | |
283 // Render surface functions. | |
284 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(true)); | |
285 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(true)); | |
286 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(false)); | |
287 // Create a render surface, because we must have a render surface if we have | |
288 // filters. | |
289 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetHasRenderSurface(true)); | |
290 | |
291 // Related filter functions. | |
292 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters)); | |
293 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters)); | |
294 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(FilterOperations())); | |
295 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters)); | |
296 | |
297 // Related scrolling functions. | |
298 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(large_size)); | |
299 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(large_size)); | |
300 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->ScrollBy(arbitrary_vector2d)); | |
301 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->ScrollBy(gfx::Vector2d())); | |
302 layer->SetScrollDelta(gfx::Vector2d(0, 0)); | |
303 host_impl.ForcePrepareToDraw(); | |
304 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( | |
305 layer->SetScrollDelta(arbitrary_vector2d)); | |
306 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( | |
307 layer->SetScrollDelta(arbitrary_vector2d)); | |
308 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->PushScrollOffsetFromMainThread( | |
309 gfx::ScrollOffset(arbitrary_vector2d))); | |
310 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->PushScrollOffsetFromMainThread( | |
311 gfx::ScrollOffset(arbitrary_vector2d))); | |
312 | |
313 // Unrelated functions, always set to new values, always set needs update. | |
314 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( | |
315 layer->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 4))); | |
316 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetMasksToBounds(true)); | |
317 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true)); | |
318 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( | |
319 layer->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 5))); | |
320 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetPosition(arbitrary_point_f)); | |
321 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetShouldFlattenTransform(false)); | |
322 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->Set3dSortingContextId(1)); | |
323 | |
324 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( | |
325 layer->SetDoubleSided(false)); // constructor initializes it to "true". | |
326 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentBounds(arbitrary_size)); | |
327 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( | |
328 layer->SetContentsScale(arbitrary_number, arbitrary_number)); | |
329 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true)); | |
330 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( | |
331 layer->SetBackgroundColor(arbitrary_color)); | |
332 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( | |
333 layer->SetBackgroundFilters(arbitrary_filters)); | |
334 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetOpacity(arbitrary_number)); | |
335 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( | |
336 layer->SetBlendMode(arbitrary_blend_mode)); | |
337 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetTransform(arbitrary_transform)); | |
338 VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(arbitrary_size)); | |
339 | |
340 // Unrelated functions, set to the same values, no needs update. | |
341 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( | |
342 layer->SetIsRootForIsolatedGroup(true)); | |
343 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters)); | |
344 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetMasksToBounds(true)); | |
345 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true)); | |
346 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetPosition(arbitrary_point_f)); | |
347 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->Set3dSortingContextId(1)); | |
348 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( | |
349 layer->SetDoubleSided(false)); // constructor initializes it to "true". | |
350 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( | |
351 layer->SetContentBounds(arbitrary_size)); | |
352 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( | |
353 layer->SetContentsScale(arbitrary_number, arbitrary_number)); | |
354 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true)); | |
355 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( | |
356 layer->SetBackgroundColor(arbitrary_color)); | |
357 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( | |
358 layer->SetBackgroundFilters(arbitrary_filters)); | |
359 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetOpacity(arbitrary_number)); | |
360 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( | |
361 layer->SetBlendMode(arbitrary_blend_mode)); | |
362 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( | |
363 layer->SetIsRootForIsolatedGroup(true)); | |
364 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( | |
365 layer->SetTransform(arbitrary_transform)); | |
366 VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(arbitrary_size)); | |
367 } | |
368 | |
369 TEST(LayerImplTest, SafeOpaqueBackgroundColor) { | |
370 FakeImplProxy proxy; | |
371 TestSharedBitmapManager shared_bitmap_manager; | |
372 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr); | |
373 EXPECT_TRUE(host_impl.InitializeRenderer(FakeOutputSurface::Create3d())); | |
374 scoped_ptr<LayerImpl> layer = LayerImpl::Create(host_impl.active_tree(), 1); | |
375 | |
376 for (int contents_opaque = 0; contents_opaque < 2; ++contents_opaque) { | |
377 for (int layer_opaque = 0; layer_opaque < 2; ++layer_opaque) { | |
378 for (int host_opaque = 0; host_opaque < 2; ++host_opaque) { | |
379 layer->SetContentsOpaque(!!contents_opaque); | |
380 layer->SetBackgroundColor(layer_opaque ? SK_ColorRED | |
381 : SK_ColorTRANSPARENT); | |
382 host_impl.active_tree()->set_background_color( | |
383 host_opaque ? SK_ColorRED : SK_ColorTRANSPARENT); | |
384 | |
385 SkColor safe_color = layer->SafeOpaqueBackgroundColor(); | |
386 if (contents_opaque) { | |
387 EXPECT_EQ(SkColorGetA(safe_color), 255u) | |
388 << "Flags: " << contents_opaque << ", " << layer_opaque << ", " | |
389 << host_opaque << "\n"; | |
390 } else { | |
391 EXPECT_NE(SkColorGetA(safe_color), 255u) | |
392 << "Flags: " << contents_opaque << ", " << layer_opaque << ", " | |
393 << host_opaque << "\n"; | |
394 } | |
395 } | |
396 } | |
397 } | |
398 } | |
399 | |
400 TEST(LayerImplTest, TransformInvertibility) { | |
401 FakeImplProxy proxy; | |
402 TestSharedBitmapManager shared_bitmap_manager; | |
403 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr); | |
404 | |
405 scoped_ptr<LayerImpl> layer = LayerImpl::Create(host_impl.active_tree(), 1); | |
406 EXPECT_TRUE(layer->transform().IsInvertible()); | |
407 EXPECT_TRUE(layer->transform_is_invertible()); | |
408 | |
409 gfx::Transform transform; | |
410 transform.Scale3d( | |
411 SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), SkDoubleToMScalar(0.0)); | |
412 layer->SetTransform(transform); | |
413 EXPECT_FALSE(layer->transform().IsInvertible()); | |
414 EXPECT_FALSE(layer->transform_is_invertible()); | |
415 | |
416 transform.MakeIdentity(); | |
417 transform.ApplyPerspectiveDepth(SkDoubleToMScalar(100.0)); | |
418 transform.RotateAboutZAxis(75.0); | |
419 transform.RotateAboutXAxis(32.2); | |
420 transform.RotateAboutZAxis(-75.0); | |
421 transform.Translate3d(SkDoubleToMScalar(50.5), | |
422 SkDoubleToMScalar(42.42), | |
423 SkDoubleToMScalar(-100.25)); | |
424 | |
425 layer->SetTransform(transform); | |
426 EXPECT_TRUE(layer->transform().IsInvertible()); | |
427 EXPECT_TRUE(layer->transform_is_invertible()); | |
428 } | |
429 | |
430 class LayerImplScrollTest : public testing::Test { | |
431 public: | |
432 LayerImplScrollTest() | |
433 : host_impl_(settings(), | |
434 &proxy_, | |
435 &shared_bitmap_manager_, | |
436 &task_graph_runner_), | |
437 root_id_(7) { | |
438 host_impl_.active_tree()->SetRootLayer( | |
439 LayerImpl::Create(host_impl_.active_tree(), root_id_)); | |
440 host_impl_.active_tree()->root_layer()->AddChild( | |
441 LayerImpl::Create(host_impl_.active_tree(), root_id_ + 1)); | |
442 layer()->SetScrollClipLayer(root_id_); | |
443 // Set the max scroll offset by noting that the root layer has bounds (1,1), | |
444 // thus whatever bounds are set for the layer will be the max scroll | |
445 // offset plus 1 in each direction. | |
446 host_impl_.active_tree()->root_layer()->SetBounds(gfx::Size(1, 1)); | |
447 gfx::Vector2d max_scroll_offset(51, 81); | |
448 layer()->SetBounds(gfx::Size(max_scroll_offset.x(), max_scroll_offset.y())); | |
449 } | |
450 | |
451 LayerImpl* layer() { | |
452 return host_impl_.active_tree()->root_layer()->children()[0]; | |
453 } | |
454 | |
455 LayerTreeHostImpl& host_impl() { return host_impl_; } | |
456 | |
457 LayerTreeImpl* tree() { return host_impl_.active_tree(); } | |
458 | |
459 LayerTreeSettings settings() { | |
460 LayerTreeSettings settings; | |
461 settings.use_pinch_virtual_viewport = true; | |
462 return settings; | |
463 } | |
464 | |
465 private: | |
466 FakeImplProxy proxy_; | |
467 TestSharedBitmapManager shared_bitmap_manager_; | |
468 TestTaskGraphRunner task_graph_runner_; | |
469 FakeLayerTreeHostImpl host_impl_; | |
470 int root_id_; | |
471 }; | |
472 | |
473 TEST_F(LayerImplScrollTest, ScrollByWithZeroOffset) { | |
474 // Test that LayerImpl::ScrollBy only affects ScrollDelta and total scroll | |
475 // offset is bounded by the range [0, max scroll offset]. | |
476 | |
477 EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->CurrentScrollOffset()); | |
478 EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->BaseScrollOffset()); | |
479 EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta()); | |
480 | |
481 layer()->ScrollBy(gfx::Vector2dF(-100, 100)); | |
482 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->CurrentScrollOffset()); | |
483 | |
484 EXPECT_VECTOR_EQ(layer()->ScrollDelta(), layer()->CurrentScrollOffset()); | |
485 EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->BaseScrollOffset()); | |
486 | |
487 layer()->ScrollBy(gfx::Vector2dF(100, -100)); | |
488 EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), layer()->CurrentScrollOffset()); | |
489 | |
490 EXPECT_VECTOR_EQ(layer()->ScrollDelta(), layer()->CurrentScrollOffset()); | |
491 EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->BaseScrollOffset()); | |
492 } | |
493 | |
494 TEST_F(LayerImplScrollTest, ScrollByWithNonZeroOffset) { | |
495 gfx::ScrollOffset scroll_offset(10, 5); | |
496 layer()->PushScrollOffsetFromMainThread(scroll_offset); | |
497 | |
498 EXPECT_VECTOR_EQ(scroll_offset, layer()->CurrentScrollOffset()); | |
499 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
500 EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta()); | |
501 | |
502 layer()->ScrollBy(gfx::Vector2dF(-100, 100)); | |
503 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->CurrentScrollOffset()); | |
504 | |
505 EXPECT_VECTOR_EQ( | |
506 gfx::ScrollOffsetWithDelta(scroll_offset, layer()->ScrollDelta()), | |
507 layer()->CurrentScrollOffset()); | |
508 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
509 | |
510 layer()->ScrollBy(gfx::Vector2dF(100, -100)); | |
511 EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), layer()->CurrentScrollOffset()); | |
512 | |
513 EXPECT_VECTOR_EQ( | |
514 gfx::ScrollOffsetWithDelta(scroll_offset, layer()->ScrollDelta()), | |
515 layer()->CurrentScrollOffset()); | |
516 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
517 } | |
518 | |
519 class ScrollDelegateIgnore : public LayerImpl::ScrollOffsetDelegate { | |
520 public: | |
521 void SetCurrentScrollOffset(const gfx::ScrollOffset& new_value) override { | |
522 last_attempted_set_offset_ = new_value; | |
523 } | |
524 gfx::ScrollOffset last_attempted_set_offset() const { | |
525 return last_attempted_set_offset_; | |
526 } | |
527 | |
528 gfx::ScrollOffset GetCurrentScrollOffset() override { | |
529 return gfx::ScrollOffset(fixed_offset_); | |
530 } | |
531 bool IsExternalFlingActive() const override { return false; } | |
532 void Update() const override { } | |
533 | |
534 void set_fixed_offset(const gfx::Vector2dF& fixed_offset) { | |
535 fixed_offset_ = fixed_offset; | |
536 } | |
537 | |
538 private: | |
539 gfx::ScrollOffset last_attempted_set_offset_; | |
540 gfx::Vector2dF fixed_offset_; | |
541 }; | |
542 | |
543 TEST_F(LayerImplScrollTest, ScrollByWithIgnoringDelegate) { | |
544 gfx::ScrollOffset scroll_offset(10, 5); | |
545 layer()->PushScrollOffsetFromMainThread(scroll_offset); | |
546 | |
547 EXPECT_VECTOR_EQ(scroll_offset, layer()->CurrentScrollOffset()); | |
548 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
549 EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta()); | |
550 | |
551 ScrollDelegateIgnore delegate; | |
552 gfx::Vector2dF fixed_offset(32, 12); | |
553 delegate.set_fixed_offset(fixed_offset); | |
554 layer()->SetScrollOffsetDelegate(&delegate); | |
555 layer()->RefreshFromScrollDelegate(); | |
556 | |
557 EXPECT_VECTOR_EQ(fixed_offset, layer()->CurrentScrollOffset()); | |
558 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
559 | |
560 layer()->ScrollBy(gfx::Vector2dF(-100, 100)); | |
561 | |
562 EXPECT_VECTOR_EQ(fixed_offset, layer()->CurrentScrollOffset()); | |
563 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
564 | |
565 layer()->SetScrollOffsetDelegate(nullptr); | |
566 | |
567 EXPECT_VECTOR_EQ(fixed_offset, layer()->CurrentScrollOffset()); | |
568 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
569 | |
570 gfx::Vector2dF scroll_delta(1, 1); | |
571 layer()->ScrollBy(scroll_delta); | |
572 | |
573 EXPECT_VECTOR_EQ(fixed_offset + scroll_delta, layer()->CurrentScrollOffset()); | |
574 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
575 } | |
576 | |
577 class ScrollDelegateAccept : public LayerImpl::ScrollOffsetDelegate { | |
578 public: | |
579 void SetCurrentScrollOffset(const gfx::ScrollOffset& new_value) override { | |
580 current_offset_ = new_value; | |
581 } | |
582 gfx::ScrollOffset GetCurrentScrollOffset() override { | |
583 return current_offset_; | |
584 } | |
585 bool IsExternalFlingActive() const override { return false; } | |
586 void Update() const override { } | |
587 | |
588 private: | |
589 gfx::ScrollOffset current_offset_; | |
590 }; | |
591 | |
592 TEST_F(LayerImplScrollTest, ScrollByWithAcceptingDelegate) { | |
593 gfx::ScrollOffset scroll_offset(10, 5); | |
594 layer()->PushScrollOffsetFromMainThread(scroll_offset); | |
595 | |
596 EXPECT_VECTOR_EQ(scroll_offset, layer()->CurrentScrollOffset()); | |
597 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
598 EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta()); | |
599 | |
600 ScrollDelegateAccept delegate; | |
601 layer()->SetScrollOffsetDelegate(&delegate); | |
602 | |
603 EXPECT_VECTOR_EQ(scroll_offset, layer()->CurrentScrollOffset()); | |
604 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
605 EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta()); | |
606 | |
607 layer()->ScrollBy(gfx::Vector2dF(-100, 100)); | |
608 | |
609 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->CurrentScrollOffset()); | |
610 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
611 | |
612 layer()->SetScrollOffsetDelegate(nullptr); | |
613 | |
614 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->CurrentScrollOffset()); | |
615 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
616 | |
617 gfx::Vector2dF scroll_delta(1, 1); | |
618 layer()->ScrollBy(scroll_delta); | |
619 | |
620 EXPECT_VECTOR_EQ(gfx::Vector2dF(1, 80), layer()->CurrentScrollOffset()); | |
621 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
622 } | |
623 | |
624 TEST_F(LayerImplScrollTest, ApplySentScrollsNoDelegate) { | |
625 gfx::ScrollOffset scroll_offset(10, 5); | |
626 gfx::Vector2dF scroll_delta(20.5f, 8.5f); | |
627 gfx::Vector2d sent_scroll_delta(12, -3); | |
628 | |
629 layer()->PushScrollOffsetFromMainThread(scroll_offset); | |
630 layer()->ScrollBy(sent_scroll_delta); | |
631 layer()->PullDeltaForMainThread(); | |
632 layer()->SetCurrentScrollOffset(scroll_offset + | |
633 gfx::ScrollOffset(scroll_delta)); | |
634 | |
635 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta), | |
636 layer()->CurrentScrollOffset()); | |
637 EXPECT_VECTOR_EQ(scroll_delta, layer()->ScrollDelta()); | |
638 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
639 | |
640 layer()->ApplySentScrollDeltasFromAbortedCommit(); | |
641 | |
642 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta), | |
643 layer()->CurrentScrollOffset()); | |
644 EXPECT_VECTOR_EQ(scroll_delta - sent_scroll_delta, layer()->ScrollDelta()); | |
645 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, sent_scroll_delta), | |
646 layer()->BaseScrollOffset()); | |
647 } | |
648 | |
649 TEST_F(LayerImplScrollTest, ApplySentScrollsWithIgnoringDelegate) { | |
650 gfx::ScrollOffset scroll_offset(10, 5); | |
651 gfx::Vector2d sent_scroll_delta(12, -3); | |
652 gfx::Vector2dF fixed_offset(32, 12); | |
653 | |
654 layer()->PushScrollOffsetFromMainThread(scroll_offset); | |
655 layer()->ScrollBy(sent_scroll_delta); | |
656 layer()->PullDeltaForMainThread(); | |
657 layer()->SetCurrentScrollOffset(scroll_offset); | |
658 ScrollDelegateIgnore delegate; | |
659 delegate.set_fixed_offset(fixed_offset); | |
660 layer()->SetScrollOffsetDelegate(&delegate); | |
661 layer()->RefreshFromScrollDelegate(); | |
662 | |
663 EXPECT_VECTOR_EQ(fixed_offset, layer()->CurrentScrollOffset()); | |
664 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
665 | |
666 layer()->ApplySentScrollDeltasFromAbortedCommit(); | |
667 | |
668 EXPECT_VECTOR_EQ(fixed_offset, delegate.last_attempted_set_offset()); | |
669 | |
670 EXPECT_VECTOR_EQ(fixed_offset, layer()->CurrentScrollOffset()); | |
671 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, sent_scroll_delta), | |
672 layer()->BaseScrollOffset()); | |
673 } | |
674 | |
675 TEST_F(LayerImplScrollTest, ApplySentScrollsWithAcceptingDelegate) { | |
676 gfx::ScrollOffset scroll_offset(10, 5); | |
677 gfx::Vector2d sent_scroll_delta(12, -3); | |
678 gfx::Vector2dF scroll_delta(20.5f, 8.5f); | |
679 | |
680 layer()->PushScrollOffsetFromMainThread(scroll_offset); | |
681 layer()->ScrollBy(sent_scroll_delta); | |
682 layer()->PullDeltaForMainThread(); | |
683 ScrollDelegateAccept delegate; | |
684 layer()->SetScrollOffsetDelegate(&delegate); | |
685 layer()->SetCurrentScrollOffset(scroll_offset + | |
686 gfx::ScrollOffset(scroll_delta)); | |
687 | |
688 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta), | |
689 layer()->CurrentScrollOffset()); | |
690 EXPECT_VECTOR_EQ(scroll_offset, layer()->BaseScrollOffset()); | |
691 | |
692 layer()->ApplySentScrollDeltasFromAbortedCommit(); | |
693 | |
694 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta), | |
695 layer()->CurrentScrollOffset()); | |
696 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, sent_scroll_delta), | |
697 layer()->BaseScrollOffset()); | |
698 } | |
699 | |
700 TEST_F(LayerImplScrollTest, ScrollUserUnscrollableLayer) { | |
701 gfx::ScrollOffset scroll_offset(10, 5); | |
702 gfx::Vector2dF scroll_delta(20.5f, 8.5f); | |
703 | |
704 layer()->set_user_scrollable_vertical(false); | |
705 layer()->PushScrollOffsetFromMainThread(scroll_offset); | |
706 gfx::Vector2dF unscrolled = layer()->ScrollBy(scroll_delta); | |
707 | |
708 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 8.5f), unscrolled); | |
709 EXPECT_VECTOR_EQ(gfx::Vector2dF(30.5f, 5), layer()->CurrentScrollOffset()); | |
710 } | |
711 | |
712 TEST_F(LayerImplScrollTest, PushPropertiesToMirrorsCurrentScrollOffset) { | |
713 gfx::ScrollOffset scroll_offset(10, 5); | |
714 gfx::Vector2dF scroll_delta(12, 18); | |
715 | |
716 host_impl().CreatePendingTree(); | |
717 | |
718 layer()->PushScrollOffsetFromMainThread(scroll_offset); | |
719 gfx::Vector2dF unscrolled = layer()->ScrollBy(scroll_delta); | |
720 | |
721 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), unscrolled); | |
722 EXPECT_VECTOR_EQ(gfx::Vector2dF(22, 23), layer()->CurrentScrollOffset()); | |
723 | |
724 layer()->PullDeltaForMainThread(); | |
725 | |
726 scoped_ptr<LayerImpl> pending_layer = LayerImpl::Create( | |
727 host_impl().sync_tree(), layer()->id(), layer()->synced_scroll_offset()); | |
728 pending_layer->PushScrollOffsetFromMainThread(layer()->CurrentScrollOffset()); | |
729 | |
730 pending_layer->PushPropertiesTo(layer()); | |
731 | |
732 EXPECT_VECTOR_EQ(gfx::Vector2dF(22, 23), layer()->CurrentScrollOffset()); | |
733 EXPECT_VECTOR_EQ(layer()->CurrentScrollOffset(), | |
734 pending_layer->CurrentScrollOffset()); | |
735 } | |
736 | |
737 TEST_F(LayerImplScrollTest, SetNewScrollbarParameters) { | |
738 gfx::ScrollOffset scroll_offset(10, 5); | |
739 layer()->PushScrollOffsetFromMainThread(scroll_offset); | |
740 | |
741 scoped_ptr<PaintedScrollbarLayerImpl> vertical_scrollbar( | |
742 PaintedScrollbarLayerImpl::Create(tree(), 100, VERTICAL)); | |
743 vertical_scrollbar->SetScrollLayerAndClipLayerByIds( | |
744 layer()->id(), tree()->root_layer()->id()); | |
745 | |
746 int expected_vertical_maximum = | |
747 layer()->bounds().height() - tree()->root_layer()->bounds().height(); | |
748 EXPECT_EQ(expected_vertical_maximum, vertical_scrollbar->maximum()); | |
749 EXPECT_EQ(scroll_offset.y(), vertical_scrollbar->current_pos()); | |
750 | |
751 scoped_ptr<PaintedScrollbarLayerImpl> horizontal_scrollbar( | |
752 PaintedScrollbarLayerImpl::Create(tree(), 101, HORIZONTAL)); | |
753 horizontal_scrollbar->SetScrollLayerAndClipLayerByIds( | |
754 layer()->id(), tree()->root_layer()->id()); | |
755 | |
756 int expected_horizontal_maximum = | |
757 layer()->bounds().width() - tree()->root_layer()->bounds().width(); | |
758 EXPECT_EQ(expected_horizontal_maximum, horizontal_scrollbar->maximum()); | |
759 EXPECT_EQ(scroll_offset.x(), horizontal_scrollbar->current_pos()); | |
760 } | |
761 | |
762 class LayerImplScrollbarSyncTest : public testing::Test { | |
763 public: | |
764 enum { | |
765 ROOT = 1, | |
766 IV_CLIP = 2, | |
767 PAGE = 3, | |
768 IV_SCROLL = 4, | |
769 SCROLLBAR = 5, | |
770 OLD_ROOT = 6, | |
771 OV_CLIP = 7, | |
772 OV_SCROLL = 8, | |
773 }; | |
774 enum TreeID { | |
775 PENDING, | |
776 ACTIVE | |
777 }; | |
778 | |
779 LayerImplScrollbarSyncTest() | |
780 : host_impl_(settings(), | |
781 &proxy_, | |
782 &shared_bitmap_manager_, | |
783 &task_graph_runner_) { | |
784 host_impl_.CreatePendingTree(); | |
785 | |
786 CreateLayers(host_impl_.pending_tree()); | |
787 CreateLayers(host_impl_.active_tree()); | |
788 } | |
789 | |
790 void CreateLayers(LayerTreeImpl * tree) { | |
791 tree->SetRootLayer(LayerImpl::Create(tree, ROOT)); | |
792 LayerImpl * root = tree->root_layer(); | |
793 ASSERT_TRUE(root != nullptr); | |
794 | |
795 int hierarchy[] = {IV_CLIP, PAGE, IV_SCROLL, OLD_ROOT, OV_CLIP, OV_SCROLL}; | |
796 LayerImpl * parent = root; | |
797 for (int child_id : hierarchy) { | |
798 parent->AddChild(LayerImpl::Create(tree, child_id)); | |
799 parent = tree->LayerById(child_id); | |
800 ASSERT_TRUE(parent != nullptr); | |
801 } | |
802 | |
803 root->AddChild( | |
804 SolidColorScrollbarLayerImpl::Create(tree, SCROLLBAR, HORIZONTAL, | |
805 5, 5, false, true)); | |
806 } | |
807 | |
808 LayerImpl* layer(int id, TreeID tree_id) { | |
809 LayerTreeImpl* tree = | |
810 ((tree_id == PENDING) ? | |
811 host_impl_.pending_tree() : host_impl_.active_tree()); | |
812 | |
813 assert(tree); | |
814 return tree->LayerById(id); | |
815 } | |
816 | |
817 bool LayerHasScrollbar(int id, TreeID tree_id) { | |
818 return layer(id, tree_id)->HasScrollbar(HORIZONTAL); | |
819 } | |
820 | |
821 ScrollbarLayerImplBase* pending_scrollbar() { | |
822 LayerImpl* layer_impl = layer(SCROLLBAR, PENDING); | |
823 assert(layer_impl); | |
824 return layer_impl->ToScrollbarLayer(); | |
825 } | |
826 | |
827 LayerImpl* pending_root() { | |
828 LayerImpl * result = layer(ROOT, PENDING); | |
829 assert(result); | |
830 return result; | |
831 } | |
832 | |
833 LayerImpl* active_root() { | |
834 LayerImpl * result = layer(ROOT, ACTIVE); | |
835 assert(result); | |
836 return result; | |
837 } | |
838 | |
839 LayerTreeSettings settings() { | |
840 LayerTreeSettings settings; | |
841 settings.use_pinch_virtual_viewport = true; | |
842 return settings; | |
843 } | |
844 | |
845 private: | |
846 FakeImplProxy proxy_; | |
847 TestSharedBitmapManager shared_bitmap_manager_; | |
848 TestTaskGraphRunner task_graph_runner_; | |
849 FakeLayerTreeHostImpl host_impl_; | |
850 }; | |
851 | |
852 TEST_F(LayerImplScrollbarSyncTest, LayerImplBecomesScrollable) { | |
853 // In the beginning IV_SCROLL layer is not scrollable. | |
854 ASSERT_FALSE(layer(IV_SCROLL, PENDING)->scrollable()); | |
855 | |
856 // For pinch virtual viewport the clip layer is the inner viewport | |
857 // clip layer (IV_CLIP) and the scroll one is the outer viewport | |
858 // scroll layer (OV_SCROLL). | |
859 pending_scrollbar()->SetScrollLayerAndClipLayerByIds(OV_SCROLL, IV_CLIP); | |
860 | |
861 ASSERT_TRUE(LayerHasScrollbar(OV_SCROLL, PENDING)); | |
862 ASSERT_TRUE(LayerHasScrollbar(IV_CLIP, PENDING)); | |
863 | |
864 // Synchronize with the active tree. | |
865 TreeSynchronizer::PushProperties(pending_root(), active_root()); | |
866 | |
867 ASSERT_TRUE(LayerHasScrollbar(OV_SCROLL, ACTIVE)); | |
868 ASSERT_TRUE(LayerHasScrollbar(IV_CLIP, ACTIVE)); | |
869 | |
870 // Make IV_SCROLL layer scrollable. | |
871 layer(IV_SCROLL, PENDING)->SetScrollClipLayer(IV_CLIP); | |
872 layer(IV_SCROLL, PENDING)->SetNeedsPushProperties(); | |
873 ASSERT_TRUE(layer(IV_SCROLL, PENDING)->scrollable()); | |
874 | |
875 pending_scrollbar()->SetScrollLayerAndClipLayerByIds(OV_SCROLL, IV_CLIP); | |
876 | |
877 // Now IV_CLIP layer should also receive the scrollbar. | |
878 ASSERT_TRUE(LayerHasScrollbar(OV_SCROLL, PENDING)); | |
879 ASSERT_TRUE(LayerHasScrollbar(IV_CLIP, PENDING)); | |
880 ASSERT_TRUE(LayerHasScrollbar(IV_SCROLL, PENDING)); | |
881 | |
882 // Synchronize with the active tree. | |
883 TreeSynchronizer::PushProperties(pending_root(), active_root()); | |
884 | |
885 ASSERT_TRUE(layer(IV_SCROLL, ACTIVE)->scrollable()); | |
886 | |
887 ASSERT_TRUE(LayerHasScrollbar(OV_SCROLL, ACTIVE)); | |
888 ASSERT_TRUE(LayerHasScrollbar(IV_CLIP, ACTIVE)); | |
889 ASSERT_TRUE(LayerHasScrollbar(IV_SCROLL, ACTIVE)); | |
890 } | |
891 | |
892 } // namespace | |
893 } // namespace cc | |
OLD | NEW |