cc: Make a FakeResourceProvider and use it in tests to construct.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_scroll.cc
blobdcd7153aa631b61cbd8391b8e498a4d305eb4616
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::Vector2d& scroll_delta,
96 float scale,
97 float top_controls_delta) override {
98 num_scrolls_++;
101 void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }
103 private:
104 gfx::ScrollOffset initial_scroll_;
105 gfx::ScrollOffset second_scroll_;
106 gfx::Vector2dF scroll_amount_;
107 int num_scrolls_;
110 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple);
112 class LayerTreeHostScrollTestScrollMultipleRedraw
113 : public LayerTreeHostScrollTest {
114 public:
115 LayerTreeHostScrollTestScrollMultipleRedraw()
116 : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
118 void BeginTest() override {
119 Layer* root_layer = layer_tree_host()->root_layer();
120 scroll_layer_ = Layer::Create(layer_settings());
121 root_layer->AddChild(scroll_layer_);
122 // Create an effective max_scroll_offset of (100, 100).
123 scroll_layer_->SetBounds(gfx::Size(root_layer->bounds().width() + 100,
124 root_layer->bounds().height() + 100));
125 scroll_layer_->SetIsDrawable(true);
126 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
127 scroll_layer_->SetScrollClipLayerId(root_layer->id());
128 scroll_layer_->SetScrollOffset(initial_scroll_);
129 layer_tree_host()->RegisterViewportLayers(NULL, root_layer, scroll_layer_,
130 NULL);
131 PostSetNeedsCommitToMainThread();
134 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
135 switch (layer_tree_host()->source_frame_number()) {
136 case 0:
137 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_);
138 break;
139 case 1:
140 EXPECT_VECTOR_EQ(
141 scroll_layer_->scroll_offset(),
142 gfx::ScrollOffsetWithDelta(initial_scroll_,
143 scroll_amount_ + scroll_amount_));
144 case 2:
145 EXPECT_VECTOR_EQ(
146 scroll_layer_->scroll_offset(),
147 gfx::ScrollOffsetWithDelta(initial_scroll_,
148 scroll_amount_ + scroll_amount_));
149 break;
153 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
154 LayerImpl* scroll_layer =
155 impl->active_tree()->LayerById(scroll_layer_->id());
156 if (impl->active_tree()->source_frame_number() == 0 &&
157 impl->SourceAnimationFrameNumber() == 1) {
158 // First draw after first commit.
159 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
160 scroll_layer->ScrollBy(scroll_amount_);
161 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
163 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), initial_scroll_);
164 PostSetNeedsRedrawToMainThread();
165 } else if (impl->active_tree()->source_frame_number() == 0 &&
166 impl->SourceAnimationFrameNumber() == 2) {
167 // Second draw after first commit.
168 EXPECT_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
169 scroll_layer->ScrollBy(scroll_amount_);
170 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
171 scroll_amount_ + scroll_amount_);
173 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_);
174 PostSetNeedsCommitToMainThread();
175 } else if (impl->active_tree()->source_frame_number() == 1) {
176 // Third or later draw after second commit.
177 EXPECT_GE(impl->SourceAnimationFrameNumber(), 3);
178 EXPECT_VECTOR_EQ(scroll_layer_->ScrollDelta(), gfx::Vector2d());
179 EXPECT_VECTOR_EQ(
180 scroll_layer_->scroll_offset(),
181 gfx::ScrollOffsetWithDelta(initial_scroll_,
182 scroll_amount_ + scroll_amount_));
183 EndTest();
187 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
188 float scale,
189 float top_controls_delta) override {
190 num_scrolls_++;
193 void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }
195 private:
196 gfx::ScrollOffset initial_scroll_;
197 gfx::Vector2dF scroll_amount_;
198 int num_scrolls_;
199 scoped_refptr<Layer> scroll_layer_;
202 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw);
204 class LayerTreeHostScrollTestScrollAbortedCommit
205 : public LayerTreeHostScrollTest {
206 public:
207 LayerTreeHostScrollTestScrollAbortedCommit()
208 : initial_scroll_(50, 60),
209 impl_scroll_(-3, 2),
210 second_main_scroll_(14, -3),
211 impl_scale_(2.f),
212 num_will_begin_main_frames_(0),
213 num_did_begin_main_frames_(0),
214 num_will_commits_(0),
215 num_did_commits_(0),
216 num_impl_commits_(0),
217 num_impl_scrolls_(0) {}
219 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
221 void SetupTree() override {
222 LayerTreeHostScrollTest::SetupTree();
223 Layer* root_layer = layer_tree_host()->root_layer();
224 scoped_refptr<Layer> root_scroll_layer = Layer::Create(layer_settings());
225 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
226 root_scroll_layer->SetScrollOffset(initial_scroll_);
227 root_scroll_layer->SetBounds(gfx::Size(200, 200));
228 root_scroll_layer->SetIsDrawable(true);
229 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
230 root_layer->AddChild(root_scroll_layer);
232 layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
233 root_scroll_layer, NULL);
234 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
237 void WillBeginMainFrame() override {
238 num_will_begin_main_frames_++;
239 Layer* root_scroll_layer =
240 layer_tree_host()->root_layer()->children()[0].get();
241 switch (num_will_begin_main_frames_) {
242 case 1:
243 // This will not be aborted because of the initial prop changes.
244 EXPECT_EQ(0, num_impl_scrolls_);
245 EXPECT_EQ(0, layer_tree_host()->source_frame_number());
246 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_);
247 EXPECT_EQ(1.f, layer_tree_host()->page_scale_factor());
248 break;
249 case 2:
250 // This commit will be aborted, and another commit will be
251 // initiated from the redraw.
252 EXPECT_EQ(1, num_impl_scrolls_);
253 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
254 EXPECT_VECTOR_EQ(
255 root_scroll_layer->scroll_offset(),
256 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_));
257 EXPECT_EQ(impl_scale_, layer_tree_host()->page_scale_factor());
258 PostSetNeedsRedrawToMainThread();
259 break;
260 case 3:
261 // This commit will not be aborted because of the scroll change.
262 EXPECT_EQ(2, num_impl_scrolls_);
263 // The source frame number still increases even with the abort.
264 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
265 EXPECT_VECTOR_EQ(
266 root_scroll_layer->scroll_offset(),
267 gfx::ScrollOffsetWithDelta(initial_scroll_,
268 impl_scroll_ + impl_scroll_));
269 EXPECT_EQ(impl_scale_ * impl_scale_,
270 layer_tree_host()->page_scale_factor());
271 root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta(
272 root_scroll_layer->scroll_offset(), second_main_scroll_));
273 break;
274 case 4:
275 // This commit will also be aborted.
276 EXPECT_EQ(3, num_impl_scrolls_);
277 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
278 gfx::Vector2dF delta =
279 impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
280 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
281 gfx::ScrollOffsetWithDelta(initial_scroll_, delta));
283 // End the test by drawing to verify this commit is also aborted.
284 PostSetNeedsRedrawToMainThread();
285 break;
289 void DidBeginMainFrame() override { num_did_begin_main_frames_++; }
291 void WillCommit() override { num_will_commits_++; }
293 void DidCommit() override { num_did_commits_++; }
295 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
296 num_impl_commits_++;
299 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
300 LayerImpl* root_scroll_layer =
301 impl->active_tree()->root_layer()->children()[0];
303 if (impl->active_tree()->source_frame_number() == 0 &&
304 impl->SourceAnimationFrameNumber() == 1) {
305 // First draw
306 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
307 root_scroll_layer->ScrollBy(impl_scroll_);
308 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
309 EXPECT_VECTOR_EQ(root_scroll_layer->BaseScrollOffset(), initial_scroll_);
311 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
312 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
313 impl->SetPageScaleOnActiveTree(impl_scale_);
314 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
315 EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor());
317 // To simplify the testing flow, don't redraw here, just commit.
318 impl->SetNeedsCommit();
319 } else if (impl->active_tree()->source_frame_number() == 0 &&
320 impl->SourceAnimationFrameNumber() == 2) {
321 // Test a second draw after an aborted commit.
322 // The scroll/scale values should be baked into the offset/scale factor
323 // since the main thread consumed but aborted the begin frame.
324 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
325 root_scroll_layer->ScrollBy(impl_scroll_);
326 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
327 EXPECT_VECTOR_EQ(
328 root_scroll_layer->BaseScrollOffset(),
329 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_));
331 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
332 EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor());
333 impl->SetPageScaleOnActiveTree(impl_scale_ * impl_scale_);
334 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
335 EXPECT_EQ(impl_scale_ * impl_scale_,
336 impl->active_tree()->current_page_scale_factor());
338 impl->SetNeedsCommit();
339 } else if (impl->active_tree()->source_frame_number() == 1) {
340 // Commit for source frame 1 is aborted.
341 NOTREACHED();
342 } else if (impl->active_tree()->source_frame_number() == 2 &&
343 impl->SourceAnimationFrameNumber() == 3) {
344 // Third draw after the second full commit.
345 EXPECT_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
346 root_scroll_layer->ScrollBy(impl_scroll_);
347 impl->SetNeedsCommit();
348 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
349 gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + second_main_scroll_;
350 EXPECT_VECTOR_EQ(root_scroll_layer->BaseScrollOffset(),
351 gfx::ScrollOffsetWithDelta(initial_scroll_, delta));
352 } else if (impl->active_tree()->source_frame_number() == 2 &&
353 impl->SourceAnimationFrameNumber() == 4) {
354 // Final draw after the second aborted commit.
355 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
356 gfx::Vector2dF delta =
357 impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
358 EXPECT_VECTOR_EQ(root_scroll_layer->BaseScrollOffset(),
359 gfx::ScrollOffsetWithDelta(initial_scroll_, delta));
360 EndTest();
361 } else {
362 // Commit for source frame 3 is aborted.
363 NOTREACHED();
367 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
368 float scale,
369 float top_controls_delta) override {
370 num_impl_scrolls_++;
373 void AfterTest() override {
374 EXPECT_EQ(3, num_impl_scrolls_);
375 // Verify that the embedder sees aborted commits as real commits.
376 EXPECT_EQ(4, num_will_begin_main_frames_);
377 EXPECT_EQ(4, num_did_begin_main_frames_);
378 EXPECT_EQ(4, num_will_commits_);
379 EXPECT_EQ(4, num_did_commits_);
380 // ...but the compositor thread only sees two real ones.
381 EXPECT_EQ(2, num_impl_commits_);
384 private:
385 gfx::ScrollOffset initial_scroll_;
386 gfx::Vector2dF impl_scroll_;
387 gfx::Vector2dF second_main_scroll_;
388 float impl_scale_;
389 int num_will_begin_main_frames_;
390 int num_did_begin_main_frames_;
391 int num_will_commits_;
392 int num_did_commits_;
393 int num_impl_commits_;
394 int num_impl_scrolls_;
397 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit);
399 class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest {
400 public:
401 LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
403 void SetupTree() override {
404 LayerTreeHostScrollTest::SetupTree();
405 Layer* root_layer = layer_tree_host()->root_layer();
406 scoped_refptr<Layer> root_scroll_layer = Layer::Create(layer_settings());
407 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
408 root_scroll_layer->SetBounds(
409 gfx::Size(root_layer->bounds().width() + 100,
410 root_layer->bounds().height() + 100));
411 root_scroll_layer->SetIsDrawable(true);
412 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
413 root_layer->AddChild(root_scroll_layer);
415 layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
416 root_scroll_layer, NULL);
417 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
420 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
422 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
423 LayerImpl* root = impl->active_tree()->root_layer();
424 LayerImpl* scroll_layer = root->children()[0];
426 // Check that a fractional scroll delta is correctly accumulated over
427 // multiple commits.
428 switch (impl->active_tree()->source_frame_number()) {
429 case 0:
430 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), gfx::Vector2d(0, 0));
431 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d(0, 0));
432 PostSetNeedsCommitToMainThread();
433 break;
434 case 1:
435 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(),
436 gfx::ToFlooredVector2d(scroll_amount_));
437 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
438 gfx::Vector2dF(fmod(scroll_amount_.x(), 1.0f), 0.0f));
439 PostSetNeedsCommitToMainThread();
440 break;
441 case 2:
442 EXPECT_VECTOR_EQ(
443 scroll_layer->BaseScrollOffset(),
444 gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_));
445 EXPECT_VECTOR_EQ(
446 scroll_layer->ScrollDelta(),
447 gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f));
448 EndTest();
449 break;
451 scroll_layer->ScrollBy(scroll_amount_);
454 void AfterTest() override {}
456 private:
457 gfx::Vector2dF scroll_amount_;
460 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll);
462 class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
463 public:
464 LayerTreeHostScrollTestCaseWithChild()
465 : initial_offset_(10, 20),
466 javascript_scroll_(40, 5),
467 scroll_amount_(2, -1),
468 num_scrolls_(0) {}
470 void SetupTree() override {
471 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
473 scoped_refptr<Layer> root_layer = Layer::Create(layer_settings());
474 root_layer->SetBounds(gfx::Size(10, 10));
476 root_scroll_layer_ =
477 FakePictureLayer::Create(layer_settings(), &fake_content_layer_client_);
478 root_scroll_layer_->SetBounds(gfx::Size(110, 110));
480 root_scroll_layer_->SetPosition(gfx::Point());
482 root_scroll_layer_->SetIsDrawable(true);
483 root_scroll_layer_->SetScrollClipLayerId(root_layer->id());
484 root_scroll_layer_->SetIsContainerForFixedPositionLayers(true);
485 root_layer->AddChild(root_scroll_layer_);
487 child_layer_ =
488 FakePictureLayer::Create(layer_settings(), &fake_content_layer_client_);
489 child_layer_->set_did_scroll_callback(
490 base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
491 base::Unretained(this)));
492 child_layer_->SetBounds(gfx::Size(110, 110));
494 if (scroll_child_layer_) {
495 // Scrolls on the child layer will happen at 5, 5. If they are treated
496 // like device pixels, and device scale factor is 2, then they will
497 // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
498 child_layer_->SetPosition(gfx::Point(5, 5));
499 } else {
500 // Adjust the child layer horizontally so that scrolls will never hit it.
501 child_layer_->SetPosition(gfx::Point(60, 5));
504 child_layer_->SetIsDrawable(true);
505 child_layer_->SetScrollClipLayerId(root_layer->id());
506 child_layer_->SetBounds(root_scroll_layer_->bounds());
507 root_scroll_layer_->AddChild(child_layer_);
509 if (scroll_child_layer_) {
510 expected_scroll_layer_ = child_layer_;
511 expected_no_scroll_layer_ = root_scroll_layer_;
512 } else {
513 expected_scroll_layer_ = root_scroll_layer_;
514 expected_no_scroll_layer_ = child_layer_;
517 expected_scroll_layer_->SetScrollOffset(initial_offset_);
519 layer_tree_host()->SetRootLayer(root_layer);
520 layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
521 root_scroll_layer_, NULL);
522 LayerTreeHostScrollTest::SetupTree();
525 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
527 void WillCommit() override {
528 // Keep the test committing (otherwise the early out for no update
529 // will stall the test).
530 if (layer_tree_host()->source_frame_number() < 2) {
531 layer_tree_host()->SetNeedsCommit();
535 void DidScroll() {
536 final_scroll_offset_ = expected_scroll_layer_->scroll_offset();
539 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
540 float scale,
541 float top_controls_delta) override {
542 num_scrolls_++;
545 void Layout() override {
546 EXPECT_VECTOR_EQ(gfx::Vector2d(),
547 expected_no_scroll_layer_->scroll_offset());
549 switch (layer_tree_host()->source_frame_number()) {
550 case 0:
551 EXPECT_VECTOR_EQ(initial_offset_,
552 expected_scroll_layer_->scroll_offset());
553 break;
554 case 1:
555 EXPECT_VECTOR_EQ(
556 gfx::ScrollOffsetWithDelta(initial_offset_, scroll_amount_),
557 expected_scroll_layer_->scroll_offset());
559 // Pretend like Javascript updated the scroll position itself.
560 expected_scroll_layer_->SetScrollOffset(javascript_scroll_);
561 break;
562 case 2:
563 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_,
564 scroll_amount_),
565 expected_scroll_layer_->scroll_offset());
566 break;
570 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
571 LayerImpl* root_impl = impl->active_tree()->root_layer();
572 FakePictureLayerImpl* root_scroll_layer_impl =
573 static_cast<FakePictureLayerImpl*>(root_impl->children()[0]);
574 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>(
575 root_scroll_layer_impl->children()[0]);
577 LayerImpl* expected_scroll_layer_impl = NULL;
578 LayerImpl* expected_no_scroll_layer_impl = NULL;
579 if (scroll_child_layer_) {
580 expected_scroll_layer_impl = child_layer_impl;
581 expected_no_scroll_layer_impl = root_scroll_layer_impl;
582 } else {
583 expected_scroll_layer_impl = root_scroll_layer_impl;
584 expected_no_scroll_layer_impl = child_layer_impl;
587 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl->ScrollDelta());
588 EXPECT_VECTOR_EQ(gfx::Vector2d(),
589 expected_no_scroll_layer_impl->ScrollDelta());
591 // Ensure device scale factor matches the active tree.
592 EXPECT_EQ(device_scale_factor_, impl->active_tree()->device_scale_factor());
593 switch (impl->active_tree()->source_frame_number()) {
594 case 0: {
595 // GESTURE scroll on impl thread.
596 InputHandler::ScrollStatus status = impl->ScrollBegin(
597 gfx::ToCeiledPoint(expected_scroll_layer_impl->position() -
598 gfx::Vector2dF(0.5f, 0.5f)),
599 InputHandler::GESTURE);
600 EXPECT_EQ(InputHandler::SCROLL_STARTED, status);
601 impl->ScrollBy(gfx::Point(), scroll_amount_);
602 impl->ScrollEnd();
604 // Check the scroll is applied as a delta.
605 EXPECT_VECTOR_EQ(initial_offset_,
606 expected_scroll_layer_impl->BaseScrollOffset());
607 EXPECT_VECTOR_EQ(scroll_amount_,
608 expected_scroll_layer_impl->ScrollDelta());
609 break;
611 case 1: {
612 // WHEEL scroll on impl thread.
613 InputHandler::ScrollStatus status = impl->ScrollBegin(
614 gfx::ToCeiledPoint(expected_scroll_layer_impl->position() +
615 gfx::Vector2dF(0.5f, 0.5f)),
616 InputHandler::WHEEL);
617 EXPECT_EQ(InputHandler::SCROLL_STARTED, status);
618 impl->ScrollBy(gfx::Point(), scroll_amount_);
619 impl->ScrollEnd();
621 // Check the scroll is applied as a delta.
622 EXPECT_VECTOR_EQ(javascript_scroll_,
623 expected_scroll_layer_impl->BaseScrollOffset());
624 EXPECT_VECTOR_EQ(scroll_amount_,
625 expected_scroll_layer_impl->ScrollDelta());
626 break;
628 case 2:
630 EXPECT_VECTOR_EQ(
631 gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_),
632 expected_scroll_layer_impl->BaseScrollOffset());
633 EXPECT_VECTOR_EQ(gfx::Vector2d(),
634 expected_scroll_layer_impl->ScrollDelta());
636 EndTest();
637 break;
641 void AfterTest() override {
642 if (scroll_child_layer_) {
643 EXPECT_EQ(0, num_scrolls_);
644 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_,
645 scroll_amount_),
646 final_scroll_offset_);
647 } else {
648 EXPECT_EQ(2, num_scrolls_);
649 EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_);
653 protected:
654 float device_scale_factor_;
655 bool scroll_child_layer_;
657 gfx::ScrollOffset initial_offset_;
658 gfx::ScrollOffset javascript_scroll_;
659 gfx::Vector2d scroll_amount_;
660 int num_scrolls_;
661 gfx::ScrollOffset final_scroll_offset_;
663 FakeContentLayerClient fake_content_layer_client_;
665 scoped_refptr<Layer> root_scroll_layer_;
666 scoped_refptr<Layer> child_layer_;
667 scoped_refptr<Layer> expected_scroll_layer_;
668 scoped_refptr<Layer> expected_no_scroll_layer_;
671 TEST_F(LayerTreeHostScrollTestCaseWithChild,
672 DeviceScaleFactor1_ScrollChild_DirectRenderer) {
673 device_scale_factor_ = 1.f;
674 scroll_child_layer_ = true;
675 RunTest(true, false, true);
678 TEST_F(LayerTreeHostScrollTestCaseWithChild,
679 DeviceScaleFactor1_ScrollChild_DelegatingRenderer) {
680 device_scale_factor_ = 1.f;
681 scroll_child_layer_ = true;
682 RunTest(true, true, true);
685 TEST_F(LayerTreeHostScrollTestCaseWithChild,
686 DeviceScaleFactor15_ScrollChild_DirectRenderer) {
687 device_scale_factor_ = 1.5f;
688 scroll_child_layer_ = true;
689 RunTest(true, false, true);
692 TEST_F(LayerTreeHostScrollTestCaseWithChild,
693 DeviceScaleFactor15_ScrollChild_DelegatingRenderer) {
694 device_scale_factor_ = 1.5f;
695 scroll_child_layer_ = true;
696 RunTest(true, true, true);
699 TEST_F(LayerTreeHostScrollTestCaseWithChild,
700 DeviceScaleFactor2_ScrollChild_DirectRenderer) {
701 device_scale_factor_ = 2.f;
702 scroll_child_layer_ = true;
703 RunTest(true, false, true);
706 TEST_F(LayerTreeHostScrollTestCaseWithChild,
707 DeviceScaleFactor2_ScrollChild_DelegatingRenderer) {
708 device_scale_factor_ = 2.f;
709 scroll_child_layer_ = true;
710 RunTest(true, true, true);
713 TEST_F(LayerTreeHostScrollTestCaseWithChild,
714 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer) {
715 device_scale_factor_ = 1.f;
716 scroll_child_layer_ = false;
717 RunTest(true, false, true);
720 TEST_F(LayerTreeHostScrollTestCaseWithChild,
721 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer) {
722 device_scale_factor_ = 1.f;
723 scroll_child_layer_ = false;
724 RunTest(true, true, true);
727 TEST_F(LayerTreeHostScrollTestCaseWithChild,
728 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer) {
729 device_scale_factor_ = 1.5f;
730 scroll_child_layer_ = false;
731 RunTest(true, false, true);
734 TEST_F(LayerTreeHostScrollTestCaseWithChild,
735 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer) {
736 device_scale_factor_ = 1.5f;
737 scroll_child_layer_ = false;
738 RunTest(true, true, true);
741 TEST_F(LayerTreeHostScrollTestCaseWithChild,
742 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer) {
743 device_scale_factor_ = 2.f;
744 scroll_child_layer_ = false;
745 RunTest(true, false, true);
748 TEST_F(LayerTreeHostScrollTestCaseWithChild,
749 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer) {
750 device_scale_factor_ = 2.f;
751 scroll_child_layer_ = false;
752 RunTest(true, true, true);
755 class ImplSidePaintingScrollTest : public LayerTreeHostScrollTest {
756 public:
757 void InitializeSettings(LayerTreeSettings* settings) override {
758 settings->impl_side_painting = true;
761 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
762 if (impl->pending_tree())
763 impl->SetNeedsRedraw();
767 class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest {
768 public:
769 ImplSidePaintingScrollTestSimple()
770 : initial_scroll_(10, 20),
771 main_thread_scroll_(40, 5),
772 impl_thread_scroll1_(2, -1),
773 impl_thread_scroll2_(-3, 10),
774 num_scrolls_(0) {}
776 void SetupTree() override {
777 LayerTreeHostScrollTest::SetupTree();
778 Layer* root_layer = layer_tree_host()->root_layer();
779 scoped_refptr<Layer> root_scroll_layer = Layer::Create(layer_settings());
780 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
781 root_scroll_layer->SetScrollOffset(initial_scroll_);
782 root_scroll_layer->SetBounds(
783 gfx::Size(root_layer->bounds().width() + 100,
784 root_layer->bounds().height() + 100));
785 root_scroll_layer->SetIsDrawable(true);
786 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
787 root_layer->AddChild(root_scroll_layer);
789 layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
790 root_scroll_layer, NULL);
791 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
794 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
796 void Layout() override {
797 Layer* root = layer_tree_host()->root_layer();
798 Layer* scroll_layer = root->children()[0].get();
799 if (!layer_tree_host()->source_frame_number()) {
800 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
801 } else {
802 EXPECT_VECTOR_EQ(
803 scroll_layer->scroll_offset(),
804 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll1_));
806 // Pretend like Javascript updated the scroll position itself with a
807 // change of main_thread_scroll.
808 scroll_layer->SetScrollOffset(
809 gfx::ScrollOffsetWithDelta(
810 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
814 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
815 // We force a second draw here of the first commit before activating
816 // the second commit.
817 if (impl->active_tree()->source_frame_number() == 0)
818 impl->SetNeedsRedraw();
821 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
822 ImplSidePaintingScrollTest::DrawLayersOnThread(impl);
824 LayerImpl* root = impl->active_tree()->root_layer();
825 LayerImpl* scroll_layer = root->children()[0];
826 LayerImpl* pending_root =
827 impl->active_tree()->FindPendingTreeLayerById(root->id());
829 switch (impl->active_tree()->source_frame_number()) {
830 case 0:
831 if (!impl->pending_tree()) {
832 impl->BlockNotifyReadyToActivateForTesting(true);
833 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
834 scroll_layer->ScrollBy(impl_thread_scroll1_);
836 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), initial_scroll_);
837 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll1_);
838 PostSetNeedsCommitToMainThread();
840 // CommitCompleteOnThread will trigger this function again
841 // and cause us to take the else clause.
842 } else {
843 impl->BlockNotifyReadyToActivateForTesting(false);
844 ASSERT_TRUE(pending_root);
845 EXPECT_EQ(impl->pending_tree()->source_frame_number(), 1);
847 scroll_layer->ScrollBy(impl_thread_scroll2_);
848 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), initial_scroll_);
849 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
850 impl_thread_scroll1_ + impl_thread_scroll2_);
852 LayerImpl* pending_scroll_layer = pending_root->children()[0];
853 EXPECT_VECTOR_EQ(
854 pending_scroll_layer->BaseScrollOffset(),
855 gfx::ScrollOffsetWithDelta(
856 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
857 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(),
858 impl_thread_scroll2_);
860 break;
861 case 1:
862 EXPECT_FALSE(impl->pending_tree());
863 EXPECT_VECTOR_EQ(
864 scroll_layer->BaseScrollOffset(),
865 gfx::ScrollOffsetWithDelta(
866 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
867 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll2_);
868 EndTest();
869 break;
873 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
874 float scale,
875 float top_controls_delta) override {
876 num_scrolls_++;
879 void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }
881 private:
882 gfx::ScrollOffset initial_scroll_;
883 gfx::Vector2dF main_thread_scroll_;
884 gfx::Vector2dF impl_thread_scroll1_;
885 gfx::Vector2dF impl_thread_scroll2_;
886 int num_scrolls_;
889 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple);
891 // This test makes sure that layers pick up scrolls that occur between
892 // beginning a commit and finishing a commit (aka scroll deltas not
893 // included in sent scroll delta) still apply to layers that don't
894 // push properties.
895 class ImplSidePaintingScrollTestImplOnlyScroll
896 : public ImplSidePaintingScrollTest {
897 public:
898 ImplSidePaintingScrollTestImplOnlyScroll()
899 : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3), impl_scale_(2.f) {}
901 void SetupTree() override {
902 LayerTreeHostScrollTest::SetupTree();
903 Layer* root_layer = layer_tree_host()->root_layer();
904 scoped_refptr<Layer> root_scroll_layer = Layer::Create(layer_settings());
905 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
906 root_scroll_layer->SetScrollOffset(initial_scroll_);
907 root_scroll_layer->SetBounds(
908 gfx::Size(root_layer->bounds().width() + 100,
909 root_layer->bounds().height() + 100));
910 root_scroll_layer->SetIsDrawable(true);
911 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
912 root_layer->AddChild(root_scroll_layer);
914 layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
915 root_scroll_layer, NULL);
916 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
919 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
921 void WillCommit() override {
922 Layer* root = layer_tree_host()->root_layer();
923 Layer* scroll_layer = root->children()[0].get();
924 switch (layer_tree_host()->source_frame_number()) {
925 case 0:
926 EXPECT_TRUE(scroll_layer->needs_push_properties());
927 break;
928 case 1:
929 // Even if this layer doesn't need push properties, it should
930 // still pick up scrolls that happen on the active layer during
931 // commit.
932 EXPECT_FALSE(scroll_layer->needs_push_properties());
933 break;
937 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
938 // Scroll after the 2nd commit has started.
939 if (impl->active_tree()->source_frame_number() == 0) {
940 LayerImpl* active_root = impl->active_tree()->root_layer();
941 LayerImpl* active_scroll_layer = active_root->children()[0];
942 ASSERT_TRUE(active_root);
943 ASSERT_TRUE(active_scroll_layer);
944 active_scroll_layer->ScrollBy(impl_thread_scroll_);
945 impl->SetPageScaleOnActiveTree(impl_scale_);
949 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
950 // We force a second draw here of the first commit before activating
951 // the second commit.
952 LayerImpl* active_root = impl->active_tree()->root_layer();
953 LayerImpl* active_scroll_layer =
954 active_root ? active_root->children()[0] : NULL;
955 LayerImpl* pending_root = impl->pending_tree()->root_layer();
956 LayerImpl* pending_scroll_layer = pending_root->children()[0];
958 ASSERT_TRUE(pending_root);
959 ASSERT_TRUE(pending_scroll_layer);
960 switch (impl->pending_tree()->source_frame_number()) {
961 case 0:
962 EXPECT_VECTOR_EQ(pending_scroll_layer->BaseScrollOffset(),
963 initial_scroll_);
964 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d());
965 EXPECT_FALSE(active_root);
966 break;
967 case 1:
968 // Even though the scroll happened during the commit, both layers
969 // should have the appropriate scroll delta.
970 EXPECT_VECTOR_EQ(pending_scroll_layer->BaseScrollOffset(),
971 initial_scroll_);
972 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(),
973 impl_thread_scroll_);
974 ASSERT_TRUE(active_root);
975 EXPECT_VECTOR_EQ(active_scroll_layer->BaseScrollOffset(),
976 initial_scroll_);
977 EXPECT_VECTOR_EQ(active_scroll_layer->ScrollDelta(),
978 impl_thread_scroll_);
979 break;
980 case 2:
981 // On the next commit, this delta should have been sent and applied.
982 EXPECT_VECTOR_EQ(
983 pending_scroll_layer->BaseScrollOffset(),
984 gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll_));
985 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d());
986 break;
990 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
991 ImplSidePaintingScrollTest::DrawLayersOnThread(impl);
993 LayerImpl* root = impl->active_tree()->root_layer();
994 LayerImpl* scroll_layer = root->children()[0];
996 switch (impl->active_tree()->source_frame_number()) {
997 case 0:
998 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), initial_scroll_);
999 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
1000 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
1001 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1002 PostSetNeedsCommitToMainThread();
1003 break;
1004 case 1:
1005 EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), initial_scroll_);
1006 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll_);
1007 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
1008 EXPECT_EQ(impl_scale_,
1009 impl->active_tree()->current_page_scale_factor());
1010 PostSetNeedsCommitToMainThread();
1011 break;
1012 case 2:
1013 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
1014 EXPECT_EQ(impl_scale_,
1015 impl->active_tree()->current_page_scale_factor());
1016 EndTest();
1017 break;
1021 void AfterTest() override {}
1023 private:
1024 gfx::ScrollOffset initial_scroll_;
1025 gfx::Vector2dF impl_thread_scroll_;
1026 float impl_scale_;
1029 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll);
1031 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
1032 : public LayerTreeHostScrollTest {
1033 public:
1034 LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
1036 void SetupTree() override {
1037 LayerTreeTest::SetupTree();
1038 scoped_refptr<Layer> scroll_layer = Layer::Create(layer_settings());
1039 layer_tree_host()->root_layer()->AddChild(scroll_layer);
1042 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1044 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1045 LayerImpl* root = impl->active_tree()->root_layer();
1046 LayerImpl* scroll_layer = root->children()[0];
1047 scroll_layer->SetScrollClipLayer(root->id());
1049 // Set max_scroll_offset = (100, 100).
1050 scroll_layer->SetBounds(
1051 gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
1052 EXPECT_EQ(
1053 InputHandler::SCROLL_STARTED,
1054 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE,
1055 SCROLL_BLOCKS_ON_NONE));
1057 // Set max_scroll_offset = (0, 0).
1058 scroll_layer->SetBounds(root->bounds());
1059 EXPECT_EQ(
1060 InputHandler::SCROLL_IGNORED,
1061 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE,
1062 SCROLL_BLOCKS_ON_NONE));
1064 // Set max_scroll_offset = (-100, -100).
1065 scroll_layer->SetBounds(gfx::Size());
1066 EXPECT_EQ(
1067 InputHandler::SCROLL_IGNORED,
1068 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::GESTURE,
1069 SCROLL_BLOCKS_ON_NONE));
1071 EndTest();
1074 void AfterTest() override {}
1077 SINGLE_AND_MULTI_THREAD_TEST_F(
1078 LayerTreeHostScrollTestScrollZeroMaxScrollOffset);
1080 class ThreadCheckingInputHandlerClient : public InputHandlerClient {
1081 public:
1082 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner* runner,
1083 bool* received_stop_flinging)
1084 : task_runner_(runner), received_stop_flinging_(received_stop_flinging) {}
1086 void WillShutdown() override {
1087 if (!received_stop_flinging_)
1088 ADD_FAILURE() << "WillShutdown() called before fling stopped";
1091 void Animate(base::TimeTicks time) override {
1092 if (!task_runner_->BelongsToCurrentThread())
1093 ADD_FAILURE() << "Animate called on wrong thread";
1096 void MainThreadHasStoppedFlinging() override {
1097 if (!task_runner_->BelongsToCurrentThread())
1098 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
1099 *received_stop_flinging_ = true;
1102 void ReconcileElasticOverscrollAndRootScroll() override {
1103 if (!task_runner_->BelongsToCurrentThread()) {
1104 ADD_FAILURE() << "ReconcileElasticOverscrollAndRootScroll called on "
1105 << "wrong thread";
1109 private:
1110 base::SingleThreadTaskRunner* task_runner_;
1111 bool* received_stop_flinging_;
1114 void BindInputHandlerOnCompositorThread(
1115 const base::WeakPtr<InputHandler>& input_handler,
1116 ThreadCheckingInputHandlerClient* client) {
1117 input_handler->BindToClient(client);
1120 TEST(LayerTreeHostFlingTest, DidStopFlingingThread) {
1121 base::Thread impl_thread("cc");
1122 ASSERT_TRUE(impl_thread.Start());
1124 bool received_stop_flinging = false;
1125 LayerTreeSettings settings;
1127 ThreadCheckingInputHandlerClient input_handler_client(
1128 impl_thread.task_runner().get(), &received_stop_flinging);
1129 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1131 ASSERT_TRUE(impl_thread.task_runner().get());
1132 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1133 new TestSharedBitmapManager());
1135 LayerTreeHost::InitParams params;
1136 params.client = &client;
1137 params.shared_bitmap_manager = shared_bitmap_manager.get();
1138 params.settings = &settings;
1139 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
1140 scoped_ptr<LayerTreeHost> layer_tree_host =
1141 LayerTreeHost::CreateThreaded(impl_thread.task_runner(), &params);
1143 impl_thread.task_runner()->PostTask(
1144 FROM_HERE, base::Bind(&BindInputHandlerOnCompositorThread,
1145 layer_tree_host->GetInputHandler(),
1146 base::Unretained(&input_handler_client)));
1148 layer_tree_host->DidStopFlinging();
1149 layer_tree_host = nullptr;
1150 impl_thread.Stop();
1151 EXPECT_TRUE(received_stop_flinging);
1154 class LayerTreeHostScrollTestLayerStructureChange
1155 : public LayerTreeHostScrollTest {
1156 public:
1157 LayerTreeHostScrollTestLayerStructureChange()
1158 : scroll_destroy_whole_tree_(false) {}
1160 void SetupTree() override {
1161 scoped_refptr<Layer> root_layer = Layer::Create(layer_settings());
1162 root_layer->SetBounds(gfx::Size(10, 10));
1164 Layer* root_scroll_layer =
1165 CreateScrollLayer(root_layer.get(), &root_scroll_layer_client_);
1166 CreateScrollLayer(root_layer.get(), &sibling_scroll_layer_client_);
1167 CreateScrollLayer(root_scroll_layer, &child_scroll_layer_client_);
1169 layer_tree_host()->SetRootLayer(root_layer);
1170 LayerTreeHostScrollTest::SetupTree();
1173 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1175 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 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(layer_settings(), &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