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