Blink roll 25b6bd3a7a131ffe68d809546ad1a20707915cdc:3a503f41ae42e5b79cfcd2ff10e65afde...
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_scroll.cc
blob6526ff8ea6ded265dfb059af3ae398f9384bd309
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/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"
24 namespace cc {
25 namespace {
27 class LayerTreeHostScrollTest : public LayerTreeTest {};
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) {}
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(root_layer, scroll_layer, NULL);
49 PostSetNeedsCommitToMainThread();
52 void Layout() override {
53 Layer* root = layer_tree_host()->root_layer();
54 Layer* scroll_layer = root->children()[0].get();
55 if (!layer_tree_host()->source_frame_number()) {
56 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
57 } else {
58 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_,
59 scroll_amount_),
60 scroll_layer->scroll_offset());
62 // Pretend like Javascript updated the scroll position itself.
63 scroll_layer->SetScrollOffset(second_scroll_);
67 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
68 LayerImpl* root = impl->active_tree()->root_layer();
69 LayerImpl* scroll_layer = root->children()[0];
70 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer->ScrollDelta());
72 scroll_layer->SetScrollClipLayer(root->id());
73 scroll_layer->SetBounds(
74 gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
75 scroll_layer->ScrollBy(scroll_amount_);
77 switch (impl->active_tree()->source_frame_number()) {
78 case 0:
79 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
80 EXPECT_VECTOR_EQ(scroll_amount_, scroll_layer->ScrollDelta());
81 PostSetNeedsCommitToMainThread();
82 break;
83 case 1:
84 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), second_scroll_);
85 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
86 EndTest();
87 break;
91 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
92 float scale,
93 float top_controls_delta) override {
94 num_scrolls_++;
97 void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }
99 private:
100 gfx::ScrollOffset initial_scroll_;
101 gfx::ScrollOffset second_scroll_;
102 gfx::Vector2dF scroll_amount_;
103 int num_scrolls_;
106 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple);
108 class LayerTreeHostScrollTestScrollMultipleRedraw
109 : public LayerTreeHostScrollTest {
110 public:
111 LayerTreeHostScrollTestScrollMultipleRedraw()
112 : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
114 void BeginTest() override {
115 Layer* root_layer = layer_tree_host()->root_layer();
116 scroll_layer_ = Layer::Create();
117 root_layer->AddChild(scroll_layer_);
118 // Create an effective max_scroll_offset of (100, 100).
119 scroll_layer_->SetBounds(gfx::Size(root_layer->bounds().width() + 100,
120 root_layer->bounds().height() + 100));
121 scroll_layer_->SetIsDrawable(true);
122 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
123 scroll_layer_->SetScrollClipLayerId(root_layer->id());
124 scroll_layer_->SetScrollOffset(initial_scroll_);
125 layer_tree_host()->RegisterViewportLayers(root_layer, scroll_layer_, NULL);
126 PostSetNeedsCommitToMainThread();
129 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
130 switch (layer_tree_host()->source_frame_number()) {
131 case 0:
132 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_);
133 break;
134 case 1:
135 EXPECT_VECTOR_EQ(
136 scroll_layer_->scroll_offset(),
137 gfx::ScrollOffsetWithDelta(initial_scroll_,
138 scroll_amount_ + scroll_amount_));
139 case 2:
140 EXPECT_VECTOR_EQ(
141 scroll_layer_->scroll_offset(),
142 gfx::ScrollOffsetWithDelta(initial_scroll_,
143 scroll_amount_ + scroll_amount_));
144 break;
148 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
149 LayerImpl* scroll_layer =
150 impl->active_tree()->LayerById(scroll_layer_->id());
151 if (impl->active_tree()->source_frame_number() == 0 &&
152 impl->SourceAnimationFrameNumber() == 1) {
153 // First draw after first commit.
154 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
155 scroll_layer->ScrollBy(scroll_amount_);
156 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
158 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
159 PostSetNeedsRedrawToMainThread();
160 } else if (impl->active_tree()->source_frame_number() == 0 &&
161 impl->SourceAnimationFrameNumber() == 2) {
162 // Second draw after first commit.
163 EXPECT_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
164 scroll_layer->ScrollBy(scroll_amount_);
165 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
166 scroll_amount_ + scroll_amount_);
168 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_);
169 PostSetNeedsCommitToMainThread();
170 } else if (impl->active_tree()->source_frame_number() == 1) {
171 // Third or later draw after second commit.
172 EXPECT_GE(impl->SourceAnimationFrameNumber(), 3);
173 EXPECT_VECTOR_EQ(scroll_layer_->ScrollDelta(), gfx::Vector2d());
174 EXPECT_VECTOR_EQ(
175 scroll_layer_->scroll_offset(),
176 gfx::ScrollOffsetWithDelta(initial_scroll_,
177 scroll_amount_ + scroll_amount_));
178 EndTest();
182 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
183 float scale,
184 float top_controls_delta) override {
185 num_scrolls_++;
188 void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }
190 private:
191 gfx::ScrollOffset initial_scroll_;
192 gfx::Vector2dF scroll_amount_;
193 int num_scrolls_;
194 scoped_refptr<Layer> scroll_layer_;
197 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw);
199 class LayerTreeHostScrollTestScrollAbortedCommit
200 : public LayerTreeHostScrollTest {
201 public:
202 LayerTreeHostScrollTestScrollAbortedCommit()
203 : initial_scroll_(50, 60),
204 impl_scroll_(-3, 2),
205 second_main_scroll_(14, -3),
206 impl_scale_(2.f),
207 num_will_begin_main_frames_(0),
208 num_did_begin_main_frames_(0),
209 num_will_commits_(0),
210 num_did_commits_(0),
211 num_impl_commits_(0),
212 num_impl_scrolls_(0) {}
214 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
216 void SetupTree() override {
217 LayerTreeHostScrollTest::SetupTree();
218 Layer* root_layer = layer_tree_host()->root_layer();
219 scoped_refptr<Layer> root_scroll_layer = Layer::Create();
220 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
221 root_scroll_layer->SetScrollOffset(initial_scroll_);
222 root_scroll_layer->SetBounds(gfx::Size(200, 200));
223 root_scroll_layer->SetIsDrawable(true);
224 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
225 root_layer->AddChild(root_scroll_layer);
227 layer_tree_host()->RegisterViewportLayers(
228 root_layer, root_scroll_layer, NULL);
229 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
232 void WillBeginMainFrame() override {
233 num_will_begin_main_frames_++;
234 Layer* root_scroll_layer =
235 layer_tree_host()->root_layer()->children()[0].get();
236 switch (num_will_begin_main_frames_) {
237 case 1:
238 // This will not be aborted because of the initial prop changes.
239 EXPECT_EQ(0, num_impl_scrolls_);
240 EXPECT_EQ(0, layer_tree_host()->source_frame_number());
241 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_);
242 EXPECT_EQ(1.f, layer_tree_host()->page_scale_factor());
243 break;
244 case 2:
245 // This commit will be aborted, and another commit will be
246 // initiated from the redraw.
247 EXPECT_EQ(1, num_impl_scrolls_);
248 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
249 EXPECT_VECTOR_EQ(
250 root_scroll_layer->scroll_offset(),
251 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_));
252 EXPECT_EQ(impl_scale_, layer_tree_host()->page_scale_factor());
253 PostSetNeedsRedrawToMainThread();
254 break;
255 case 3:
256 // This commit will not be aborted because of the scroll change.
257 EXPECT_EQ(2, num_impl_scrolls_);
258 // The source frame number still increases even with the abort.
259 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
260 EXPECT_VECTOR_EQ(
261 root_scroll_layer->scroll_offset(),
262 gfx::ScrollOffsetWithDelta(initial_scroll_,
263 impl_scroll_ + impl_scroll_));
264 EXPECT_EQ(impl_scale_ * impl_scale_,
265 layer_tree_host()->page_scale_factor());
266 root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta(
267 root_scroll_layer->scroll_offset(), second_main_scroll_));
268 break;
269 case 4:
270 // This commit will also be aborted.
271 EXPECT_EQ(3, num_impl_scrolls_);
272 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
273 gfx::Vector2dF delta =
274 impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
275 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
276 gfx::ScrollOffsetWithDelta(initial_scroll_, delta));
278 // End the test by drawing to verify this commit is also aborted.
279 PostSetNeedsRedrawToMainThread();
280 break;
284 void DidBeginMainFrame() override { num_did_begin_main_frames_++; }
286 void WillCommit() override { num_will_commits_++; }
288 void DidCommit() override { num_did_commits_++; }
290 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
291 num_impl_commits_++;
294 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
295 LayerImpl* root_scroll_layer =
296 impl->active_tree()->root_layer()->children()[0];
298 if (impl->active_tree()->source_frame_number() == 0 &&
299 impl->SourceAnimationFrameNumber() == 1) {
300 // First draw
301 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
302 root_scroll_layer->ScrollBy(impl_scroll_);
303 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
304 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_);
306 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
307 EXPECT_EQ(1.f, impl->active_tree()->total_page_scale_factor());
308 impl->active_tree()->SetPageScaleDelta(impl_scale_);
309 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
310 EXPECT_EQ(impl_scale_, impl->active_tree()->total_page_scale_factor());
312 // To simplify the testing flow, don't redraw here, just commit.
313 impl->SetNeedsCommit();
314 } else if (impl->active_tree()->source_frame_number() == 0 &&
315 impl->SourceAnimationFrameNumber() == 2) {
316 // Test a second draw after an aborted commit.
317 // The scroll/scale values should be baked into the offset/scale factor
318 // since the main thread consumed but aborted the begin frame.
319 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
320 root_scroll_layer->ScrollBy(impl_scroll_);
321 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
322 EXPECT_VECTOR_EQ(
323 root_scroll_layer->scroll_offset(),
324 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_));
326 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
327 EXPECT_EQ(impl_scale_, impl->active_tree()->total_page_scale_factor());
328 impl->active_tree()->SetPageScaleDelta(impl_scale_);
329 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
330 EXPECT_EQ(impl_scale_ * impl_scale_,
331 impl->active_tree()->total_page_scale_factor());
333 impl->SetNeedsCommit();
334 } else if (impl->active_tree()->source_frame_number() == 1) {
335 // Commit for source frame 1 is aborted.
336 NOTREACHED();
337 } else if (impl->active_tree()->source_frame_number() == 2 &&
338 impl->SourceAnimationFrameNumber() == 3) {
339 // Third draw after the second full commit.
340 EXPECT_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
341 root_scroll_layer->ScrollBy(impl_scroll_);
342 impl->SetNeedsCommit();
343 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
344 gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + second_main_scroll_;
345 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
346 gfx::ScrollOffsetWithDelta(initial_scroll_, delta));
347 } else if (impl->active_tree()->source_frame_number() == 2 &&
348 impl->SourceAnimationFrameNumber() == 4) {
349 // Final draw after the second aborted commit.
350 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
351 gfx::Vector2dF delta =
352 impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
353 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
354 gfx::ScrollOffsetWithDelta(initial_scroll_, delta));
355 EndTest();
356 } else {
357 // Commit for source frame 3 is aborted.
358 NOTREACHED();
362 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
363 float scale,
364 float top_controls_delta) override {
365 num_impl_scrolls_++;
368 void AfterTest() override {
369 EXPECT_EQ(3, num_impl_scrolls_);
370 // Verify that the embedder sees aborted commits as real commits.
371 EXPECT_EQ(4, num_will_begin_main_frames_);
372 EXPECT_EQ(4, num_did_begin_main_frames_);
373 EXPECT_EQ(4, num_will_commits_);
374 EXPECT_EQ(4, num_did_commits_);
375 // ...but the compositor thread only sees two real ones.
376 EXPECT_EQ(2, num_impl_commits_);
379 private:
380 gfx::ScrollOffset initial_scroll_;
381 gfx::Vector2dF impl_scroll_;
382 gfx::Vector2dF second_main_scroll_;
383 float impl_scale_;
384 int num_will_begin_main_frames_;
385 int num_did_begin_main_frames_;
386 int num_will_commits_;
387 int num_did_commits_;
388 int num_impl_commits_;
389 int num_impl_scrolls_;
392 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit);
394 class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest {
395 public:
396 LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
398 void SetupTree() override {
399 LayerTreeHostScrollTest::SetupTree();
400 Layer* root_layer = layer_tree_host()->root_layer();
401 scoped_refptr<Layer> root_scroll_layer = Layer::Create();
402 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
403 root_scroll_layer->SetBounds(
404 gfx::Size(root_layer->bounds().width() + 100,
405 root_layer->bounds().height() + 100));
406 root_scroll_layer->SetIsDrawable(true);
407 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
408 root_layer->AddChild(root_scroll_layer);
410 layer_tree_host()->RegisterViewportLayers(
411 root_layer, root_scroll_layer, NULL);
412 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
415 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
417 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
418 LayerImpl* root = impl->active_tree()->root_layer();
419 LayerImpl* scroll_layer = root->children()[0];
421 // Check that a fractional scroll delta is correctly accumulated over
422 // multiple commits.
423 switch (impl->active_tree()->source_frame_number()) {
424 case 0:
425 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), gfx::Vector2d(0, 0));
426 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d(0, 0));
427 PostSetNeedsCommitToMainThread();
428 break;
429 case 1:
430 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(),
431 gfx::ToFlooredVector2d(scroll_amount_));
432 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
433 gfx::Vector2dF(fmod(scroll_amount_.x(), 1.0f), 0.0f));
434 PostSetNeedsCommitToMainThread();
435 break;
436 case 2:
437 EXPECT_VECTOR_EQ(
438 scroll_layer->scroll_offset(),
439 gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_));
440 EXPECT_VECTOR_EQ(
441 scroll_layer->ScrollDelta(),
442 gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f));
443 EndTest();
444 break;
446 scroll_layer->ScrollBy(scroll_amount_);
449 void AfterTest() override {}
451 private:
452 gfx::Vector2dF scroll_amount_;
455 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll);
457 class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
458 public:
459 LayerTreeHostScrollTestCaseWithChild()
460 : initial_offset_(10, 20),
461 javascript_scroll_(40, 5),
462 scroll_amount_(2, -1),
463 num_scrolls_(0) {}
465 void SetupTree() override {
466 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
468 scoped_refptr<Layer> root_layer = Layer::Create();
469 root_layer->SetBounds(gfx::Size(10, 10));
471 root_scroll_layer_ = FakePictureLayer::Create(&fake_content_layer_client_);
472 root_scroll_layer_->SetBounds(gfx::Size(110, 110));
474 root_scroll_layer_->SetPosition(gfx::Point());
476 root_scroll_layer_->SetIsDrawable(true);
477 root_scroll_layer_->SetScrollClipLayerId(root_layer->id());
478 root_scroll_layer_->SetIsContainerForFixedPositionLayers(true);
479 root_layer->AddChild(root_scroll_layer_);
481 child_layer_ = FakePictureLayer::Create(&fake_content_layer_client_);
482 child_layer_->set_did_scroll_callback(
483 base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
484 base::Unretained(this)));
485 child_layer_->SetBounds(gfx::Size(110, 110));
487 if (scroll_child_layer_) {
488 // Scrolls on the child layer will happen at 5, 5. If they are treated
489 // like device pixels, and device scale factor is 2, then they will
490 // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
491 child_layer_->SetPosition(gfx::Point(5, 5));
492 } else {
493 // Adjust the child layer horizontally so that scrolls will never hit it.
494 child_layer_->SetPosition(gfx::Point(60, 5));
497 child_layer_->SetIsDrawable(true);
498 child_layer_->SetScrollClipLayerId(root_layer->id());
499 child_layer_->SetBounds(root_scroll_layer_->bounds());
500 root_scroll_layer_->AddChild(child_layer_);
502 if (scroll_child_layer_) {
503 expected_scroll_layer_ = child_layer_;
504 expected_no_scroll_layer_ = root_scroll_layer_;
505 } else {
506 expected_scroll_layer_ = root_scroll_layer_;
507 expected_no_scroll_layer_ = child_layer_;
510 expected_scroll_layer_->SetScrollOffset(initial_offset_);
512 layer_tree_host()->SetRootLayer(root_layer);
513 layer_tree_host()->RegisterViewportLayers(
514 root_layer, root_scroll_layer_, NULL);
515 LayerTreeHostScrollTest::SetupTree();
518 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
520 void WillCommit() override {
521 // Keep the test committing (otherwise the early out for no update
522 // will stall the test).
523 if (layer_tree_host()->source_frame_number() < 2) {
524 layer_tree_host()->SetNeedsCommit();
528 void DidScroll() {
529 final_scroll_offset_ = expected_scroll_layer_->scroll_offset();
532 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
533 float scale,
534 float top_controls_delta) override {
535 num_scrolls_++;
538 void Layout() override {
539 EXPECT_VECTOR_EQ(gfx::Vector2d(),
540 expected_no_scroll_layer_->scroll_offset());
542 switch (layer_tree_host()->source_frame_number()) {
543 case 0:
544 EXPECT_VECTOR_EQ(initial_offset_,
545 expected_scroll_layer_->scroll_offset());
546 break;
547 case 1:
548 EXPECT_VECTOR_EQ(
549 gfx::ScrollOffsetWithDelta(initial_offset_, scroll_amount_),
550 expected_scroll_layer_->scroll_offset());
552 // Pretend like Javascript updated the scroll position itself.
553 expected_scroll_layer_->SetScrollOffset(javascript_scroll_);
554 break;
555 case 2:
556 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_,
557 scroll_amount_),
558 expected_scroll_layer_->scroll_offset());
559 break;
563 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
564 LayerImpl* root_impl = impl->active_tree()->root_layer();
565 FakePictureLayerImpl* root_scroll_layer_impl =
566 static_cast<FakePictureLayerImpl*>(root_impl->children()[0]);
567 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>(
568 root_scroll_layer_impl->children()[0]);
570 LayerImpl* expected_scroll_layer_impl = NULL;
571 LayerImpl* expected_no_scroll_layer_impl = NULL;
572 if (scroll_child_layer_) {
573 expected_scroll_layer_impl = child_layer_impl;
574 expected_no_scroll_layer_impl = root_scroll_layer_impl;
575 } else {
576 expected_scroll_layer_impl = root_scroll_layer_impl;
577 expected_no_scroll_layer_impl = child_layer_impl;
580 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl->ScrollDelta());
581 EXPECT_VECTOR_EQ(gfx::Vector2d(),
582 expected_no_scroll_layer_impl->ScrollDelta());
584 // Ensure device scale factor matches the active tree.
585 EXPECT_EQ(device_scale_factor_, impl->active_tree()->device_scale_factor());
586 switch (impl->active_tree()->source_frame_number()) {
587 case 0: {
588 // Gesture scroll on impl thread.
589 InputHandler::ScrollStatus status = impl->ScrollBegin(
590 gfx::ToCeiledPoint(expected_scroll_layer_impl->position() -
591 gfx::Vector2dF(0.5f, 0.5f)),
592 InputHandler::Gesture);
593 EXPECT_EQ(InputHandler::ScrollStarted, status);
594 impl->ScrollBy(gfx::Point(), scroll_amount_);
595 impl->ScrollEnd();
597 // Check the scroll is applied as a delta.
598 EXPECT_VECTOR_EQ(initial_offset_,
599 expected_scroll_layer_impl->scroll_offset());
600 EXPECT_VECTOR_EQ(scroll_amount_,
601 expected_scroll_layer_impl->ScrollDelta());
602 break;
604 case 1: {
605 // Wheel scroll on impl thread.
606 InputHandler::ScrollStatus status = impl->ScrollBegin(
607 gfx::ToCeiledPoint(expected_scroll_layer_impl->position() +
608 gfx::Vector2dF(0.5f, 0.5f)),
609 InputHandler::Wheel);
610 EXPECT_EQ(InputHandler::ScrollStarted, status);
611 impl->ScrollBy(gfx::Point(), scroll_amount_);
612 impl->ScrollEnd();
614 // Check the scroll is applied as a delta.
615 EXPECT_VECTOR_EQ(javascript_scroll_,
616 expected_scroll_layer_impl->scroll_offset());
617 EXPECT_VECTOR_EQ(scroll_amount_,
618 expected_scroll_layer_impl->ScrollDelta());
619 break;
621 case 2:
623 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_,
624 scroll_amount_),
625 expected_scroll_layer_impl->scroll_offset());
626 EXPECT_VECTOR_EQ(gfx::Vector2d(),
627 expected_scroll_layer_impl->ScrollDelta());
629 EndTest();
630 break;
634 void AfterTest() override {
635 if (scroll_child_layer_) {
636 EXPECT_EQ(0, num_scrolls_);
637 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_,
638 scroll_amount_),
639 final_scroll_offset_);
640 } else {
641 EXPECT_EQ(2, num_scrolls_);
642 EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_);
646 protected:
647 float device_scale_factor_;
648 bool scroll_child_layer_;
650 gfx::ScrollOffset initial_offset_;
651 gfx::ScrollOffset javascript_scroll_;
652 gfx::Vector2d scroll_amount_;
653 int num_scrolls_;
654 gfx::ScrollOffset final_scroll_offset_;
656 FakeContentLayerClient fake_content_layer_client_;
658 scoped_refptr<Layer> root_scroll_layer_;
659 scoped_refptr<Layer> child_layer_;
660 scoped_refptr<Layer> expected_scroll_layer_;
661 scoped_refptr<Layer> expected_no_scroll_layer_;
664 TEST_F(LayerTreeHostScrollTestCaseWithChild,
665 DeviceScaleFactor1_ScrollChild_DirectRenderer) {
666 device_scale_factor_ = 1.f;
667 scroll_child_layer_ = true;
668 RunTest(true, false, true);
671 TEST_F(LayerTreeHostScrollTestCaseWithChild,
672 DeviceScaleFactor1_ScrollChild_DelegatingRenderer) {
673 device_scale_factor_ = 1.f;
674 scroll_child_layer_ = true;
675 RunTest(true, true, true);
678 TEST_F(LayerTreeHostScrollTestCaseWithChild,
679 DeviceScaleFactor15_ScrollChild_DirectRenderer) {
680 device_scale_factor_ = 1.5f;
681 scroll_child_layer_ = true;
682 RunTest(true, false, true);
685 TEST_F(LayerTreeHostScrollTestCaseWithChild,
686 DeviceScaleFactor15_ScrollChild_DelegatingRenderer) {
687 device_scale_factor_ = 1.5f;
688 scroll_child_layer_ = true;
689 RunTest(true, true, true);
692 TEST_F(LayerTreeHostScrollTestCaseWithChild,
693 DeviceScaleFactor2_ScrollChild_DirectRenderer) {
694 device_scale_factor_ = 2.f;
695 scroll_child_layer_ = true;
696 RunTest(true, false, true);
699 TEST_F(LayerTreeHostScrollTestCaseWithChild,
700 DeviceScaleFactor2_ScrollChild_DelegatingRenderer) {
701 device_scale_factor_ = 2.f;
702 scroll_child_layer_ = true;
703 RunTest(true, true, true);
706 TEST_F(LayerTreeHostScrollTestCaseWithChild,
707 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer) {
708 device_scale_factor_ = 1.f;
709 scroll_child_layer_ = false;
710 RunTest(true, false, true);
713 TEST_F(LayerTreeHostScrollTestCaseWithChild,
714 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer) {
715 device_scale_factor_ = 1.f;
716 scroll_child_layer_ = false;
717 RunTest(true, true, true);
720 TEST_F(LayerTreeHostScrollTestCaseWithChild,
721 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer) {
722 device_scale_factor_ = 1.5f;
723 scroll_child_layer_ = false;
724 RunTest(true, false, true);
727 TEST_F(LayerTreeHostScrollTestCaseWithChild,
728 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer) {
729 device_scale_factor_ = 1.5f;
730 scroll_child_layer_ = false;
731 RunTest(true, true, true);
734 TEST_F(LayerTreeHostScrollTestCaseWithChild,
735 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer) {
736 device_scale_factor_ = 2.f;
737 scroll_child_layer_ = false;
738 RunTest(true, false, true);
741 TEST_F(LayerTreeHostScrollTestCaseWithChild,
742 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer) {
743 device_scale_factor_ = 2.f;
744 scroll_child_layer_ = false;
745 RunTest(true, true, true);
748 class ImplSidePaintingScrollTest : public LayerTreeHostScrollTest {
749 public:
750 void InitializeSettings(LayerTreeSettings* settings) override {
751 settings->impl_side_painting = true;
754 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
755 if (impl->pending_tree())
756 impl->SetNeedsRedraw();
760 class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest {
761 public:
762 ImplSidePaintingScrollTestSimple()
763 : initial_scroll_(10, 20),
764 main_thread_scroll_(40, 5),
765 impl_thread_scroll1_(2, -1),
766 impl_thread_scroll2_(-3, 10),
767 num_scrolls_(0) {}
769 void SetupTree() override {
770 LayerTreeHostScrollTest::SetupTree();
771 Layer* root_layer = layer_tree_host()->root_layer();
772 scoped_refptr<Layer> root_scroll_layer = Layer::Create();
773 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
774 root_scroll_layer->SetScrollOffset(initial_scroll_);
775 root_scroll_layer->SetBounds(
776 gfx::Size(root_layer->bounds().width() + 100,
777 root_layer->bounds().height() + 100));
778 root_scroll_layer->SetIsDrawable(true);
779 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
780 root_layer->AddChild(root_scroll_layer);
782 layer_tree_host()->RegisterViewportLayers(
783 root_layer, root_scroll_layer, NULL);
784 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
787 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
789 void Layout() override {
790 Layer* root = layer_tree_host()->root_layer();
791 Layer* scroll_layer = root->children()[0].get();
792 if (!layer_tree_host()->source_frame_number()) {
793 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
794 } else {
795 EXPECT_VECTOR_EQ(
796 scroll_layer->scroll_offset(),
797 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll1_));
799 // Pretend like Javascript updated the scroll position itself with a
800 // change of main_thread_scroll.
801 scroll_layer->SetScrollOffset(
802 gfx::ScrollOffsetWithDelta(
803 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
807 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
808 // We force a second draw here of the first commit before activating
809 // the second commit.
810 if (impl->active_tree()->source_frame_number() == 0)
811 impl->SetNeedsRedraw();
814 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
815 ImplSidePaintingScrollTest::DrawLayersOnThread(impl);
817 LayerImpl* root = impl->active_tree()->root_layer();
818 LayerImpl* scroll_layer = root->children()[0];
819 LayerImpl* pending_root =
820 impl->active_tree()->FindPendingTreeLayerById(root->id());
822 switch (impl->active_tree()->source_frame_number()) {
823 case 0:
824 if (!impl->pending_tree()) {
825 impl->BlockNotifyReadyToActivateForTesting(true);
826 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
827 scroll_layer->ScrollBy(impl_thread_scroll1_);
829 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
830 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll1_);
831 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
832 PostSetNeedsCommitToMainThread();
834 // CommitCompleteOnThread will trigger this function again
835 // and cause us to take the else clause.
836 } else {
837 impl->BlockNotifyReadyToActivateForTesting(false);
838 ASSERT_TRUE(pending_root);
839 EXPECT_EQ(impl->pending_tree()->source_frame_number(), 1);
841 scroll_layer->ScrollBy(impl_thread_scroll2_);
842 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
843 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
844 impl_thread_scroll1_ + impl_thread_scroll2_);
845 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(),
846 impl_thread_scroll1_);
848 LayerImpl* pending_scroll_layer = pending_root->children()[0];
849 EXPECT_VECTOR_EQ(
850 pending_scroll_layer->scroll_offset(),
851 gfx::ScrollOffsetWithDelta(
852 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
853 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(),
854 impl_thread_scroll2_);
855 EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
856 gfx::Vector2d());
858 break;
859 case 1:
860 EXPECT_FALSE(impl->pending_tree());
861 EXPECT_VECTOR_EQ(
862 scroll_layer->scroll_offset(),
863 gfx::ScrollOffsetWithDelta(
864 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
865 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll2_);
866 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
867 EndTest();
868 break;
872 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
873 float scale,
874 float top_controls_delta) override {
875 num_scrolls_++;
878 void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }
880 private:
881 gfx::ScrollOffset initial_scroll_;
882 gfx::Vector2dF main_thread_scroll_;
883 gfx::Vector2dF impl_thread_scroll1_;
884 gfx::Vector2dF impl_thread_scroll2_;
885 int num_scrolls_;
888 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple);
890 // This test makes sure that layers pick up scrolls that occur between
891 // beginning a commit and finishing a commit (aka scroll deltas not
892 // included in sent scroll delta) still apply to layers that don't
893 // push properties.
894 class ImplSidePaintingScrollTestImplOnlyScroll
895 : public ImplSidePaintingScrollTest {
896 public:
897 ImplSidePaintingScrollTestImplOnlyScroll()
898 : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3) {}
900 void SetupTree() override {
901 LayerTreeHostScrollTest::SetupTree();
902 Layer* root_layer = layer_tree_host()->root_layer();
903 scoped_refptr<Layer> root_scroll_layer = Layer::Create();
904 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
905 root_scroll_layer->SetScrollOffset(initial_scroll_);
906 root_scroll_layer->SetBounds(
907 gfx::Size(root_layer->bounds().width() + 100,
908 root_layer->bounds().height() + 100));
909 root_scroll_layer->SetIsDrawable(true);
910 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
911 root_layer->AddChild(root_scroll_layer);
913 layer_tree_host()->RegisterViewportLayers(
914 root_layer, root_scroll_layer, NULL);
915 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
918 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
920 void WillCommit() override {
921 Layer* root = layer_tree_host()->root_layer();
922 Layer* scroll_layer = root->children()[0].get();
923 switch (layer_tree_host()->source_frame_number()) {
924 case 0:
925 EXPECT_TRUE(scroll_layer->needs_push_properties());
926 break;
927 case 1:
928 // Even if this layer doesn't need push properties, it should
929 // still pick up scrolls that happen on the active layer during
930 // commit.
931 EXPECT_FALSE(scroll_layer->needs_push_properties());
932 break;
936 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
937 // Scroll after the 2nd commit has started.
938 if (impl->active_tree()->source_frame_number() == 0) {
939 LayerImpl* active_root = impl->active_tree()->root_layer();
940 LayerImpl* active_scroll_layer = active_root->children()[0];
941 ASSERT_TRUE(active_root);
942 ASSERT_TRUE(active_scroll_layer);
943 active_scroll_layer->ScrollBy(impl_thread_scroll_);
947 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
948 // We force a second draw here of the first commit before activating
949 // the second commit.
950 LayerImpl* active_root = impl->active_tree()->root_layer();
951 LayerImpl* active_scroll_layer =
952 active_root ? active_root->children()[0] : NULL;
953 LayerImpl* pending_root = impl->pending_tree()->root_layer();
954 LayerImpl* pending_scroll_layer = pending_root->children()[0];
956 ASSERT_TRUE(pending_root);
957 ASSERT_TRUE(pending_scroll_layer);
958 switch (impl->pending_tree()->source_frame_number()) {
959 case 0:
960 EXPECT_VECTOR_EQ(pending_scroll_layer->scroll_offset(),
961 initial_scroll_);
962 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d());
963 EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
964 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->scroll_offset(),
971 initial_scroll_);
972 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(),
973 impl_thread_scroll_);
974 EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
975 gfx::Vector2d());
976 ASSERT_TRUE(active_root);
977 EXPECT_VECTOR_EQ(active_scroll_layer->scroll_offset(), initial_scroll_);
978 EXPECT_VECTOR_EQ(active_scroll_layer->ScrollDelta(),
979 impl_thread_scroll_);
980 EXPECT_VECTOR_EQ(active_scroll_layer->sent_scroll_delta(),
981 gfx::Vector2d());
982 break;
983 case 2:
984 // On the next commit, this delta should have been sent and applied.
985 EXPECT_VECTOR_EQ(pending_scroll_layer->scroll_offset(),
986 gfx::ScrollOffsetWithDelta(initial_scroll_,
987 impl_thread_scroll_));
988 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d());
989 EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
990 gfx::Vector2d());
991 EndTest();
992 break;
996 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
997 ImplSidePaintingScrollTest::DrawLayersOnThread(impl);
999 LayerImpl* root = impl->active_tree()->root_layer();
1000 LayerImpl* scroll_layer = root->children()[0];
1002 switch (impl->active_tree()->source_frame_number()) {
1003 case 0:
1004 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
1005 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
1006 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
1007 PostSetNeedsCommitToMainThread();
1008 break;
1009 case 1:
1010 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
1011 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll_);
1012 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
1013 PostSetNeedsCommitToMainThread();
1014 break;
1018 void AfterTest() override {}
1020 private:
1021 gfx::ScrollOffset initial_scroll_;
1022 gfx::Vector2dF impl_thread_scroll_;
1025 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll);
1027 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
1028 : public LayerTreeHostScrollTest {
1029 public:
1030 LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
1032 void SetupTree() override {
1033 LayerTreeTest::SetupTree();
1034 scoped_refptr<Layer> scroll_layer = Layer::Create();
1035 layer_tree_host()->root_layer()->AddChild(scroll_layer);
1038 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1040 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1041 LayerImpl* root = impl->active_tree()->root_layer();
1042 LayerImpl* scroll_layer = root->children()[0];
1043 scroll_layer->SetScrollClipLayer(root->id());
1045 // Set max_scroll_offset = (100, 100).
1046 scroll_layer->SetBounds(
1047 gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
1048 EXPECT_EQ(InputHandler::ScrollStarted,
1049 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f),
1050 InputHandler::Gesture));
1052 // Set max_scroll_offset = (0, 0).
1053 scroll_layer->SetBounds(root->bounds());
1054 EXPECT_EQ(InputHandler::ScrollIgnored,
1055 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f),
1056 InputHandler::Gesture));
1058 // Set max_scroll_offset = (-100, -100).
1059 scroll_layer->SetBounds(gfx::Size());
1060 EXPECT_EQ(InputHandler::ScrollIgnored,
1061 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f),
1062 InputHandler::Gesture));
1064 EndTest();
1067 void AfterTest() override {}
1070 SINGLE_AND_MULTI_THREAD_TEST_F(
1071 LayerTreeHostScrollTestScrollZeroMaxScrollOffset);
1073 class ThreadCheckingInputHandlerClient : public InputHandlerClient {
1074 public:
1075 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner* runner,
1076 bool* received_stop_flinging)
1077 : task_runner_(runner), received_stop_flinging_(received_stop_flinging) {}
1079 void WillShutdown() override {
1080 if (!received_stop_flinging_)
1081 ADD_FAILURE() << "WillShutdown() called before fling stopped";
1084 void Animate(base::TimeTicks time) override {
1085 if (!task_runner_->BelongsToCurrentThread())
1086 ADD_FAILURE() << "Animate called on wrong thread";
1089 void MainThreadHasStoppedFlinging() override {
1090 if (!task_runner_->BelongsToCurrentThread())
1091 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
1092 *received_stop_flinging_ = true;
1095 private:
1096 base::SingleThreadTaskRunner* task_runner_;
1097 bool* received_stop_flinging_;
1100 void BindInputHandlerOnCompositorThread(
1101 const base::WeakPtr<InputHandler>& input_handler,
1102 ThreadCheckingInputHandlerClient* client) {
1103 input_handler->BindToClient(client);
1106 TEST(LayerTreeHostFlingTest, DidStopFlingingThread) {
1107 base::Thread impl_thread("cc");
1108 ASSERT_TRUE(impl_thread.Start());
1110 bool received_stop_flinging = false;
1111 LayerTreeSettings settings;
1113 ThreadCheckingInputHandlerClient input_handler_client(
1114 impl_thread.message_loop_proxy().get(), &received_stop_flinging);
1115 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1117 ASSERT_TRUE(impl_thread.message_loop_proxy().get());
1118 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1119 new TestSharedBitmapManager());
1120 scoped_ptr<LayerTreeHost> layer_tree_host =
1121 LayerTreeHost::CreateThreaded(&client,
1122 shared_bitmap_manager.get(),
1123 NULL,
1124 settings,
1125 base::MessageLoopProxy::current(),
1126 impl_thread.message_loop_proxy(),
1127 nullptr);
1129 impl_thread.message_loop_proxy()
1130 ->PostTask(FROM_HERE,
1131 base::Bind(&BindInputHandlerOnCompositorThread,
1132 layer_tree_host->GetInputHandler(),
1133 base::Unretained(&input_handler_client)));
1135 layer_tree_host->DidStopFlinging();
1136 layer_tree_host = nullptr;
1137 impl_thread.Stop();
1138 EXPECT_TRUE(received_stop_flinging);
1141 class LayerTreeHostScrollTestLayerStructureChange
1142 : public LayerTreeHostScrollTest {
1143 public:
1144 LayerTreeHostScrollTestLayerStructureChange()
1145 : scroll_destroy_whole_tree_(false) {}
1147 void SetupTree() override {
1148 scoped_refptr<Layer> root_layer = Layer::Create();
1149 root_layer->SetBounds(gfx::Size(10, 10));
1151 Layer* root_scroll_layer =
1152 CreateScrollLayer(root_layer.get(), &root_scroll_layer_client_);
1153 CreateScrollLayer(root_layer.get(), &sibling_scroll_layer_client_);
1154 CreateScrollLayer(root_scroll_layer, &child_scroll_layer_client_);
1156 layer_tree_host()->SetRootLayer(root_layer);
1157 LayerTreeHostScrollTest::SetupTree();
1160 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1162 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1163 LayerImpl* root = impl->active_tree()->root_layer();
1164 switch (impl->active_tree()->source_frame_number()) {
1165 case 0:
1166 root->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1167 root->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1168 root->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5));
1169 PostSetNeedsCommitToMainThread();
1170 break;
1171 case 1:
1172 EndTest();
1173 break;
1177 void AfterTest() override {}
1179 virtual void DidScroll(Layer* layer) {
1180 if (scroll_destroy_whole_tree_) {
1181 layer_tree_host()->SetRootLayer(NULL);
1182 EndTest();
1183 return;
1185 layer->RemoveFromParent();
1188 protected:
1189 class FakeLayerScrollClient {
1190 public:
1191 void DidScroll() {
1192 owner_->DidScroll(layer_);
1194 LayerTreeHostScrollTestLayerStructureChange* owner_;
1195 Layer* layer_;
1198 Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) {
1199 scoped_refptr<PictureLayer> scroll_layer =
1200 PictureLayer::Create(&fake_content_layer_client_);
1201 scroll_layer->SetBounds(gfx::Size(110, 110));
1202 scroll_layer->SetPosition(gfx::Point(0, 0));
1203 scroll_layer->SetIsDrawable(true);
1204 scroll_layer->SetScrollClipLayerId(parent->id());
1205 scroll_layer->SetBounds(gfx::Size(parent->bounds().width() + 100,
1206 parent->bounds().height() + 100));
1207 scroll_layer->set_did_scroll_callback(base::Bind(
1208 &FakeLayerScrollClient::DidScroll, base::Unretained(client)));
1209 client->owner_ = this;
1210 client->layer_ = scroll_layer.get();
1211 parent->AddChild(scroll_layer);
1212 return scroll_layer.get();
1215 FakeLayerScrollClient root_scroll_layer_client_;
1216 FakeLayerScrollClient sibling_scroll_layer_client_;
1217 FakeLayerScrollClient child_scroll_layer_client_;
1219 FakeContentLayerClient fake_content_layer_client_;
1221 bool scroll_destroy_whole_tree_;
1224 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyLayer) {
1225 RunTest(true, false, true);
1228 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) {
1229 scroll_destroy_whole_tree_ = true;
1230 RunTest(true, false, true);
1233 } // namespace
1234 } // namespace cc