OLD | NEW |
| (Empty) |
1 // Copyright 2012 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/trees/layer_tree_host.h" | |
6 | |
7 #include "base/memory/weak_ptr.h" | |
8 #include "cc/layers/layer.h" | |
9 #include "cc/layers/layer_impl.h" | |
10 #include "cc/layers/picture_layer.h" | |
11 #include "cc/scheduler/begin_frame_source.h" | |
12 #include "cc/test/fake_content_layer_client.h" | |
13 #include "cc/test/fake_layer_tree_host_client.h" | |
14 #include "cc/test/fake_picture_layer.h" | |
15 #include "cc/test/fake_picture_layer_impl.h" | |
16 #include "cc/test/geometry_test_utils.h" | |
17 #include "cc/test/layer_tree_test.h" | |
18 #include "cc/test/test_shared_bitmap_manager.h" | |
19 #include "cc/trees/layer_tree_impl.h" | |
20 #include "ui/gfx/geometry/point_conversions.h" | |
21 #include "ui/gfx/geometry/size_conversions.h" | |
22 #include "ui/gfx/geometry/vector2d_conversions.h" | |
23 | |
24 namespace cc { | |
25 namespace { | |
26 | |
27 class LayerTreeHostScrollTest : public LayerTreeTest {}; | |
28 | |
29 class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { | |
30 public: | |
31 LayerTreeHostScrollTestScrollSimple() | |
32 : initial_scroll_(10, 20), | |
33 second_scroll_(40, 5), | |
34 scroll_amount_(2, -1), | |
35 num_scrolls_(0) {} | |
36 | |
37 void BeginTest() override { | |
38 Layer* root_layer = layer_tree_host()->root_layer(); | |
39 scoped_refptr<Layer> scroll_layer = Layer::Create(); | |
40 root_layer->AddChild(scroll_layer); | |
41 // Create an effective max_scroll_offset of (100, 100). | |
42 scroll_layer->SetBounds(gfx::Size(root_layer->bounds().width() + 100, | |
43 root_layer->bounds().height() + 100)); | |
44 scroll_layer->SetIsDrawable(true); | |
45 scroll_layer->SetIsContainerForFixedPositionLayers(true); | |
46 scroll_layer->SetScrollClipLayerId(root_layer->id()); | |
47 scroll_layer->SetScrollOffset(initial_scroll_); | |
48 layer_tree_host()->RegisterViewportLayers(NULL, root_layer, scroll_layer, | |
49 NULL); | |
50 PostSetNeedsCommitToMainThread(); | |
51 } | |
52 | |
53 void Layout() override { | |
54 Layer* root = layer_tree_host()->root_layer(); | |
55 Layer* scroll_layer = root->children()[0].get(); | |
56 if (!layer_tree_host()->source_frame_number()) { | |
57 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset()); | |
58 } else { | |
59 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, | |
60 scroll_amount_), | |
61 scroll_layer->scroll_offset()); | |
62 | |
63 // Pretend like Javascript updated the scroll position itself. | |
64 scroll_layer->SetScrollOffset(second_scroll_); | |
65 } | |
66 } | |
67 | |
68 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
69 LayerImpl* root = impl->active_tree()->root_layer(); | |
70 LayerImpl* scroll_layer = root->children()[0]; | |
71 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer->ScrollDelta()); | |
72 | |
73 scroll_layer->SetScrollClipLayer(root->id()); | |
74 scroll_layer->SetBounds( | |
75 gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); | |
76 scroll_layer->ScrollBy(scroll_amount_); | |
77 | |
78 switch (impl->active_tree()->source_frame_number()) { | |
79 case 0: | |
80 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->BaseScrollOffset()); | |
81 EXPECT_VECTOR_EQ(scroll_amount_, scroll_layer->ScrollDelta()); | |
82 PostSetNeedsCommitToMainThread(); | |
83 break; | |
84 case 1: | |
85 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), second_scroll_); | |
86 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), scroll_amount_); | |
87 EndTest(); | |
88 break; | |
89 } | |
90 } | |
91 | |
92 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, | |
93 float scale, | |
94 float top_controls_delta) override { | |
95 num_scrolls_++; | |
96 } | |
97 | |
98 void AfterTest() override { EXPECT_EQ(1, num_scrolls_); } | |
99 | |
100 private: | |
101 gfx::ScrollOffset initial_scroll_; | |
102 gfx::ScrollOffset second_scroll_; | |
103 gfx::Vector2dF scroll_amount_; | |
104 int num_scrolls_; | |
105 }; | |
106 | |
107 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple); | |
108 | |
109 class LayerTreeHostScrollTestScrollMultipleRedraw | |
110 : public LayerTreeHostScrollTest { | |
111 public: | |
112 LayerTreeHostScrollTestScrollMultipleRedraw() | |
113 : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {} | |
114 | |
115 void BeginTest() override { | |
116 Layer* root_layer = layer_tree_host()->root_layer(); | |
117 scroll_layer_ = Layer::Create(); | |
118 root_layer->AddChild(scroll_layer_); | |
119 // Create an effective max_scroll_offset of (100, 100). | |
120 scroll_layer_->SetBounds(gfx::Size(root_layer->bounds().width() + 100, | |
121 root_layer->bounds().height() + 100)); | |
122 scroll_layer_->SetIsDrawable(true); | |
123 scroll_layer_->SetIsContainerForFixedPositionLayers(true); | |
124 scroll_layer_->SetScrollClipLayerId(root_layer->id()); | |
125 scroll_layer_->SetScrollOffset(initial_scroll_); | |
126 layer_tree_host()->RegisterViewportLayers(NULL, root_layer, scroll_layer_, | |
127 NULL); | |
128 PostSetNeedsCommitToMainThread(); | |
129 } | |
130 | |
131 void BeginCommitOnThread(LayerTreeHostImpl* impl) override { | |
132 switch (layer_tree_host()->source_frame_number()) { | |
133 case 0: | |
134 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_); | |
135 break; | |
136 case 1: | |
137 EXPECT_VECTOR_EQ( | |
138 scroll_layer_->scroll_offset(), | |
139 gfx::ScrollOffsetWithDelta(initial_scroll_, | |
140 scroll_amount_ + scroll_amount_)); | |
141 case 2: | |
142 EXPECT_VECTOR_EQ( | |
143 scroll_layer_->scroll_offset(), | |
144 gfx::ScrollOffsetWithDelta(initial_scroll_, | |
145 scroll_amount_ + scroll_amount_)); | |
146 break; | |
147 } | |
148 } | |
149 | |
150 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
151 LayerImpl* scroll_layer = | |
152 impl->active_tree()->LayerById(scroll_layer_->id()); | |
153 if (impl->active_tree()->source_frame_number() == 0 && | |
154 impl->SourceAnimationFrameNumber() == 1) { | |
155 // First draw after first commit. | |
156 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d()); | |
157 scroll_layer->ScrollBy(scroll_amount_); | |
158 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), scroll_amount_); | |
159 | |
160 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), initial_scroll_); | |
161 PostSetNeedsRedrawToMainThread(); | |
162 } else if (impl->active_tree()->source_frame_number() == 0 && | |
163 impl->SourceAnimationFrameNumber() == 2) { | |
164 // Second draw after first commit. | |
165 EXPECT_EQ(scroll_layer->ScrollDelta(), scroll_amount_); | |
166 scroll_layer->ScrollBy(scroll_amount_); | |
167 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), | |
168 scroll_amount_ + scroll_amount_); | |
169 | |
170 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_); | |
171 PostSetNeedsCommitToMainThread(); | |
172 } else if (impl->active_tree()->source_frame_number() == 1) { | |
173 // Third or later draw after second commit. | |
174 EXPECT_GE(impl->SourceAnimationFrameNumber(), 3); | |
175 EXPECT_VECTOR_EQ(scroll_layer_->ScrollDelta(), gfx::Vector2d()); | |
176 EXPECT_VECTOR_EQ( | |
177 scroll_layer_->scroll_offset(), | |
178 gfx::ScrollOffsetWithDelta(initial_scroll_, | |
179 scroll_amount_ + scroll_amount_)); | |
180 EndTest(); | |
181 } | |
182 } | |
183 | |
184 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, | |
185 float scale, | |
186 float top_controls_delta) override { | |
187 num_scrolls_++; | |
188 } | |
189 | |
190 void AfterTest() override { EXPECT_EQ(1, num_scrolls_); } | |
191 | |
192 private: | |
193 gfx::ScrollOffset initial_scroll_; | |
194 gfx::Vector2dF scroll_amount_; | |
195 int num_scrolls_; | |
196 scoped_refptr<Layer> scroll_layer_; | |
197 }; | |
198 | |
199 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw); | |
200 | |
201 class LayerTreeHostScrollTestScrollAbortedCommit | |
202 : public LayerTreeHostScrollTest { | |
203 public: | |
204 LayerTreeHostScrollTestScrollAbortedCommit() | |
205 : initial_scroll_(50, 60), | |
206 impl_scroll_(-3, 2), | |
207 second_main_scroll_(14, -3), | |
208 impl_scale_(2.f), | |
209 num_will_begin_main_frames_(0), | |
210 num_did_begin_main_frames_(0), | |
211 num_will_commits_(0), | |
212 num_did_commits_(0), | |
213 num_impl_commits_(0), | |
214 num_impl_scrolls_(0) {} | |
215 | |
216 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
217 | |
218 void SetupTree() override { | |
219 LayerTreeHostScrollTest::SetupTree(); | |
220 Layer* root_layer = layer_tree_host()->root_layer(); | |
221 scoped_refptr<Layer> root_scroll_layer = Layer::Create(); | |
222 root_scroll_layer->SetScrollClipLayerId(root_layer->id()); | |
223 root_scroll_layer->SetScrollOffset(initial_scroll_); | |
224 root_scroll_layer->SetBounds(gfx::Size(200, 200)); | |
225 root_scroll_layer->SetIsDrawable(true); | |
226 root_scroll_layer->SetIsContainerForFixedPositionLayers(true); | |
227 root_layer->AddChild(root_scroll_layer); | |
228 | |
229 layer_tree_host()->RegisterViewportLayers(NULL, root_layer, | |
230 root_scroll_layer, NULL); | |
231 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); | |
232 } | |
233 | |
234 void WillBeginMainFrame() override { | |
235 num_will_begin_main_frames_++; | |
236 Layer* root_scroll_layer = | |
237 layer_tree_host()->root_layer()->children()[0].get(); | |
238 switch (num_will_begin_main_frames_) { | |
239 case 1: | |
240 // This will not be aborted because of the initial prop changes. | |
241 EXPECT_EQ(0, num_impl_scrolls_); | |
242 EXPECT_EQ(0, layer_tree_host()->source_frame_number()); | |
243 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_); | |
244 EXPECT_EQ(1.f, layer_tree_host()->page_scale_factor()); | |
245 break; | |
246 case 2: | |
247 // This commit will be aborted, and another commit will be | |
248 // initiated from the redraw. | |
249 EXPECT_EQ(1, num_impl_scrolls_); | |
250 EXPECT_EQ(1, layer_tree_host()->source_frame_number()); | |
251 EXPECT_VECTOR_EQ( | |
252 root_scroll_layer->scroll_offset(), | |
253 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_)); | |
254 EXPECT_EQ(impl_scale_, layer_tree_host()->page_scale_factor()); | |
255 PostSetNeedsRedrawToMainThread(); | |
256 break; | |
257 case 3: | |
258 // This commit will not be aborted because of the scroll change. | |
259 EXPECT_EQ(2, num_impl_scrolls_); | |
260 // The source frame number still increases even with the abort. | |
261 EXPECT_EQ(2, layer_tree_host()->source_frame_number()); | |
262 EXPECT_VECTOR_EQ( | |
263 root_scroll_layer->scroll_offset(), | |
264 gfx::ScrollOffsetWithDelta(initial_scroll_, | |
265 impl_scroll_ + impl_scroll_)); | |
266 EXPECT_EQ(impl_scale_ * impl_scale_, | |
267 layer_tree_host()->page_scale_factor()); | |
268 root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta( | |
269 root_scroll_layer->scroll_offset(), second_main_scroll_)); | |
270 break; | |
271 case 4: | |
272 // This commit will also be aborted. | |
273 EXPECT_EQ(3, num_impl_scrolls_); | |
274 EXPECT_EQ(3, layer_tree_host()->source_frame_number()); | |
275 gfx::Vector2dF delta = | |
276 impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_; | |
277 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), | |
278 gfx::ScrollOffsetWithDelta(initial_scroll_, delta)); | |
279 | |
280 // End the test by drawing to verify this commit is also aborted. | |
281 PostSetNeedsRedrawToMainThread(); | |
282 break; | |
283 } | |
284 } | |
285 | |
286 void DidBeginMainFrame() override { num_did_begin_main_frames_++; } | |
287 | |
288 void WillCommit() override { num_will_commits_++; } | |
289 | |
290 void DidCommit() override { num_did_commits_++; } | |
291 | |
292 void BeginCommitOnThread(LayerTreeHostImpl* impl) override { | |
293 num_impl_commits_++; | |
294 } | |
295 | |
296 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
297 LayerImpl* root_scroll_layer = | |
298 impl->active_tree()->root_layer()->children()[0]; | |
299 | |
300 if (impl->active_tree()->source_frame_number() == 0 && | |
301 impl->SourceAnimationFrameNumber() == 1) { | |
302 // First draw | |
303 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d()); | |
304 root_scroll_layer->ScrollBy(impl_scroll_); | |
305 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_); | |
306 EXPECT_VECTOR_EQ(root_scroll_layer->BaseScrollOffset(), initial_scroll_); | |
307 | |
308 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta()); | |
309 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor()); | |
310 impl->SetPageScaleOnActiveTree(impl_scale_); | |
311 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta()); | |
312 EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor()); | |
313 | |
314 // To simplify the testing flow, don't redraw here, just commit. | |
315 impl->SetNeedsCommit(); | |
316 } else if (impl->active_tree()->source_frame_number() == 0 && | |
317 impl->SourceAnimationFrameNumber() == 2) { | |
318 // Test a second draw after an aborted commit. | |
319 // The scroll/scale values should be baked into the offset/scale factor | |
320 // since the main thread consumed but aborted the begin frame. | |
321 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d()); | |
322 root_scroll_layer->ScrollBy(impl_scroll_); | |
323 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_); | |
324 EXPECT_VECTOR_EQ( | |
325 root_scroll_layer->BaseScrollOffset(), | |
326 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_)); | |
327 | |
328 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta()); | |
329 EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor()); | |
330 impl->SetPageScaleOnActiveTree(impl_scale_ * impl_scale_); | |
331 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta()); | |
332 EXPECT_EQ(impl_scale_ * impl_scale_, | |
333 impl->active_tree()->current_page_scale_factor()); | |
334 | |
335 impl->SetNeedsCommit(); | |
336 } else if (impl->active_tree()->source_frame_number() == 1) { | |
337 // Commit for source frame 1 is aborted. | |
338 NOTREACHED(); | |
339 } else if (impl->active_tree()->source_frame_number() == 2 && | |
340 impl->SourceAnimationFrameNumber() == 3) { | |
341 // Third draw after the second full commit. | |
342 EXPECT_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d()); | |
343 root_scroll_layer->ScrollBy(impl_scroll_); | |
344 impl->SetNeedsCommit(); | |
345 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_); | |
346 gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + second_main_scroll_; | |
347 EXPECT_VECTOR_EQ(root_scroll_layer->BaseScrollOffset(), | |
348 gfx::ScrollOffsetWithDelta(initial_scroll_, delta)); | |
349 } else if (impl->active_tree()->source_frame_number() == 2 && | |
350 impl->SourceAnimationFrameNumber() == 4) { | |
351 // Final draw after the second aborted commit. | |
352 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d()); | |
353 gfx::Vector2dF delta = | |
354 impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_; | |
355 EXPECT_VECTOR_EQ(root_scroll_layer->BaseScrollOffset(), | |
356 gfx::ScrollOffsetWithDelta(initial_scroll_, delta)); | |
357 EndTest(); | |
358 } else { | |
359 // Commit for source frame 3 is aborted. | |
360 NOTREACHED(); | |
361 } | |
362 } | |
363 | |
364 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, | |
365 float scale, | |
366 float top_controls_delta) override { | |
367 num_impl_scrolls_++; | |
368 } | |
369 | |
370 void AfterTest() override { | |
371 EXPECT_EQ(3, num_impl_scrolls_); | |
372 // Verify that the embedder sees aborted commits as real commits. | |
373 EXPECT_EQ(4, num_will_begin_main_frames_); | |
374 EXPECT_EQ(4, num_did_begin_main_frames_); | |
375 EXPECT_EQ(4, num_will_commits_); | |
376 EXPECT_EQ(4, num_did_commits_); | |
377 // ...but the compositor thread only sees two real ones. | |
378 EXPECT_EQ(2, num_impl_commits_); | |
379 } | |
380 | |
381 private: | |
382 gfx::ScrollOffset initial_scroll_; | |
383 gfx::Vector2dF impl_scroll_; | |
384 gfx::Vector2dF second_main_scroll_; | |
385 float impl_scale_; | |
386 int num_will_begin_main_frames_; | |
387 int num_did_begin_main_frames_; | |
388 int num_will_commits_; | |
389 int num_did_commits_; | |
390 int num_impl_commits_; | |
391 int num_impl_scrolls_; | |
392 }; | |
393 | |
394 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit); | |
395 | |
396 class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest { | |
397 public: | |
398 LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {} | |
399 | |
400 void SetupTree() override { | |
401 LayerTreeHostScrollTest::SetupTree(); | |
402 Layer* root_layer = layer_tree_host()->root_layer(); | |
403 scoped_refptr<Layer> root_scroll_layer = Layer::Create(); | |
404 root_scroll_layer->SetScrollClipLayerId(root_layer->id()); | |
405 root_scroll_layer->SetBounds( | |
406 gfx::Size(root_layer->bounds().width() + 100, | |
407 root_layer->bounds().height() + 100)); | |
408 root_scroll_layer->SetIsDrawable(true); | |
409 root_scroll_layer->SetIsContainerForFixedPositionLayers(true); | |
410 root_layer->AddChild(root_scroll_layer); | |
411 | |
412 layer_tree_host()->RegisterViewportLayers(NULL, root_layer, | |
413 root_scroll_layer, NULL); | |
414 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); | |
415 } | |
416 | |
417 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
418 | |
419 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
420 LayerImpl* root = impl->active_tree()->root_layer(); | |
421 LayerImpl* scroll_layer = root->children()[0]; | |
422 | |
423 // Check that a fractional scroll delta is correctly accumulated over | |
424 // multiple commits. | |
425 switch (impl->active_tree()->source_frame_number()) { | |
426 case 0: | |
427 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), gfx::Vector2d(0, 0)); | |
428 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d(0, 0)); | |
429 PostSetNeedsCommitToMainThread(); | |
430 break; | |
431 case 1: | |
432 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), | |
433 gfx::ToFlooredVector2d(scroll_amount_)); | |
434 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), | |
435 gfx::Vector2dF(fmod(scroll_amount_.x(), 1.0f), 0.0f)); | |
436 PostSetNeedsCommitToMainThread(); | |
437 break; | |
438 case 2: | |
439 EXPECT_VECTOR_EQ( | |
440 scroll_layer->BaseScrollOffset(), | |
441 gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_)); | |
442 EXPECT_VECTOR_EQ( | |
443 scroll_layer->ScrollDelta(), | |
444 gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f)); | |
445 EndTest(); | |
446 break; | |
447 } | |
448 scroll_layer->ScrollBy(scroll_amount_); | |
449 } | |
450 | |
451 void AfterTest() override {} | |
452 | |
453 private: | |
454 gfx::Vector2dF scroll_amount_; | |
455 }; | |
456 | |
457 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll); | |
458 | |
459 class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { | |
460 public: | |
461 LayerTreeHostScrollTestCaseWithChild() | |
462 : initial_offset_(10, 20), | |
463 javascript_scroll_(40, 5), | |
464 scroll_amount_(2, -1), | |
465 num_scrolls_(0) {} | |
466 | |
467 void SetupTree() override { | |
468 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_); | |
469 | |
470 scoped_refptr<Layer> root_layer = Layer::Create(); | |
471 root_layer->SetBounds(gfx::Size(10, 10)); | |
472 | |
473 root_scroll_layer_ = FakePictureLayer::Create(&fake_content_layer_client_); | |
474 root_scroll_layer_->SetBounds(gfx::Size(110, 110)); | |
475 | |
476 root_scroll_layer_->SetPosition(gfx::Point()); | |
477 | |
478 root_scroll_layer_->SetIsDrawable(true); | |
479 root_scroll_layer_->SetScrollClipLayerId(root_layer->id()); | |
480 root_scroll_layer_->SetIsContainerForFixedPositionLayers(true); | |
481 root_layer->AddChild(root_scroll_layer_); | |
482 | |
483 child_layer_ = FakePictureLayer::Create(&fake_content_layer_client_); | |
484 child_layer_->set_did_scroll_callback( | |
485 base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll, | |
486 base::Unretained(this))); | |
487 child_layer_->SetBounds(gfx::Size(110, 110)); | |
488 | |
489 if (scroll_child_layer_) { | |
490 // Scrolls on the child layer will happen at 5, 5. If they are treated | |
491 // like device pixels, and device scale factor is 2, then they will | |
492 // be considered at 2.5, 2.5 in logical pixels, and will miss this layer. | |
493 child_layer_->SetPosition(gfx::Point(5, 5)); | |
494 } else { | |
495 // Adjust the child layer horizontally so that scrolls will never hit it. | |
496 child_layer_->SetPosition(gfx::Point(60, 5)); | |
497 } | |
498 | |
499 child_layer_->SetIsDrawable(true); | |
500 child_layer_->SetScrollClipLayerId(root_layer->id()); | |
501 child_layer_->SetBounds(root_scroll_layer_->bounds()); | |
502 root_scroll_layer_->AddChild(child_layer_); | |
503 | |
504 if (scroll_child_layer_) { | |
505 expected_scroll_layer_ = child_layer_; | |
506 expected_no_scroll_layer_ = root_scroll_layer_; | |
507 } else { | |
508 expected_scroll_layer_ = root_scroll_layer_; | |
509 expected_no_scroll_layer_ = child_layer_; | |
510 } | |
511 | |
512 expected_scroll_layer_->SetScrollOffset(initial_offset_); | |
513 | |
514 layer_tree_host()->SetRootLayer(root_layer); | |
515 layer_tree_host()->RegisterViewportLayers(NULL, root_layer, | |
516 root_scroll_layer_, NULL); | |
517 LayerTreeHostScrollTest::SetupTree(); | |
518 } | |
519 | |
520 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
521 | |
522 void WillCommit() override { | |
523 // Keep the test committing (otherwise the early out for no update | |
524 // will stall the test). | |
525 if (layer_tree_host()->source_frame_number() < 2) { | |
526 layer_tree_host()->SetNeedsCommit(); | |
527 } | |
528 } | |
529 | |
530 void DidScroll() { | |
531 final_scroll_offset_ = expected_scroll_layer_->scroll_offset(); | |
532 } | |
533 | |
534 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, | |
535 float scale, | |
536 float top_controls_delta) override { | |
537 num_scrolls_++; | |
538 } | |
539 | |
540 void Layout() override { | |
541 EXPECT_VECTOR_EQ(gfx::Vector2d(), | |
542 expected_no_scroll_layer_->scroll_offset()); | |
543 | |
544 switch (layer_tree_host()->source_frame_number()) { | |
545 case 0: | |
546 EXPECT_VECTOR_EQ(initial_offset_, | |
547 expected_scroll_layer_->scroll_offset()); | |
548 break; | |
549 case 1: | |
550 EXPECT_VECTOR_EQ( | |
551 gfx::ScrollOffsetWithDelta(initial_offset_, scroll_amount_), | |
552 expected_scroll_layer_->scroll_offset()); | |
553 | |
554 // Pretend like Javascript updated the scroll position itself. | |
555 expected_scroll_layer_->SetScrollOffset(javascript_scroll_); | |
556 break; | |
557 case 2: | |
558 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_, | |
559 scroll_amount_), | |
560 expected_scroll_layer_->scroll_offset()); | |
561 break; | |
562 } | |
563 } | |
564 | |
565 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
566 LayerImpl* root_impl = impl->active_tree()->root_layer(); | |
567 FakePictureLayerImpl* root_scroll_layer_impl = | |
568 static_cast<FakePictureLayerImpl*>(root_impl->children()[0]); | |
569 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>( | |
570 root_scroll_layer_impl->children()[0]); | |
571 | |
572 LayerImpl* expected_scroll_layer_impl = NULL; | |
573 LayerImpl* expected_no_scroll_layer_impl = NULL; | |
574 if (scroll_child_layer_) { | |
575 expected_scroll_layer_impl = child_layer_impl; | |
576 expected_no_scroll_layer_impl = root_scroll_layer_impl; | |
577 } else { | |
578 expected_scroll_layer_impl = root_scroll_layer_impl; | |
579 expected_no_scroll_layer_impl = child_layer_impl; | |
580 } | |
581 | |
582 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl->ScrollDelta()); | |
583 EXPECT_VECTOR_EQ(gfx::Vector2d(), | |
584 expected_no_scroll_layer_impl->ScrollDelta()); | |
585 | |
586 // Ensure device scale factor matches the active tree. | |
587 EXPECT_EQ(device_scale_factor_, impl->active_tree()->device_scale_factor()); | |
588 switch (impl->active_tree()->source_frame_number()) { | |
589 case 0: { | |
590 // GESTURE scroll on impl thread. | |
591 InputHandler::ScrollStatus status = impl->ScrollBegin( | |
592 gfx::ToCeiledPoint(expected_scroll_layer_impl->position() - | |
593 gfx::Vector2dF(0.5f, 0.5f)), | |
594 InputHandler::GESTURE); | |
595 EXPECT_EQ(InputHandler::SCROLL_STARTED, status); | |
596 impl->ScrollBy(gfx::Point(), scroll_amount_); | |
597 impl->ScrollEnd(); | |
598 | |
599 // Check the scroll is applied as a delta. | |
600 EXPECT_VECTOR_EQ(initial_offset_, | |
601 expected_scroll_layer_impl->BaseScrollOffset()); | |
602 EXPECT_VECTOR_EQ(scroll_amount_, | |
603 expected_scroll_layer_impl->ScrollDelta()); | |
604 break; | |
605 } | |
606 case 1: { | |
607 // WHEEL scroll on impl thread. | |
608 InputHandler::ScrollStatus status = impl->ScrollBegin( | |
609 gfx::ToCeiledPoint(expected_scroll_layer_impl->position() + | |
610 gfx::Vector2dF(0.5f, 0.5f)), | |
611 InputHandler::WHEEL); | |
612 EXPECT_EQ(InputHandler::SCROLL_STARTED, status); | |
613 impl->ScrollBy(gfx::Point(), scroll_amount_); | |
614 impl->ScrollEnd(); | |
615 | |
616 // Check the scroll is applied as a delta. | |
617 EXPECT_VECTOR_EQ(javascript_scroll_, | |
618 expected_scroll_layer_impl->BaseScrollOffset()); | |
619 EXPECT_VECTOR_EQ(scroll_amount_, | |
620 expected_scroll_layer_impl->ScrollDelta()); | |
621 break; | |
622 } | |
623 case 2: | |
624 | |
625 EXPECT_VECTOR_EQ( | |
626 gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_), | |
627 expected_scroll_layer_impl->BaseScrollOffset()); | |
628 EXPECT_VECTOR_EQ(gfx::Vector2d(), | |
629 expected_scroll_layer_impl->ScrollDelta()); | |
630 | |
631 EndTest(); | |
632 break; | |
633 } | |
634 } | |
635 | |
636 void AfterTest() override { | |
637 if (scroll_child_layer_) { | |
638 EXPECT_EQ(0, num_scrolls_); | |
639 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_, | |
640 scroll_amount_), | |
641 final_scroll_offset_); | |
642 } else { | |
643 EXPECT_EQ(2, num_scrolls_); | |
644 EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_); | |
645 } | |
646 } | |
647 | |
648 protected: | |
649 float device_scale_factor_; | |
650 bool scroll_child_layer_; | |
651 | |
652 gfx::ScrollOffset initial_offset_; | |
653 gfx::ScrollOffset javascript_scroll_; | |
654 gfx::Vector2d scroll_amount_; | |
655 int num_scrolls_; | |
656 gfx::ScrollOffset final_scroll_offset_; | |
657 | |
658 FakeContentLayerClient fake_content_layer_client_; | |
659 | |
660 scoped_refptr<Layer> root_scroll_layer_; | |
661 scoped_refptr<Layer> child_layer_; | |
662 scoped_refptr<Layer> expected_scroll_layer_; | |
663 scoped_refptr<Layer> expected_no_scroll_layer_; | |
664 }; | |
665 | |
666 TEST_F(LayerTreeHostScrollTestCaseWithChild, | |
667 DeviceScaleFactor1_ScrollChild_DirectRenderer) { | |
668 device_scale_factor_ = 1.f; | |
669 scroll_child_layer_ = true; | |
670 RunTest(true, false, true); | |
671 } | |
672 | |
673 TEST_F(LayerTreeHostScrollTestCaseWithChild, | |
674 DeviceScaleFactor1_ScrollChild_DelegatingRenderer) { | |
675 device_scale_factor_ = 1.f; | |
676 scroll_child_layer_ = true; | |
677 RunTest(true, true, true); | |
678 } | |
679 | |
680 TEST_F(LayerTreeHostScrollTestCaseWithChild, | |
681 DeviceScaleFactor15_ScrollChild_DirectRenderer) { | |
682 device_scale_factor_ = 1.5f; | |
683 scroll_child_layer_ = true; | |
684 RunTest(true, false, true); | |
685 } | |
686 | |
687 TEST_F(LayerTreeHostScrollTestCaseWithChild, | |
688 DeviceScaleFactor15_ScrollChild_DelegatingRenderer) { | |
689 device_scale_factor_ = 1.5f; | |
690 scroll_child_layer_ = true; | |
691 RunTest(true, true, true); | |
692 } | |
693 | |
694 TEST_F(LayerTreeHostScrollTestCaseWithChild, | |
695 DeviceScaleFactor2_ScrollChild_DirectRenderer) { | |
696 device_scale_factor_ = 2.f; | |
697 scroll_child_layer_ = true; | |
698 RunTest(true, false, true); | |
699 } | |
700 | |
701 TEST_F(LayerTreeHostScrollTestCaseWithChild, | |
702 DeviceScaleFactor2_ScrollChild_DelegatingRenderer) { | |
703 device_scale_factor_ = 2.f; | |
704 scroll_child_layer_ = true; | |
705 RunTest(true, true, true); | |
706 } | |
707 | |
708 TEST_F(LayerTreeHostScrollTestCaseWithChild, | |
709 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer) { | |
710 device_scale_factor_ = 1.f; | |
711 scroll_child_layer_ = false; | |
712 RunTest(true, false, true); | |
713 } | |
714 | |
715 TEST_F(LayerTreeHostScrollTestCaseWithChild, | |
716 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer) { | |
717 device_scale_factor_ = 1.f; | |
718 scroll_child_layer_ = false; | |
719 RunTest(true, true, true); | |
720 } | |
721 | |
722 TEST_F(LayerTreeHostScrollTestCaseWithChild, | |
723 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer) { | |
724 device_scale_factor_ = 1.5f; | |
725 scroll_child_layer_ = false; | |
726 RunTest(true, false, true); | |
727 } | |
728 | |
729 TEST_F(LayerTreeHostScrollTestCaseWithChild, | |
730 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer) { | |
731 device_scale_factor_ = 1.5f; | |
732 scroll_child_layer_ = false; | |
733 RunTest(true, true, true); | |
734 } | |
735 | |
736 TEST_F(LayerTreeHostScrollTestCaseWithChild, | |
737 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer) { | |
738 device_scale_factor_ = 2.f; | |
739 scroll_child_layer_ = false; | |
740 RunTest(true, false, true); | |
741 } | |
742 | |
743 TEST_F(LayerTreeHostScrollTestCaseWithChild, | |
744 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer) { | |
745 device_scale_factor_ = 2.f; | |
746 scroll_child_layer_ = false; | |
747 RunTest(true, true, true); | |
748 } | |
749 | |
750 class ImplSidePaintingScrollTest : public LayerTreeHostScrollTest { | |
751 public: | |
752 void InitializeSettings(LayerTreeSettings* settings) override { | |
753 settings->impl_side_painting = true; | |
754 } | |
755 | |
756 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
757 if (impl->pending_tree()) | |
758 impl->SetNeedsRedraw(); | |
759 } | |
760 }; | |
761 | |
762 class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest { | |
763 public: | |
764 ImplSidePaintingScrollTestSimple() | |
765 : initial_scroll_(10, 20), | |
766 main_thread_scroll_(40, 5), | |
767 impl_thread_scroll1_(2, -1), | |
768 impl_thread_scroll2_(-3, 10), | |
769 num_scrolls_(0) {} | |
770 | |
771 void SetupTree() override { | |
772 LayerTreeHostScrollTest::SetupTree(); | |
773 Layer* root_layer = layer_tree_host()->root_layer(); | |
774 scoped_refptr<Layer> root_scroll_layer = Layer::Create(); | |
775 root_scroll_layer->SetScrollClipLayerId(root_layer->id()); | |
776 root_scroll_layer->SetScrollOffset(initial_scroll_); | |
777 root_scroll_layer->SetBounds( | |
778 gfx::Size(root_layer->bounds().width() + 100, | |
779 root_layer->bounds().height() + 100)); | |
780 root_scroll_layer->SetIsDrawable(true); | |
781 root_scroll_layer->SetIsContainerForFixedPositionLayers(true); | |
782 root_layer->AddChild(root_scroll_layer); | |
783 | |
784 layer_tree_host()->RegisterViewportLayers(NULL, root_layer, | |
785 root_scroll_layer, NULL); | |
786 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); | |
787 } | |
788 | |
789 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
790 | |
791 void Layout() override { | |
792 Layer* root = layer_tree_host()->root_layer(); | |
793 Layer* scroll_layer = root->children()[0].get(); | |
794 if (!layer_tree_host()->source_frame_number()) { | |
795 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_); | |
796 } else { | |
797 EXPECT_VECTOR_EQ( | |
798 scroll_layer->scroll_offset(), | |
799 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll1_)); | |
800 | |
801 // Pretend like Javascript updated the scroll position itself with a | |
802 // change of main_thread_scroll. | |
803 scroll_layer->SetScrollOffset( | |
804 gfx::ScrollOffsetWithDelta( | |
805 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_)); | |
806 } | |
807 } | |
808 | |
809 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
810 // We force a second draw here of the first commit before activating | |
811 // the second commit. | |
812 if (impl->active_tree()->source_frame_number() == 0) | |
813 impl->SetNeedsRedraw(); | |
814 } | |
815 | |
816 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
817 ImplSidePaintingScrollTest::DrawLayersOnThread(impl); | |
818 | |
819 LayerImpl* root = impl->active_tree()->root_layer(); | |
820 LayerImpl* scroll_layer = root->children()[0]; | |
821 LayerImpl* pending_root = | |
822 impl->active_tree()->FindPendingTreeLayerById(root->id()); | |
823 | |
824 switch (impl->active_tree()->source_frame_number()) { | |
825 case 0: | |
826 if (!impl->pending_tree()) { | |
827 impl->BlockNotifyReadyToActivateForTesting(true); | |
828 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d()); | |
829 scroll_layer->ScrollBy(impl_thread_scroll1_); | |
830 | |
831 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), initial_scroll_); | |
832 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll1_); | |
833 PostSetNeedsCommitToMainThread(); | |
834 | |
835 // CommitCompleteOnThread will trigger this function again | |
836 // and cause us to take the else clause. | |
837 } else { | |
838 impl->BlockNotifyReadyToActivateForTesting(false); | |
839 ASSERT_TRUE(pending_root); | |
840 EXPECT_EQ(impl->pending_tree()->source_frame_number(), 1); | |
841 | |
842 scroll_layer->ScrollBy(impl_thread_scroll2_); | |
843 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), initial_scroll_); | |
844 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), | |
845 impl_thread_scroll1_ + impl_thread_scroll2_); | |
846 | |
847 LayerImpl* pending_scroll_layer = pending_root->children()[0]; | |
848 EXPECT_VECTOR_EQ( | |
849 pending_scroll_layer->BaseScrollOffset(), | |
850 gfx::ScrollOffsetWithDelta( | |
851 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_)); | |
852 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), | |
853 impl_thread_scroll2_); | |
854 } | |
855 break; | |
856 case 1: | |
857 EXPECT_FALSE(impl->pending_tree()); | |
858 EXPECT_VECTOR_EQ( | |
859 scroll_layer->BaseScrollOffset(), | |
860 gfx::ScrollOffsetWithDelta( | |
861 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_)); | |
862 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll2_); | |
863 EndTest(); | |
864 break; | |
865 } | |
866 } | |
867 | |
868 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, | |
869 float scale, | |
870 float top_controls_delta) override { | |
871 num_scrolls_++; | |
872 } | |
873 | |
874 void AfterTest() override { EXPECT_EQ(1, num_scrolls_); } | |
875 | |
876 private: | |
877 gfx::ScrollOffset initial_scroll_; | |
878 gfx::Vector2dF main_thread_scroll_; | |
879 gfx::Vector2dF impl_thread_scroll1_; | |
880 gfx::Vector2dF impl_thread_scroll2_; | |
881 int num_scrolls_; | |
882 }; | |
883 | |
884 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple); | |
885 | |
886 // This test makes sure that layers pick up scrolls that occur between | |
887 // beginning a commit and finishing a commit (aka scroll deltas not | |
888 // included in sent scroll delta) still apply to layers that don't | |
889 // push properties. | |
890 class ImplSidePaintingScrollTestImplOnlyScroll | |
891 : public ImplSidePaintingScrollTest { | |
892 public: | |
893 ImplSidePaintingScrollTestImplOnlyScroll() | |
894 : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3), impl_scale_(2.f) {} | |
895 | |
896 void SetupTree() override { | |
897 LayerTreeHostScrollTest::SetupTree(); | |
898 Layer* root_layer = layer_tree_host()->root_layer(); | |
899 scoped_refptr<Layer> root_scroll_layer = Layer::Create(); | |
900 root_scroll_layer->SetScrollClipLayerId(root_layer->id()); | |
901 root_scroll_layer->SetScrollOffset(initial_scroll_); | |
902 root_scroll_layer->SetBounds( | |
903 gfx::Size(root_layer->bounds().width() + 100, | |
904 root_layer->bounds().height() + 100)); | |
905 root_scroll_layer->SetIsDrawable(true); | |
906 root_scroll_layer->SetIsContainerForFixedPositionLayers(true); | |
907 root_layer->AddChild(root_scroll_layer); | |
908 | |
909 layer_tree_host()->RegisterViewportLayers(NULL, root_layer, | |
910 root_scroll_layer, NULL); | |
911 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); | |
912 } | |
913 | |
914 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
915 | |
916 void WillCommit() override { | |
917 Layer* root = layer_tree_host()->root_layer(); | |
918 Layer* scroll_layer = root->children()[0].get(); | |
919 switch (layer_tree_host()->source_frame_number()) { | |
920 case 0: | |
921 EXPECT_TRUE(scroll_layer->needs_push_properties()); | |
922 break; | |
923 case 1: | |
924 // Even if this layer doesn't need push properties, it should | |
925 // still pick up scrolls that happen on the active layer during | |
926 // commit. | |
927 EXPECT_FALSE(scroll_layer->needs_push_properties()); | |
928 break; | |
929 } | |
930 } | |
931 | |
932 void BeginCommitOnThread(LayerTreeHostImpl* impl) override { | |
933 // Scroll after the 2nd commit has started. | |
934 if (impl->active_tree()->source_frame_number() == 0) { | |
935 LayerImpl* active_root = impl->active_tree()->root_layer(); | |
936 LayerImpl* active_scroll_layer = active_root->children()[0]; | |
937 ASSERT_TRUE(active_root); | |
938 ASSERT_TRUE(active_scroll_layer); | |
939 active_scroll_layer->ScrollBy(impl_thread_scroll_); | |
940 impl->SetPageScaleOnActiveTree(impl_scale_); | |
941 } | |
942 } | |
943 | |
944 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
945 // We force a second draw here of the first commit before activating | |
946 // the second commit. | |
947 LayerImpl* active_root = impl->active_tree()->root_layer(); | |
948 LayerImpl* active_scroll_layer = | |
949 active_root ? active_root->children()[0] : NULL; | |
950 LayerImpl* pending_root = impl->pending_tree()->root_layer(); | |
951 LayerImpl* pending_scroll_layer = pending_root->children()[0]; | |
952 | |
953 ASSERT_TRUE(pending_root); | |
954 ASSERT_TRUE(pending_scroll_layer); | |
955 switch (impl->pending_tree()->source_frame_number()) { | |
956 case 0: | |
957 EXPECT_VECTOR_EQ(pending_scroll_layer->BaseScrollOffset(), | |
958 initial_scroll_); | |
959 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d()); | |
960 EXPECT_FALSE(active_root); | |
961 break; | |
962 case 1: | |
963 // Even though the scroll happened during the commit, both layers | |
964 // should have the appropriate scroll delta. | |
965 EXPECT_VECTOR_EQ(pending_scroll_layer->BaseScrollOffset(), | |
966 initial_scroll_); | |
967 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), | |
968 impl_thread_scroll_); | |
969 ASSERT_TRUE(active_root); | |
970 EXPECT_VECTOR_EQ(active_scroll_layer->BaseScrollOffset(), | |
971 initial_scroll_); | |
972 EXPECT_VECTOR_EQ(active_scroll_layer->ScrollDelta(), | |
973 impl_thread_scroll_); | |
974 break; | |
975 case 2: | |
976 // On the next commit, this delta should have been sent and applied. | |
977 EXPECT_VECTOR_EQ( | |
978 pending_scroll_layer->BaseScrollOffset(), | |
979 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll_)); | |
980 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d()); | |
981 break; | |
982 } | |
983 } | |
984 | |
985 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
986 ImplSidePaintingScrollTest::DrawLayersOnThread(impl); | |
987 | |
988 LayerImpl* root = impl->active_tree()->root_layer(); | |
989 LayerImpl* scroll_layer = root->children()[0]; | |
990 | |
991 switch (impl->active_tree()->source_frame_number()) { | |
992 case 0: | |
993 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), initial_scroll_); | |
994 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d()); | |
995 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta()); | |
996 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor()); | |
997 PostSetNeedsCommitToMainThread(); | |
998 break; | |
999 case 1: | |
1000 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), initial_scroll_); | |
1001 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll_); | |
1002 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta()); | |
1003 EXPECT_EQ(impl_scale_, | |
1004 impl->active_tree()->current_page_scale_factor()); | |
1005 PostSetNeedsCommitToMainThread(); | |
1006 break; | |
1007 case 2: | |
1008 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta()); | |
1009 EXPECT_EQ(impl_scale_, | |
1010 impl->active_tree()->current_page_scale_factor()); | |
1011 EndTest(); | |
1012 break; | |
1013 } | |
1014 } | |
1015 | |
1016 void AfterTest() override {} | |
1017 | |
1018 private: | |
1019 gfx::ScrollOffset initial_scroll_; | |
1020 gfx::Vector2dF impl_thread_scroll_; | |
1021 float impl_scale_; | |
1022 }; | |
1023 | |
1024 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll); | |
1025 | |
1026 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset | |
1027 : public LayerTreeHostScrollTest { | |
1028 public: | |
1029 LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {} | |
1030 | |
1031 void SetupTree() override { | |
1032 LayerTreeTest::SetupTree(); | |
1033 scoped_refptr<Layer> scroll_layer = Layer::Create(); | |
1034 layer_tree_host()->root_layer()->AddChild(scroll_layer); | |
1035 } | |
1036 | |
1037 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
1038 | |
1039 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
1040 LayerImpl* root = impl->active_tree()->root_layer(); | |
1041 LayerImpl* scroll_layer = root->children()[0]; | |
1042 scroll_layer->SetScrollClipLayer(root->id()); | |
1043 | |
1044 // Set max_scroll_offset = (100, 100). | |
1045 scroll_layer->SetBounds( | |
1046 gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); | |
1047 EXPECT_EQ( | |
1048 InputHandler::SCROLL_STARTED, | |
1049 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE, | |
1050 SCROLL_BLOCKS_ON_NONE)); | |
1051 | |
1052 // Set max_scroll_offset = (0, 0). | |
1053 scroll_layer->SetBounds(root->bounds()); | |
1054 EXPECT_EQ( | |
1055 InputHandler::SCROLL_IGNORED, | |
1056 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE, | |
1057 SCROLL_BLOCKS_ON_NONE)); | |
1058 | |
1059 // Set max_scroll_offset = (-100, -100). | |
1060 scroll_layer->SetBounds(gfx::Size()); | |
1061 EXPECT_EQ( | |
1062 InputHandler::SCROLL_IGNORED, | |
1063 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE, | |
1064 SCROLL_BLOCKS_ON_NONE)); | |
1065 | |
1066 EndTest(); | |
1067 } | |
1068 | |
1069 void AfterTest() override {} | |
1070 }; | |
1071 | |
1072 SINGLE_AND_MULTI_THREAD_TEST_F( | |
1073 LayerTreeHostScrollTestScrollZeroMaxScrollOffset); | |
1074 | |
1075 class ThreadCheckingInputHandlerClient : public InputHandlerClient { | |
1076 public: | |
1077 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner* runner, | |
1078 bool* received_stop_flinging) | |
1079 : task_runner_(runner), received_stop_flinging_(received_stop_flinging) {} | |
1080 | |
1081 void WillShutdown() override { | |
1082 if (!received_stop_flinging_) | |
1083 ADD_FAILURE() << "WillShutdown() called before fling stopped"; | |
1084 } | |
1085 | |
1086 void Animate(base::TimeTicks time) override { | |
1087 if (!task_runner_->BelongsToCurrentThread()) | |
1088 ADD_FAILURE() << "Animate called on wrong thread"; | |
1089 } | |
1090 | |
1091 void MainThreadHasStoppedFlinging() override { | |
1092 if (!task_runner_->BelongsToCurrentThread()) | |
1093 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread"; | |
1094 *received_stop_flinging_ = true; | |
1095 } | |
1096 | |
1097 void ReconcileElasticOverscrollAndRootScroll() override { | |
1098 if (!task_runner_->BelongsToCurrentThread()) { | |
1099 ADD_FAILURE() << "ReconcileElasticOverscrollAndRootScroll called on " | |
1100 << "wrong thread"; | |
1101 } | |
1102 } | |
1103 | |
1104 private: | |
1105 base::SingleThreadTaskRunner* task_runner_; | |
1106 bool* received_stop_flinging_; | |
1107 }; | |
1108 | |
1109 void BindInputHandlerOnCompositorThread( | |
1110 const base::WeakPtr<InputHandler>& input_handler, | |
1111 ThreadCheckingInputHandlerClient* client) { | |
1112 input_handler->BindToClient(client); | |
1113 } | |
1114 | |
1115 TEST(LayerTreeHostFlingTest, DidStopFlingingThread) { | |
1116 base::Thread impl_thread("cc"); | |
1117 ASSERT_TRUE(impl_thread.Start()); | |
1118 | |
1119 bool received_stop_flinging = false; | |
1120 LayerTreeSettings settings; | |
1121 | |
1122 ThreadCheckingInputHandlerClient input_handler_client( | |
1123 impl_thread.message_loop_proxy().get(), &received_stop_flinging); | |
1124 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); | |
1125 | |
1126 ASSERT_TRUE(impl_thread.message_loop_proxy().get()); | |
1127 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( | |
1128 new TestSharedBitmapManager()); | |
1129 scoped_ptr<LayerTreeHost> layer_tree_host = LayerTreeHost::CreateThreaded( | |
1130 &client, shared_bitmap_manager.get(), NULL, NULL, settings, | |
1131 base::MessageLoopProxy::current(), impl_thread.message_loop_proxy(), | |
1132 nullptr); | |
1133 | |
1134 impl_thread.message_loop_proxy() | |
1135 ->PostTask(FROM_HERE, | |
1136 base::Bind(&BindInputHandlerOnCompositorThread, | |
1137 layer_tree_host->GetInputHandler(), | |
1138 base::Unretained(&input_handler_client))); | |
1139 | |
1140 layer_tree_host->DidStopFlinging(); | |
1141 layer_tree_host = nullptr; | |
1142 impl_thread.Stop(); | |
1143 EXPECT_TRUE(received_stop_flinging); | |
1144 } | |
1145 | |
1146 class LayerTreeHostScrollTestLayerStructureChange | |
1147 : public LayerTreeHostScrollTest { | |
1148 public: | |
1149 LayerTreeHostScrollTestLayerStructureChange() | |
1150 : scroll_destroy_whole_tree_(false) {} | |
1151 | |
1152 void SetupTree() override { | |
1153 scoped_refptr<Layer> root_layer = Layer::Create(); | |
1154 root_layer->SetBounds(gfx::Size(10, 10)); | |
1155 | |
1156 Layer* root_scroll_layer = | |
1157 CreateScrollLayer(root_layer.get(), &root_scroll_layer_client_); | |
1158 CreateScrollLayer(root_layer.get(), &sibling_scroll_layer_client_); | |
1159 CreateScrollLayer(root_scroll_layer, &child_scroll_layer_client_); | |
1160 | |
1161 layer_tree_host()->SetRootLayer(root_layer); | |
1162 LayerTreeHostScrollTest::SetupTree(); | |
1163 } | |
1164 | |
1165 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
1166 | |
1167 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
1168 LayerImpl* root = impl->active_tree()->root_layer(); | |
1169 switch (impl->active_tree()->source_frame_number()) { | |
1170 case 0: | |
1171 root->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5)); | |
1172 root->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5)); | |
1173 root->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5)); | |
1174 PostSetNeedsCommitToMainThread(); | |
1175 break; | |
1176 case 1: | |
1177 EndTest(); | |
1178 break; | |
1179 } | |
1180 } | |
1181 | |
1182 void AfterTest() override {} | |
1183 | |
1184 virtual void DidScroll(Layer* layer) { | |
1185 if (scroll_destroy_whole_tree_) { | |
1186 layer_tree_host()->SetRootLayer(NULL); | |
1187 EndTest(); | |
1188 return; | |
1189 } | |
1190 layer->RemoveFromParent(); | |
1191 } | |
1192 | |
1193 protected: | |
1194 class FakeLayerScrollClient { | |
1195 public: | |
1196 void DidScroll() { | |
1197 owner_->DidScroll(layer_); | |
1198 } | |
1199 LayerTreeHostScrollTestLayerStructureChange* owner_; | |
1200 Layer* layer_; | |
1201 }; | |
1202 | |
1203 Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) { | |
1204 scoped_refptr<PictureLayer> scroll_layer = | |
1205 PictureLayer::Create(&fake_content_layer_client_); | |
1206 scroll_layer->SetBounds(gfx::Size(110, 110)); | |
1207 scroll_layer->SetPosition(gfx::Point(0, 0)); | |
1208 scroll_layer->SetIsDrawable(true); | |
1209 scroll_layer->SetScrollClipLayerId(parent->id()); | |
1210 scroll_layer->SetBounds(gfx::Size(parent->bounds().width() + 100, | |
1211 parent->bounds().height() + 100)); | |
1212 scroll_layer->set_did_scroll_callback(base::Bind( | |
1213 &FakeLayerScrollClient::DidScroll, base::Unretained(client))); | |
1214 client->owner_ = this; | |
1215 client->layer_ = scroll_layer.get(); | |
1216 parent->AddChild(scroll_layer); | |
1217 return scroll_layer.get(); | |
1218 } | |
1219 | |
1220 FakeLayerScrollClient root_scroll_layer_client_; | |
1221 FakeLayerScrollClient sibling_scroll_layer_client_; | |
1222 FakeLayerScrollClient child_scroll_layer_client_; | |
1223 | |
1224 FakeContentLayerClient fake_content_layer_client_; | |
1225 | |
1226 bool scroll_destroy_whole_tree_; | |
1227 }; | |
1228 | |
1229 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyLayer) { | |
1230 RunTest(true, false, true); | |
1231 } | |
1232 | |
1233 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) { | |
1234 scroll_destroy_whole_tree_ = true; | |
1235 RunTest(true, false, true); | |
1236 } | |
1237 | |
1238 } // namespace | |
1239 } // namespace cc | |
OLD | NEW |