Add ICU message format support
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_scroll.cc
blobb6df2433e423083765958f2b1801928fe2c5eb96
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 {
32 protected:
33 void SetupTree() override {
34 LayerTreeTest::SetupTree();
35 Layer* root_layer = layer_tree_host()->root_layer();
37 // Create an effective max_scroll_offset of (100, 100).
38 gfx::Size scroll_layer_bounds(root_layer->bounds().width() + 100,
39 root_layer->bounds().height() + 100);
41 CreateVirtualViewportLayers(root_layer,
42 root_layer->bounds(),
43 root_layer->bounds(),
44 scroll_layer_bounds,
45 layer_tree_host(),
46 layer_settings());
50 class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest {
51 public:
52 LayerTreeHostScrollTestScrollSimple()
53 : initial_scroll_(10, 20),
54 second_scroll_(40, 5),
55 scroll_amount_(2, -1),
56 num_scrolls_(0) {}
58 void BeginTest() override {
59 layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
60 initial_scroll_);
61 PostSetNeedsCommitToMainThread();
64 void Layout() override {
65 Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
66 if (!layer_tree_host()->source_frame_number()) {
67 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
68 } else {
69 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_,
70 scroll_amount_),
71 scroll_layer->scroll_offset());
73 // Pretend like Javascript updated the scroll position itself.
74 scroll_layer->SetScrollOffset(second_scroll_);
78 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
79 LayerImpl* root = impl->active_tree()->root_layer();
80 LayerImpl* scroll_layer = impl->OuterViewportScrollLayer();
81 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer->ScrollDelta());
83 scroll_layer->SetScrollClipLayer(root->id());
84 scroll_layer->SetBounds(
85 gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
86 scroll_layer->ScrollBy(scroll_amount_);
88 switch (impl->active_tree()->source_frame_number()) {
89 case 0:
90 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->BaseScrollOffset());
91 EXPECT_VECTOR_EQ(scroll_amount_, scroll_layer->ScrollDelta());
92 PostSetNeedsCommitToMainThread();
93 break;
94 case 1:
95 EXPECT_VECTOR_EQ(second_scroll_, scroll_layer->BaseScrollOffset());
96 EXPECT_VECTOR_EQ(scroll_amount_, scroll_layer->ScrollDelta());
97 EndTest();
98 break;
102 void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
103 const gfx::Vector2dF& outer_delta,
104 const gfx::Vector2dF& elastic_overscroll_delta,
105 float scale,
106 float top_controls_delta) override {
107 num_scrolls_++;
110 void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }
112 private:
113 gfx::ScrollOffset initial_scroll_;
114 gfx::ScrollOffset second_scroll_;
115 gfx::Vector2dF scroll_amount_;
116 int num_scrolls_;
119 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple);
121 class LayerTreeHostScrollTestScrollMultipleRedraw
122 : public LayerTreeHostScrollTest {
123 public:
124 LayerTreeHostScrollTestScrollMultipleRedraw()
125 : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
127 void BeginTest() override {
128 scroll_layer_ = layer_tree_host()->outer_viewport_scroll_layer();
129 scroll_layer_->SetScrollOffset(initial_scroll_);
130 PostSetNeedsCommitToMainThread();
133 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
134 switch (layer_tree_host()->source_frame_number()) {
135 case 0:
136 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer_->scroll_offset());
137 break;
138 case 1:
139 EXPECT_VECTOR_EQ(
140 gfx::ScrollOffsetWithDelta(initial_scroll_,
141 scroll_amount_ + scroll_amount_),
142 scroll_layer_->scroll_offset());
143 case 2:
144 EXPECT_VECTOR_EQ(
145 gfx::ScrollOffsetWithDelta(initial_scroll_,
146 scroll_amount_ + scroll_amount_),
147 scroll_layer_->scroll_offset());
148 break;
152 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
153 LayerImpl* scroll_layer =
154 impl->active_tree()->LayerById(scroll_layer_->id());
155 if (impl->active_tree()->source_frame_number() == 0 &&
156 impl->SourceAnimationFrameNumberForTesting() == 1) {
157 // First draw after first commit.
158 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer->ScrollDelta());
159 scroll_layer->ScrollBy(scroll_amount_);
160 EXPECT_VECTOR_EQ(scroll_amount_, scroll_layer->ScrollDelta());
162 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->BaseScrollOffset());
163 PostSetNeedsRedrawToMainThread();
164 } else if (impl->active_tree()->source_frame_number() == 0 &&
165 impl->SourceAnimationFrameNumberForTesting() == 2) {
166 // Second draw after first commit.
167 EXPECT_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
168 scroll_layer->ScrollBy(scroll_amount_);
169 EXPECT_VECTOR_EQ(scroll_amount_ + scroll_amount_,
170 scroll_layer->ScrollDelta());
172 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer_->scroll_offset());
173 PostSetNeedsCommitToMainThread();
174 } else if (impl->active_tree()->source_frame_number() == 1) {
175 // Third or later draw after second commit.
176 EXPECT_GE(impl->SourceAnimationFrameNumberForTesting(), 3u);
177 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer_->ScrollDelta());
178 EXPECT_VECTOR_EQ(
179 gfx::ScrollOffsetWithDelta(initial_scroll_,
180 scroll_amount_ + scroll_amount_),
181 scroll_layer_->scroll_offset());
182 EndTest();
186 void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
187 const gfx::Vector2dF& outer_delta,
188 const gfx::Vector2dF& elastic_overscroll_delta,
189 float scale,
190 float top_controls_delta) override {
191 num_scrolls_++;
194 void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }
196 private:
197 gfx::ScrollOffset initial_scroll_;
198 gfx::Vector2dF scroll_amount_;
199 int num_scrolls_;
200 scoped_refptr<Layer> scroll_layer_;
203 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw);
205 class LayerTreeHostScrollTestScrollAbortedCommit
206 : public LayerTreeHostScrollTest {
207 public:
208 LayerTreeHostScrollTestScrollAbortedCommit()
209 : initial_scroll_(50, 60),
210 impl_scroll_(-3, 2),
211 second_main_scroll_(14, -3),
212 impl_scale_(2.f),
213 num_will_begin_main_frames_(0),
214 num_did_begin_main_frames_(0),
215 num_will_commits_(0),
216 num_did_commits_(0),
217 num_impl_commits_(0),
218 num_impl_scrolls_(0) {}
220 void BeginTest() override {
221 layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
222 initial_scroll_);
223 PostSetNeedsCommitToMainThread();
226 void SetupTree() override {
227 LayerTreeHostScrollTest::SetupTree();
229 gfx::Size scroll_layer_bounds(200, 200);
230 layer_tree_host()->outer_viewport_scroll_layer()->SetBounds(
231 scroll_layer_bounds);
232 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
235 void WillBeginMainFrame() override {
236 num_will_begin_main_frames_++;
237 Layer* root_scroll_layer =
238 layer_tree_host()->outer_viewport_scroll_layer();
239 switch (num_will_begin_main_frames_) {
240 case 1:
241 // This will not be aborted because of the initial prop changes.
242 EXPECT_EQ(0, num_impl_scrolls_);
243 EXPECT_EQ(0, layer_tree_host()->source_frame_number());
244 EXPECT_VECTOR_EQ(initial_scroll_, root_scroll_layer->scroll_offset());
245 EXPECT_EQ(1.f, layer_tree_host()->page_scale_factor());
246 break;
247 case 2:
248 // This commit will be aborted, and another commit will be
249 // initiated from the redraw.
250 EXPECT_EQ(1, num_impl_scrolls_);
251 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
252 EXPECT_VECTOR_EQ(
253 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_),
254 root_scroll_layer->scroll_offset());
255 EXPECT_EQ(impl_scale_, layer_tree_host()->page_scale_factor());
256 PostSetNeedsRedrawToMainThread();
257 break;
258 case 3:
259 // This commit will not be aborted because of the scroll change.
260 EXPECT_EQ(2, num_impl_scrolls_);
261 // The source frame number still increases even with the abort.
262 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
263 EXPECT_VECTOR_EQ(
264 gfx::ScrollOffsetWithDelta(initial_scroll_,
265 impl_scroll_ + impl_scroll_),
266 root_scroll_layer->scroll_offset());
267 EXPECT_EQ(impl_scale_ * impl_scale_,
268 layer_tree_host()->page_scale_factor());
269 root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta(
270 root_scroll_layer->scroll_offset(), second_main_scroll_));
271 break;
272 case 4:
273 // This commit will also be aborted.
274 EXPECT_EQ(3, num_impl_scrolls_);
275 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
276 gfx::Vector2dF delta =
277 impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
278 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
279 root_scroll_layer->scroll_offset());
281 // End the test by drawing to verify this commit is also aborted.
282 PostSetNeedsRedrawToMainThread();
283 break;
287 void DidBeginMainFrame() override { num_did_begin_main_frames_++; }
289 void WillCommit() override { num_will_commits_++; }
291 void DidCommit() override { num_did_commits_++; }
293 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
294 num_impl_commits_++;
297 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
298 LayerImpl* root_scroll_layer = impl->OuterViewportScrollLayer();
300 if (impl->active_tree()->source_frame_number() == 0 &&
301 impl->SourceAnimationFrameNumberForTesting() == 1) {
302 // First draw
303 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_scroll_layer->ScrollDelta());
304 root_scroll_layer->ScrollBy(impl_scroll_);
305 EXPECT_VECTOR_EQ(impl_scroll_, root_scroll_layer->ScrollDelta());
306 EXPECT_VECTOR_EQ(initial_scroll_, root_scroll_layer->BaseScrollOffset());
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());
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->SourceAnimationFrameNumberForTesting() == 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(gfx::Vector2d(), root_scroll_layer->ScrollDelta());
322 root_scroll_layer->ScrollBy(impl_scroll_);
323 EXPECT_VECTOR_EQ(impl_scroll_, root_scroll_layer->ScrollDelta());
324 EXPECT_VECTOR_EQ(
325 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_),
326 root_scroll_layer->BaseScrollOffset());
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());
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->SourceAnimationFrameNumberForTesting() == 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(impl_scroll_, root_scroll_layer->ScrollDelta());
346 gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + second_main_scroll_;
347 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
348 root_scroll_layer->BaseScrollOffset());
349 } else if (impl->active_tree()->source_frame_number() == 2 &&
350 impl->SourceAnimationFrameNumberForTesting() == 4) {
351 // Final draw after the second aborted commit.
352 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_scroll_layer->ScrollDelta());
353 gfx::Vector2dF delta =
354 impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
355 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
356 root_scroll_layer->BaseScrollOffset());
357 EndTest();
358 } else {
359 // Commit for source frame 3 is aborted.
360 NOTREACHED();
364 void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
365 const gfx::Vector2dF& outer_delta,
366 const gfx::Vector2dF& elastic_overscroll_delta,
367 float scale,
368 float top_controls_delta) override {
369 num_impl_scrolls_++;
372 void AfterTest() override {
373 EXPECT_EQ(3, num_impl_scrolls_);
374 // Verify that the embedder sees aborted commits as real commits.
375 EXPECT_EQ(4, num_will_begin_main_frames_);
376 EXPECT_EQ(4, num_did_begin_main_frames_);
377 EXPECT_EQ(4, num_will_commits_);
378 EXPECT_EQ(4, num_did_commits_);
379 // ...but the compositor thread only sees two real ones.
380 EXPECT_EQ(2, num_impl_commits_);
383 private:
384 gfx::ScrollOffset initial_scroll_;
385 gfx::Vector2dF impl_scroll_;
386 gfx::Vector2dF second_main_scroll_;
387 float impl_scale_;
388 int num_will_begin_main_frames_;
389 int num_did_begin_main_frames_;
390 int num_will_commits_;
391 int num_did_commits_;
392 int num_impl_commits_;
393 int num_impl_scrolls_;
396 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit);
398 class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest {
399 public:
400 LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
402 void SetupTree() override {
403 LayerTreeHostScrollTest::SetupTree();
404 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
407 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
409 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
410 LayerImpl* scroll_layer = impl->OuterViewportScrollLayer();
412 // Check that a fractional scroll delta is correctly accumulated over
413 // multiple commits.
414 switch (impl->active_tree()->source_frame_number()) {
415 case 0:
416 EXPECT_VECTOR_EQ(gfx::Vector2d(0, 0), scroll_layer->BaseScrollOffset());
417 EXPECT_VECTOR_EQ(gfx::Vector2d(0, 0), scroll_layer->ScrollDelta());
418 PostSetNeedsCommitToMainThread();
419 break;
420 case 1:
421 EXPECT_VECTOR_EQ(gfx::ToFlooredVector2d(scroll_amount_),
422 scroll_layer->BaseScrollOffset());
423 EXPECT_VECTOR_EQ(gfx::Vector2dF(fmod(scroll_amount_.x(), 1.0f), 0.0f),
424 scroll_layer->ScrollDelta());
425 PostSetNeedsCommitToMainThread();
426 break;
427 case 2:
428 EXPECT_VECTOR_EQ(
429 gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_),
430 scroll_layer->BaseScrollOffset());
431 EXPECT_VECTOR_EQ(
432 gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f),
433 scroll_layer->ScrollDelta());
434 EndTest();
435 break;
437 scroll_layer->ScrollBy(scroll_amount_);
440 void AfterTest() override {}
442 private:
443 gfx::Vector2dF scroll_amount_;
446 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll);
448 class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
449 public:
450 LayerTreeHostScrollTestCaseWithChild()
451 : initial_offset_(10, 20),
452 javascript_scroll_(40, 5),
453 scroll_amount_(2, -1),
454 num_scrolls_(0) {}
456 void SetupTree() override {
457 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
459 scoped_refptr<Layer> root_layer = Layer::Create(layer_settings());
460 root_layer->SetBounds(gfx::Size(10, 10));
462 root_scroll_layer_ =
463 FakePictureLayer::Create(layer_settings(), &fake_content_layer_client_);
464 root_scroll_layer_->SetBounds(gfx::Size(110, 110));
465 root_scroll_layer_->SetPosition(gfx::Point());
466 root_scroll_layer_->SetIsDrawable(true);
468 CreateVirtualViewportLayers(root_layer.get(),
469 root_scroll_layer_,
470 root_layer->bounds(),
471 root_layer->bounds(),
472 layer_tree_host(),
473 layer_settings());
476 child_layer_ =
477 FakePictureLayer::Create(layer_settings(), &fake_content_layer_client_);
478 child_layer_->set_did_scroll_callback(
479 base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
480 base::Unretained(this)));
481 child_layer_->SetBounds(gfx::Size(110, 110));
483 if (scroll_child_layer_) {
484 // Scrolls on the child layer will happen at 5, 5. If they are treated
485 // like device pixels, and device scale factor is 2, then they will
486 // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
487 child_layer_->SetPosition(gfx::Point(5, 5));
488 } else {
489 // Adjust the child layer horizontally so that scrolls will never hit it.
490 child_layer_->SetPosition(gfx::Point(60, 5));
493 scoped_refptr<Layer> outer_container_layer =
494 layer_tree_host()->outer_viewport_scroll_layer()->parent();
496 child_layer_->SetIsDrawable(true);
497 child_layer_->SetScrollClipLayerId(outer_container_layer->id());
498 child_layer_->SetBounds(root_scroll_layer_->bounds());
499 root_scroll_layer_->AddChild(child_layer_);
501 if (scroll_child_layer_) {
502 expected_scroll_layer_ = child_layer_;
503 expected_no_scroll_layer_ = root_scroll_layer_;
504 } else {
505 expected_scroll_layer_ = root_scroll_layer_;
506 expected_no_scroll_layer_ = child_layer_;
509 expected_scroll_layer_->SetScrollOffset(initial_offset_);
511 layer_tree_host()->SetRootLayer(root_layer);
512 LayerTreeTest::SetupTree();
515 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
517 void WillCommit() override {
518 // Keep the test committing (otherwise the early out for no update
519 // will stall the test).
520 if (layer_tree_host()->source_frame_number() < 2) {
521 layer_tree_host()->SetNeedsCommit();
525 void DidScroll() {
526 final_scroll_offset_ = expected_scroll_layer_->scroll_offset();
529 void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
530 const gfx::Vector2dF& outer_delta,
531 const gfx::Vector2dF& elastic_overscroll_delta,
532 float scale,
533 float top_controls_delta) override {
534 num_scrolls_++;
537 void Layout() override {
538 EXPECT_VECTOR_EQ(gfx::Vector2d(),
539 expected_no_scroll_layer_->scroll_offset());
541 switch (layer_tree_host()->source_frame_number()) {
542 case 0:
543 EXPECT_VECTOR_EQ(initial_offset_,
544 expected_scroll_layer_->scroll_offset());
545 break;
546 case 1:
547 EXPECT_VECTOR_EQ(
548 gfx::ScrollOffsetWithDelta(initial_offset_, scroll_amount_),
549 expected_scroll_layer_->scroll_offset());
551 // Pretend like Javascript updated the scroll position itself.
552 expected_scroll_layer_->SetScrollOffset(javascript_scroll_);
553 break;
554 case 2:
555 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_,
556 scroll_amount_),
557 expected_scroll_layer_->scroll_offset());
558 break;
562 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
563 LayerImpl* inner_scroll = impl->InnerViewportScrollLayer();
564 FakePictureLayerImpl* root_scroll_layer_impl =
565 static_cast<FakePictureLayerImpl*>(impl->OuterViewportScrollLayer());
566 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>(
567 root_scroll_layer_impl->children()[0]);
569 LayerImpl* expected_scroll_layer_impl = NULL;
570 LayerImpl* expected_no_scroll_layer_impl = NULL;
571 if (scroll_child_layer_) {
572 expected_scroll_layer_impl = child_layer_impl;
573 expected_no_scroll_layer_impl = root_scroll_layer_impl;
574 } else {
575 expected_scroll_layer_impl = root_scroll_layer_impl;
576 expected_no_scroll_layer_impl = child_layer_impl;
579 EXPECT_VECTOR_EQ(gfx::Vector2d(), inner_scroll->ScrollDelta());
580 EXPECT_VECTOR_EQ(gfx::Vector2d(),
581 expected_no_scroll_layer_impl->ScrollDelta());
583 // Ensure device scale factor matches the active tree.
584 EXPECT_EQ(device_scale_factor_, impl->active_tree()->device_scale_factor());
585 switch (impl->active_tree()->source_frame_number()) {
586 case 0: {
587 // GESTURE scroll on impl thread.
588 InputHandler::ScrollStatus status = impl->ScrollBegin(
589 gfx::ToCeiledPoint(expected_scroll_layer_impl->position() -
590 gfx::Vector2dF(0.5f, 0.5f)),
591 InputHandler::GESTURE);
592 EXPECT_EQ(InputHandler::SCROLL_STARTED, status);
593 impl->ScrollBy(gfx::Point(), scroll_amount_);
594 impl->ScrollEnd();
596 // Check the scroll is applied as a delta.
597 EXPECT_VECTOR_EQ(initial_offset_,
598 expected_scroll_layer_impl->BaseScrollOffset());
599 EXPECT_VECTOR_EQ(scroll_amount_,
600 expected_scroll_layer_impl->ScrollDelta());
601 break;
603 case 1: {
604 // WHEEL 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::WHEEL);
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(javascript_scroll_,
615 expected_scroll_layer_impl->BaseScrollOffset());
616 EXPECT_VECTOR_EQ(scroll_amount_,
617 expected_scroll_layer_impl->ScrollDelta());
618 break;
620 case 2:
622 EXPECT_VECTOR_EQ(
623 gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_),
624 expected_scroll_layer_impl->BaseScrollOffset());
625 EXPECT_VECTOR_EQ(gfx::Vector2d(),
626 expected_scroll_layer_impl->ScrollDelta());
628 EndTest();
629 break;
633 void AfterTest() override {
634 if (scroll_child_layer_) {
635 EXPECT_EQ(0, num_scrolls_);
636 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_,
637 scroll_amount_),
638 final_scroll_offset_);
639 } else {
640 EXPECT_EQ(2, num_scrolls_);
641 EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_);
645 protected:
646 float device_scale_factor_;
647 bool scroll_child_layer_;
649 gfx::ScrollOffset initial_offset_;
650 gfx::ScrollOffset javascript_scroll_;
651 gfx::Vector2d scroll_amount_;
652 int num_scrolls_;
653 gfx::ScrollOffset final_scroll_offset_;
655 FakeContentLayerClient fake_content_layer_client_;
657 scoped_refptr<Layer> root_scroll_layer_;
658 scoped_refptr<Layer> child_layer_;
659 scoped_refptr<Layer> expected_scroll_layer_;
660 scoped_refptr<Layer> expected_no_scroll_layer_;
663 TEST_F(LayerTreeHostScrollTestCaseWithChild,
664 DeviceScaleFactor1_ScrollChild_DirectRenderer) {
665 device_scale_factor_ = 1.f;
666 scroll_child_layer_ = true;
667 RunTest(true, false);
670 TEST_F(LayerTreeHostScrollTestCaseWithChild,
671 DeviceScaleFactor1_ScrollChild_DelegatingRenderer) {
672 device_scale_factor_ = 1.f;
673 scroll_child_layer_ = true;
674 RunTest(true, true);
677 TEST_F(LayerTreeHostScrollTestCaseWithChild,
678 DeviceScaleFactor15_ScrollChild_DirectRenderer) {
679 device_scale_factor_ = 1.5f;
680 scroll_child_layer_ = true;
681 RunTest(true, false);
684 TEST_F(LayerTreeHostScrollTestCaseWithChild,
685 DeviceScaleFactor15_ScrollChild_DelegatingRenderer) {
686 device_scale_factor_ = 1.5f;
687 scroll_child_layer_ = true;
688 RunTest(true, true);
691 TEST_F(LayerTreeHostScrollTestCaseWithChild,
692 DeviceScaleFactor2_ScrollChild_DirectRenderer) {
693 device_scale_factor_ = 2.f;
694 scroll_child_layer_ = true;
695 RunTest(true, false);
698 TEST_F(LayerTreeHostScrollTestCaseWithChild,
699 DeviceScaleFactor2_ScrollChild_DelegatingRenderer) {
700 device_scale_factor_ = 2.f;
701 scroll_child_layer_ = true;
702 RunTest(true, true);
705 TEST_F(LayerTreeHostScrollTestCaseWithChild,
706 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer) {
707 device_scale_factor_ = 1.f;
708 scroll_child_layer_ = false;
709 RunTest(true, false);
712 TEST_F(LayerTreeHostScrollTestCaseWithChild,
713 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer) {
714 device_scale_factor_ = 1.f;
715 scroll_child_layer_ = false;
716 RunTest(true, true);
719 TEST_F(LayerTreeHostScrollTestCaseWithChild,
720 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer) {
721 device_scale_factor_ = 1.5f;
722 scroll_child_layer_ = false;
723 RunTest(true, false);
726 TEST_F(LayerTreeHostScrollTestCaseWithChild,
727 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer) {
728 device_scale_factor_ = 1.5f;
729 scroll_child_layer_ = false;
730 RunTest(true, true);
733 TEST_F(LayerTreeHostScrollTestCaseWithChild,
734 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer) {
735 device_scale_factor_ = 2.f;
736 scroll_child_layer_ = false;
737 RunTest(true, false);
740 TEST_F(LayerTreeHostScrollTestCaseWithChild,
741 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer) {
742 device_scale_factor_ = 2.f;
743 scroll_child_layer_ = false;
744 RunTest(true, true);
747 class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest {
748 public:
749 LayerTreeHostScrollTestSimple()
750 : initial_scroll_(10, 20),
751 main_thread_scroll_(40, 5),
752 impl_thread_scroll1_(2, -1),
753 impl_thread_scroll2_(-3, 10),
754 num_scrolls_(0) {}
756 void SetupTree() override {
757 LayerTreeHostScrollTest::SetupTree();
758 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
761 void BeginTest() override {
762 layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
763 initial_scroll_);
764 PostSetNeedsCommitToMainThread();
767 void Layout() override {
768 Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
769 if (!layer_tree_host()->source_frame_number()) {
770 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
771 } else {
772 EXPECT_VECTOR_EQ(
773 scroll_layer->scroll_offset(),
774 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll1_));
776 // Pretend like Javascript updated the scroll position itself with a
777 // change of main_thread_scroll.
778 scroll_layer->SetScrollOffset(
779 gfx::ScrollOffsetWithDelta(
780 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
784 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
785 // We force a second draw here of the first commit before activating
786 // the second commit.
787 if (impl->active_tree()->source_frame_number() == 0)
788 impl->SetNeedsRedraw();
791 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
792 if (impl->pending_tree())
793 impl->SetNeedsRedraw();
795 LayerImpl* root = impl->active_tree()->root_layer();
796 LayerImpl* scroll_layer = impl->OuterViewportScrollLayer();
797 LayerImpl* pending_root =
798 impl->active_tree()->FindPendingTreeLayerById(root->id());
800 switch (impl->active_tree()->source_frame_number()) {
801 case 0:
802 if (!impl->pending_tree()) {
803 impl->BlockNotifyReadyToActivateForTesting(true);
804 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer->ScrollDelta());
805 scroll_layer->ScrollBy(impl_thread_scroll1_);
807 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->BaseScrollOffset());
808 EXPECT_VECTOR_EQ(impl_thread_scroll1_, scroll_layer->ScrollDelta());
809 PostSetNeedsCommitToMainThread();
811 // CommitCompleteOnThread will trigger this function again
812 // and cause us to take the else clause.
813 } else {
814 impl->BlockNotifyReadyToActivateForTesting(false);
815 ASSERT_TRUE(pending_root);
816 EXPECT_EQ(impl->pending_tree()->source_frame_number(), 1);
818 scroll_layer->ScrollBy(impl_thread_scroll2_);
819 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->BaseScrollOffset());
820 EXPECT_VECTOR_EQ(impl_thread_scroll1_ + impl_thread_scroll2_,
821 scroll_layer->ScrollDelta());
823 LayerImpl* pending_scroll_layer =
824 impl->pending_tree()->OuterViewportScrollLayer();
825 EXPECT_VECTOR_EQ(
826 gfx::ScrollOffsetWithDelta(
827 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_),
828 pending_scroll_layer->BaseScrollOffset());
829 EXPECT_VECTOR_EQ(impl_thread_scroll2_,
830 pending_scroll_layer->ScrollDelta());
832 break;
833 case 1:
834 EXPECT_FALSE(impl->pending_tree());
835 EXPECT_VECTOR_EQ(
836 gfx::ScrollOffsetWithDelta(
837 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_),
838 scroll_layer->BaseScrollOffset());
839 EXPECT_VECTOR_EQ(impl_thread_scroll2_, scroll_layer->ScrollDelta());
840 EndTest();
841 break;
845 void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
846 const gfx::Vector2dF& outer_delta,
847 const gfx::Vector2dF& elastic_overscroll_delta,
848 float scale,
849 float top_controls_delta) override {
850 num_scrolls_++;
853 void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }
855 private:
856 gfx::ScrollOffset initial_scroll_;
857 gfx::Vector2dF main_thread_scroll_;
858 gfx::Vector2dF impl_thread_scroll1_;
859 gfx::Vector2dF impl_thread_scroll2_;
860 int num_scrolls_;
863 // This tests scrolling on the impl side which is only possible with a thread.
864 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestSimple);
866 // This test makes sure that layers pick up scrolls that occur between
867 // beginning a commit and finishing a commit (aka scroll deltas not
868 // included in sent scroll delta) still apply to layers that don't
869 // push properties.
870 class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest {
871 public:
872 LayerTreeHostScrollTestImplOnlyScroll()
873 : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3), impl_scale_(2.f) {}
875 void SetupTree() override {
876 LayerTreeHostScrollTest::SetupTree();
877 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
880 void BeginTest() override {
881 layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
882 initial_scroll_);
883 PostSetNeedsCommitToMainThread();
886 void WillCommit() override {
887 Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
888 switch (layer_tree_host()->source_frame_number()) {
889 case 0:
890 EXPECT_TRUE(scroll_layer->needs_push_properties());
891 break;
892 case 1:
893 // Even if this layer doesn't need push properties, it should
894 // still pick up scrolls that happen on the active layer during
895 // commit.
896 EXPECT_FALSE(scroll_layer->needs_push_properties());
897 break;
901 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
902 // Scroll after the 2nd commit has started.
903 if (impl->active_tree()->source_frame_number() == 0) {
904 LayerImpl* active_root = impl->active_tree()->root_layer();
905 LayerImpl* active_scroll_layer = impl->OuterViewportScrollLayer();
906 ASSERT_TRUE(active_root);
907 ASSERT_TRUE(active_scroll_layer);
908 active_scroll_layer->ScrollBy(impl_thread_scroll_);
909 impl->SetPageScaleOnActiveTree(impl_scale_);
913 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
914 // We force a second draw here of the first commit before activating
915 // the second commit.
916 LayerImpl* active_root = impl->active_tree()->root_layer();
917 LayerImpl* active_scroll_layer =
918 active_root ? impl->OuterViewportScrollLayer() : NULL;
919 LayerImpl* pending_root = impl->pending_tree()->root_layer();
920 LayerImpl* pending_scroll_layer =
921 impl->pending_tree()->OuterViewportScrollLayer();
923 ASSERT_TRUE(pending_root);
924 ASSERT_TRUE(pending_scroll_layer);
925 switch (impl->pending_tree()->source_frame_number()) {
926 case 0:
927 EXPECT_VECTOR_EQ(initial_scroll_,
928 pending_scroll_layer->BaseScrollOffset());
929 EXPECT_VECTOR_EQ(gfx::Vector2d(), pending_scroll_layer->ScrollDelta());
930 EXPECT_FALSE(active_root);
931 break;
932 case 1:
933 // Even though the scroll happened during the commit, both layers
934 // should have the appropriate scroll delta.
935 EXPECT_VECTOR_EQ(initial_scroll_,
936 pending_scroll_layer->BaseScrollOffset());
937 EXPECT_VECTOR_EQ(impl_thread_scroll_,
938 pending_scroll_layer->ScrollDelta());
939 ASSERT_TRUE(active_root);
940 EXPECT_VECTOR_EQ(initial_scroll_,
941 active_scroll_layer->BaseScrollOffset());
942 EXPECT_VECTOR_EQ(impl_thread_scroll_,
943 active_scroll_layer->ScrollDelta());
944 break;
945 case 2:
946 // On the next commit, this delta should have been sent and applied.
947 EXPECT_VECTOR_EQ(
948 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll_),
949 pending_scroll_layer->BaseScrollOffset());
950 EXPECT_VECTOR_EQ(gfx::Vector2d(), pending_scroll_layer->ScrollDelta());
951 break;
955 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
956 if (impl->pending_tree())
957 impl->SetNeedsRedraw();
959 LayerImpl* scroll_layer = impl->OuterViewportScrollLayer();
961 switch (impl->active_tree()->source_frame_number()) {
962 case 0:
963 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->BaseScrollOffset());
964 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer->ScrollDelta());
965 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
966 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
967 PostSetNeedsCommitToMainThread();
968 break;
969 case 1:
970 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->BaseScrollOffset());
971 EXPECT_VECTOR_EQ(impl_thread_scroll_, scroll_layer->ScrollDelta());
972 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
973 EXPECT_EQ(impl_scale_,
974 impl->active_tree()->current_page_scale_factor());
975 PostSetNeedsCommitToMainThread();
976 break;
977 case 2:
978 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
979 EXPECT_EQ(impl_scale_,
980 impl->active_tree()->current_page_scale_factor());
981 EndTest();
982 break;
986 void AfterTest() override {}
988 private:
989 gfx::ScrollOffset initial_scroll_;
990 gfx::Vector2dF impl_thread_scroll_;
991 float impl_scale_;
994 // This tests scrolling on the impl side which is only possible with a thread.
995 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplOnlyScroll);
997 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
998 : public LayerTreeHostScrollTest {
999 public:
1000 LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
1002 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1004 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1005 LayerImpl* root = impl->active_tree()->root_layer();
1006 LayerImpl* scroll_layer = impl->OuterViewportScrollLayer();
1007 scroll_layer->SetScrollClipLayer(root->id());
1009 // Set max_scroll_offset = (100, 100).
1010 scroll_layer->SetBounds(
1011 gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
1012 EXPECT_EQ(
1013 InputHandler::SCROLL_STARTED,
1014 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE,
1015 SCROLL_BLOCKS_ON_NONE));
1017 // Set max_scroll_offset = (0, 0).
1018 scroll_layer->SetBounds(root->bounds());
1019 EXPECT_EQ(
1020 InputHandler::SCROLL_IGNORED,
1021 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE,
1022 SCROLL_BLOCKS_ON_NONE));
1024 // Set max_scroll_offset = (-100, -100).
1025 scroll_layer->SetBounds(gfx::Size());
1026 EXPECT_EQ(
1027 InputHandler::SCROLL_IGNORED,
1028 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE,
1029 SCROLL_BLOCKS_ON_NONE));
1031 EndTest();
1034 void AfterTest() override {}
1037 SINGLE_AND_MULTI_THREAD_TEST_F(
1038 LayerTreeHostScrollTestScrollZeroMaxScrollOffset);
1040 class ThreadCheckingInputHandlerClient : public InputHandlerClient {
1041 public:
1042 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner* runner,
1043 bool* received_stop_flinging)
1044 : task_runner_(runner), received_stop_flinging_(received_stop_flinging) {}
1046 void WillShutdown() override {
1047 if (!received_stop_flinging_)
1048 ADD_FAILURE() << "WillShutdown() called before fling stopped";
1051 void Animate(base::TimeTicks time) override {
1052 if (!task_runner_->BelongsToCurrentThread())
1053 ADD_FAILURE() << "Animate called on wrong thread";
1056 void MainThreadHasStoppedFlinging() override {
1057 if (!task_runner_->BelongsToCurrentThread())
1058 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
1059 *received_stop_flinging_ = true;
1062 void ReconcileElasticOverscrollAndRootScroll() override {
1063 if (!task_runner_->BelongsToCurrentThread()) {
1064 ADD_FAILURE() << "ReconcileElasticOverscrollAndRootScroll called on "
1065 << "wrong thread";
1069 private:
1070 base::SingleThreadTaskRunner* task_runner_;
1071 bool* received_stop_flinging_;
1074 void BindInputHandlerOnCompositorThread(
1075 const base::WeakPtr<InputHandler>& input_handler,
1076 ThreadCheckingInputHandlerClient* client) {
1077 input_handler->BindToClient(client);
1080 TEST(LayerTreeHostFlingTest, DidStopFlingingThread) {
1081 base::Thread impl_thread("cc");
1082 ASSERT_TRUE(impl_thread.Start());
1084 bool received_stop_flinging = false;
1085 LayerTreeSettings settings;
1087 ThreadCheckingInputHandlerClient input_handler_client(
1088 impl_thread.task_runner().get(), &received_stop_flinging);
1089 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1091 ASSERT_TRUE(impl_thread.task_runner());
1092 TestSharedBitmapManager shared_bitmap_manager;
1093 TestTaskGraphRunner task_graph_runner;
1095 LayerTreeHost::InitParams params;
1096 params.client = &client;
1097 params.shared_bitmap_manager = &shared_bitmap_manager;
1098 params.task_graph_runner = &task_graph_runner;
1099 params.settings = &settings;
1100 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
1101 scoped_ptr<LayerTreeHost> layer_tree_host =
1102 LayerTreeHost::CreateThreaded(impl_thread.task_runner(), &params);
1104 impl_thread.task_runner()->PostTask(
1105 FROM_HERE, base::Bind(&BindInputHandlerOnCompositorThread,
1106 layer_tree_host->GetInputHandler(),
1107 base::Unretained(&input_handler_client)));
1109 layer_tree_host->DidStopFlinging();
1110 layer_tree_host = nullptr;
1111 impl_thread.Stop();
1112 EXPECT_TRUE(received_stop_flinging);
1115 class LayerTreeHostScrollTestLayerStructureChange
1116 : public LayerTreeHostScrollTest {
1117 public:
1118 LayerTreeHostScrollTestLayerStructureChange()
1119 : scroll_destroy_whole_tree_(false) {}
1121 void SetupTree() override {
1122 LayerTreeTest::SetupTree();
1123 Layer* root_layer = layer_tree_host()->root_layer();
1124 root_layer->SetBounds(gfx::Size(10, 10));
1126 CreateVirtualViewportLayers(root_layer,
1127 root_layer->bounds(),
1128 root_layer->bounds(),
1129 root_layer->bounds(),
1130 layer_tree_host(),
1131 layer_settings());
1133 Layer* outer_scroll_layer =
1134 layer_tree_host()->outer_viewport_scroll_layer();
1136 Layer* root_scroll_layer =
1137 CreateScrollLayer(outer_scroll_layer, &root_scroll_layer_client_);
1138 CreateScrollLayer(outer_scroll_layer, &sibling_scroll_layer_client_);
1139 CreateScrollLayer(root_scroll_layer, &child_scroll_layer_client_);
1142 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1144 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1145 LayerImpl* root = impl->OuterViewportScrollLayer();
1146 switch (impl->active_tree()->source_frame_number()) {
1147 case 0:
1148 root->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1149 root->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1150 root->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5));
1151 PostSetNeedsCommitToMainThread();
1152 break;
1153 case 1:
1154 EndTest();
1155 break;
1159 void AfterTest() override {}
1161 virtual void DidScroll(Layer* layer) {
1162 if (scroll_destroy_whole_tree_) {
1163 layer_tree_host()->RegisterViewportLayers(NULL, NULL, NULL, NULL);
1164 layer_tree_host()->SetRootLayer(NULL);
1165 EndTest();
1166 return;
1168 layer->RemoveFromParent();
1171 protected:
1172 class FakeLayerScrollClient {
1173 public:
1174 void DidScroll() {
1175 owner_->DidScroll(layer_);
1177 LayerTreeHostScrollTestLayerStructureChange* owner_;
1178 Layer* layer_;
1181 Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) {
1182 scoped_refptr<PictureLayer> scroll_layer =
1183 PictureLayer::Create(layer_settings(), &fake_content_layer_client_);
1184 scroll_layer->SetBounds(gfx::Size(110, 110));
1185 scroll_layer->SetPosition(gfx::Point(0, 0));
1186 scroll_layer->SetIsDrawable(true);
1187 scroll_layer->SetScrollClipLayerId(parent->id());
1188 scroll_layer->SetBounds(gfx::Size(parent->bounds().width() + 100,
1189 parent->bounds().height() + 100));
1190 scroll_layer->set_did_scroll_callback(base::Bind(
1191 &FakeLayerScrollClient::DidScroll, base::Unretained(client)));
1192 client->owner_ = this;
1193 client->layer_ = scroll_layer.get();
1194 parent->AddChild(scroll_layer);
1195 return scroll_layer.get();
1198 FakeLayerScrollClient root_scroll_layer_client_;
1199 FakeLayerScrollClient sibling_scroll_layer_client_;
1200 FakeLayerScrollClient child_scroll_layer_client_;
1202 FakeContentLayerClient fake_content_layer_client_;
1204 bool scroll_destroy_whole_tree_;
1207 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyLayer) {
1208 RunTest(true, false);
1211 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) {
1212 scroll_destroy_whole_tree_ = true;
1213 RunTest(true, false);
1216 } // namespace
1217 } // namespace cc