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