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