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"
26 class LayerTreeHostScrollTest : public LayerTreeTest {};
28 class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest {
30 LayerTreeHostScrollTestScrollSimple()
31 : initial_scroll_(10, 20),
32 second_scroll_(40, 5),
33 scroll_amount_(2, -1),
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];
54 if (!layer_tree_host()->source_frame_number()) {
55 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
57 EXPECT_VECTOR_EQ(initial_scroll_ + scroll_amount_,
58 scroll_layer->scroll_offset());
60 // Pretend like Javascript updated the scroll position itself.
61 scroll_layer->SetScrollOffset(second_scroll_);
65 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
66 LayerImpl* root = impl->active_tree()->root_layer();
67 LayerImpl* scroll_layer = root->children()[0];
68 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer->ScrollDelta());
70 scroll_layer->SetScrollClipLayer(root->id());
71 scroll_layer->SetBounds(
72 gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
73 scroll_layer->ScrollBy(scroll_amount_);
75 switch (impl->active_tree()->source_frame_number()) {
77 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
78 EXPECT_VECTOR_EQ(scroll_amount_, scroll_layer->ScrollDelta());
79 PostSetNeedsCommitToMainThread();
82 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), second_scroll_);
83 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
89 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
90 float scale) OVERRIDE {
94 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); }
97 gfx::Vector2d initial_scroll_;
98 gfx::Vector2d second_scroll_;
99 gfx::Vector2d scroll_amount_;
103 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple);
105 class LayerTreeHostScrollTestScrollMultipleRedraw
106 : public LayerTreeHostScrollTest {
108 LayerTreeHostScrollTestScrollMultipleRedraw()
109 : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
111 virtual void BeginTest() OVERRIDE {
112 Layer* root_layer = layer_tree_host()->root_layer();
113 scroll_layer_ = Layer::Create();
114 root_layer->AddChild(scroll_layer_);
115 // Create an effective max_scroll_offset of (100, 100).
116 scroll_layer_->SetBounds(gfx::Size(root_layer->bounds().width() + 100,
117 root_layer->bounds().height() + 100));
118 scroll_layer_->SetIsDrawable(true);
119 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
120 scroll_layer_->SetScrollClipLayerId(root_layer->id());
121 scroll_layer_->SetScrollOffset(initial_scroll_);
122 layer_tree_host()->RegisterViewportLayers(root_layer, scroll_layer_, NULL);
123 PostSetNeedsCommitToMainThread();
126 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
127 switch (layer_tree_host()->source_frame_number()) {
129 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_);
132 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(),
133 initial_scroll_ + scroll_amount_ + scroll_amount_);
135 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(),
136 initial_scroll_ + scroll_amount_ + scroll_amount_);
141 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
142 LayerImpl* scroll_layer =
143 impl->active_tree()->LayerById(scroll_layer_->id());
144 if (impl->active_tree()->source_frame_number() == 0 &&
145 impl->SourceAnimationFrameNumber() == 1) {
146 // First draw after first commit.
147 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
148 scroll_layer->ScrollBy(scroll_amount_);
149 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
151 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
152 PostSetNeedsRedrawToMainThread();
153 } else if (impl->active_tree()->source_frame_number() == 0 &&
154 impl->SourceAnimationFrameNumber() == 2) {
155 // Second draw after first commit.
156 EXPECT_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
157 scroll_layer->ScrollBy(scroll_amount_);
158 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
159 scroll_amount_ + scroll_amount_);
161 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_);
162 PostSetNeedsCommitToMainThread();
163 } else if (impl->active_tree()->source_frame_number() == 1) {
164 // Third or later draw after second commit.
165 EXPECT_GE(impl->SourceAnimationFrameNumber(), 3);
166 EXPECT_VECTOR_EQ(scroll_layer_->ScrollDelta(), gfx::Vector2d());
167 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(),
168 initial_scroll_ + scroll_amount_ + scroll_amount_);
173 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
174 float scale) OVERRIDE {
178 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); }
181 gfx::Vector2d initial_scroll_;
182 gfx::Vector2d scroll_amount_;
184 scoped_refptr<Layer> scroll_layer_;
187 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw);
189 class LayerTreeHostScrollTestScrollAbortedCommit
190 : public LayerTreeHostScrollTest {
192 LayerTreeHostScrollTestScrollAbortedCommit()
193 : initial_scroll_(50, 60),
195 second_main_scroll_(14, -3),
197 num_will_begin_main_frames_(0),
198 num_did_begin_main_frames_(0),
199 num_will_commits_(0),
201 num_impl_commits_(0),
202 num_impl_scrolls_(0) {}
204 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
206 virtual void SetupTree() OVERRIDE {
207 LayerTreeHostScrollTest::SetupTree();
208 Layer* root_layer = layer_tree_host()->root_layer();
209 scoped_refptr<Layer> root_scroll_layer = Layer::Create();
210 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
211 root_scroll_layer->SetScrollOffset(initial_scroll_);
212 root_scroll_layer->SetBounds(gfx::Size(200, 200));
213 root_scroll_layer->SetIsDrawable(true);
214 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
215 root_layer->AddChild(root_scroll_layer);
217 layer_tree_host()->RegisterViewportLayers(
218 root_layer, root_scroll_layer, NULL);
219 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
222 virtual void WillBeginMainFrame() OVERRIDE {
223 num_will_begin_main_frames_++;
224 Layer* root_scroll_layer = layer_tree_host()->root_layer()->children()[0];
225 switch (num_will_begin_main_frames_) {
227 // This will not be aborted because of the initial prop changes.
228 EXPECT_EQ(0, num_impl_scrolls_);
229 EXPECT_EQ(0, layer_tree_host()->source_frame_number());
230 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_);
231 EXPECT_EQ(1.f, layer_tree_host()->page_scale_factor());
234 // This commit will be aborted, and another commit will be
235 // initiated from the redraw.
236 EXPECT_EQ(1, num_impl_scrolls_);
237 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
238 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
239 initial_scroll_ + impl_scroll_);
240 EXPECT_EQ(impl_scale_, layer_tree_host()->page_scale_factor());
241 PostSetNeedsRedrawToMainThread();
244 // This commit will not be aborted because of the scroll change.
245 EXPECT_EQ(2, num_impl_scrolls_);
246 // The source frame number still increases even with the abort.
247 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
248 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
249 initial_scroll_ + impl_scroll_ + impl_scroll_);
250 EXPECT_EQ(impl_scale_ * impl_scale_,
251 layer_tree_host()->page_scale_factor());
252 root_scroll_layer->SetScrollOffset(root_scroll_layer->scroll_offset() +
253 second_main_scroll_);
256 // This commit will also be aborted.
257 EXPECT_EQ(3, num_impl_scrolls_);
258 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
259 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
260 initial_scroll_ + impl_scroll_ + impl_scroll_ +
261 impl_scroll_ + second_main_scroll_);
262 // End the test by drawing to verify this commit is also aborted.
263 PostSetNeedsRedrawToMainThread();
268 virtual void DidBeginMainFrame() OVERRIDE { num_did_begin_main_frames_++; }
270 virtual void WillCommit() OVERRIDE { num_will_commits_++; }
272 virtual void DidCommit() OVERRIDE { num_did_commits_++; }
274 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
278 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
279 LayerImpl* root_scroll_layer =
280 impl->active_tree()->root_layer()->children()[0];
282 if (impl->active_tree()->source_frame_number() == 0 &&
283 impl->SourceAnimationFrameNumber() == 1) {
285 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
286 root_scroll_layer->ScrollBy(impl_scroll_);
287 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
288 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_);
290 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
291 EXPECT_EQ(1.f, impl->active_tree()->total_page_scale_factor());
292 impl->active_tree()->SetPageScaleDelta(impl_scale_);
293 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
294 EXPECT_EQ(impl_scale_, impl->active_tree()->total_page_scale_factor());
296 // To simplify the testing flow, don't redraw here, just commit.
297 impl->SetNeedsCommit();
298 } else if (impl->active_tree()->source_frame_number() == 0 &&
299 impl->SourceAnimationFrameNumber() == 2) {
300 // Test a second draw after an aborted commit.
301 // The scroll/scale values should be baked into the offset/scale factor
302 // since the main thread consumed but aborted the begin frame.
303 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
304 root_scroll_layer->ScrollBy(impl_scroll_);
305 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
306 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
307 initial_scroll_ + impl_scroll_);
309 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
310 EXPECT_EQ(impl_scale_, impl->active_tree()->total_page_scale_factor());
311 impl->active_tree()->SetPageScaleDelta(impl_scale_);
312 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
313 EXPECT_EQ(impl_scale_ * impl_scale_,
314 impl->active_tree()->total_page_scale_factor());
316 impl->SetNeedsCommit();
317 } else if (impl->active_tree()->source_frame_number() == 1) {
318 // Commit for source frame 1 is aborted.
320 } else if (impl->active_tree()->source_frame_number() == 2 &&
321 impl->SourceAnimationFrameNumber() == 3) {
322 // Third draw after the second full commit.
323 EXPECT_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
324 root_scroll_layer->ScrollBy(impl_scroll_);
325 impl->SetNeedsCommit();
326 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
328 root_scroll_layer->scroll_offset(),
329 initial_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_);
330 } else if (impl->active_tree()->source_frame_number() == 2 &&
331 impl->SourceAnimationFrameNumber() == 4) {
332 // Final draw after the second aborted commit.
333 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
334 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
335 initial_scroll_ + impl_scroll_ + impl_scroll_ +
336 impl_scroll_ + second_main_scroll_);
339 // Commit for source frame 3 is aborted.
344 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
345 float scale) OVERRIDE {
349 virtual void AfterTest() OVERRIDE {
350 EXPECT_EQ(3, num_impl_scrolls_);
351 // Verify that the embedder sees aborted commits as real commits.
352 EXPECT_EQ(4, num_will_begin_main_frames_);
353 EXPECT_EQ(4, num_did_begin_main_frames_);
354 EXPECT_EQ(4, num_will_commits_);
355 EXPECT_EQ(4, num_did_commits_);
356 // ...but the compositor thread only sees two real ones.
357 EXPECT_EQ(2, num_impl_commits_);
361 gfx::Vector2d initial_scroll_;
362 gfx::Vector2d impl_scroll_;
363 gfx::Vector2d second_main_scroll_;
365 int num_will_begin_main_frames_;
366 int num_did_begin_main_frames_;
367 int num_will_commits_;
368 int num_did_commits_;
369 int num_impl_commits_;
370 int num_impl_scrolls_;
373 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit);
375 class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest {
377 LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
379 virtual void SetupTree() OVERRIDE {
380 LayerTreeHostScrollTest::SetupTree();
381 Layer* root_layer = layer_tree_host()->root_layer();
382 scoped_refptr<Layer> root_scroll_layer = Layer::Create();
383 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
384 root_scroll_layer->SetBounds(
385 gfx::Size(root_layer->bounds().width() + 100,
386 root_layer->bounds().height() + 100));
387 root_scroll_layer->SetIsDrawable(true);
388 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
389 root_layer->AddChild(root_scroll_layer);
391 layer_tree_host()->RegisterViewportLayers(
392 root_layer, root_scroll_layer, NULL);
393 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
396 virtual void BeginTest() OVERRIDE {
397 PostSetNeedsCommitToMainThread();
400 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
401 LayerImpl* root = impl->active_tree()->root_layer();
402 LayerImpl* scroll_layer = root->children()[0];
404 // Check that a fractional scroll delta is correctly accumulated over
406 switch (impl->active_tree()->source_frame_number()) {
408 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), gfx::Vector2d(0, 0));
409 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d(0, 0));
410 PostSetNeedsCommitToMainThread();
413 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(),
414 gfx::ToFlooredVector2d(scroll_amount_));
415 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
416 gfx::Vector2dF(fmod(scroll_amount_.x(), 1.0f), 0.0f));
417 PostSetNeedsCommitToMainThread();
421 scroll_layer->scroll_offset(),
422 gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_));
424 scroll_layer->ScrollDelta(),
425 gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f));
429 scroll_layer->ScrollBy(scroll_amount_);
432 virtual void AfterTest() OVERRIDE {}
435 gfx::Vector2dF scroll_amount_;
438 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll);
440 class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
442 LayerTreeHostScrollTestCaseWithChild()
443 : initial_offset_(10, 20),
444 javascript_scroll_(40, 5),
445 scroll_amount_(2, -1),
448 virtual void SetupTree() OVERRIDE {
449 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
451 scoped_refptr<Layer> root_layer = Layer::Create();
452 root_layer->SetBounds(gfx::Size(10, 10));
454 root_scroll_layer_ = FakePictureLayer::Create(&fake_content_layer_client_);
455 root_scroll_layer_->SetBounds(gfx::Size(110, 110));
457 root_scroll_layer_->SetPosition(gfx::Point());
459 root_scroll_layer_->SetIsDrawable(true);
460 root_scroll_layer_->SetScrollClipLayerId(root_layer->id());
461 root_scroll_layer_->SetIsContainerForFixedPositionLayers(true);
462 root_layer->AddChild(root_scroll_layer_);
464 child_layer_ = FakePictureLayer::Create(&fake_content_layer_client_);
465 child_layer_->set_did_scroll_callback(
466 base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
467 base::Unretained(this)));
468 child_layer_->SetBounds(gfx::Size(110, 110));
470 if (scroll_child_layer_) {
471 // Scrolls on the child layer will happen at 5, 5. If they are treated
472 // like device pixels, and device scale factor is 2, then they will
473 // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
474 child_layer_->SetPosition(gfx::Point(5, 5));
476 // Adjust the child layer horizontally so that scrolls will never hit it.
477 child_layer_->SetPosition(gfx::Point(60, 5));
480 child_layer_->SetIsDrawable(true);
481 child_layer_->SetScrollClipLayerId(root_layer->id());
482 child_layer_->SetBounds(root_scroll_layer_->bounds());
483 root_scroll_layer_->AddChild(child_layer_);
485 if (scroll_child_layer_) {
486 expected_scroll_layer_ = child_layer_;
487 expected_no_scroll_layer_ = root_scroll_layer_;
489 expected_scroll_layer_ = root_scroll_layer_;
490 expected_no_scroll_layer_ = child_layer_;
493 expected_scroll_layer_->SetScrollOffset(initial_offset_);
495 layer_tree_host()->SetRootLayer(root_layer);
496 layer_tree_host()->RegisterViewportLayers(
497 root_layer, root_scroll_layer_, NULL);
498 LayerTreeHostScrollTest::SetupTree();
501 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
503 virtual void WillCommit() OVERRIDE {
504 // Keep the test committing (otherwise the early out for no update
505 // will stall the test).
506 if (layer_tree_host()->source_frame_number() < 2) {
507 layer_tree_host()->SetNeedsCommit();
512 final_scroll_offset_ = expected_scroll_layer_->scroll_offset();
515 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
516 float scale) OVERRIDE {
520 virtual void Layout() OVERRIDE {
521 EXPECT_VECTOR_EQ(gfx::Vector2d(),
522 expected_no_scroll_layer_->scroll_offset());
524 switch (layer_tree_host()->source_frame_number()) {
526 EXPECT_VECTOR_EQ(initial_offset_,
527 expected_scroll_layer_->scroll_offset());
530 EXPECT_VECTOR_EQ(initial_offset_ + scroll_amount_,
531 expected_scroll_layer_->scroll_offset());
533 // Pretend like Javascript updated the scroll position itself.
534 expected_scroll_layer_->SetScrollOffset(javascript_scroll_);
537 EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_,
538 expected_scroll_layer_->scroll_offset());
543 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
544 LayerImpl* root_impl = impl->active_tree()->root_layer();
545 FakePictureLayerImpl* root_scroll_layer_impl =
546 static_cast<FakePictureLayerImpl*>(root_impl->children()[0]);
547 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>(
548 root_scroll_layer_impl->children()[0]);
550 LayerImpl* expected_scroll_layer_impl = NULL;
551 LayerImpl* expected_no_scroll_layer_impl = NULL;
552 if (scroll_child_layer_) {
553 expected_scroll_layer_impl = child_layer_impl;
554 expected_no_scroll_layer_impl = root_scroll_layer_impl;
556 expected_scroll_layer_impl = root_scroll_layer_impl;
557 expected_no_scroll_layer_impl = child_layer_impl;
560 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl->ScrollDelta());
561 EXPECT_VECTOR_EQ(gfx::Vector2d(),
562 expected_no_scroll_layer_impl->ScrollDelta());
564 // Ensure device scale factor is affecting the layers.
565 EXPECT_FLOAT_EQ(device_scale_factor_,
566 root_scroll_layer_impl->HighResTiling()->contents_scale());
568 EXPECT_FLOAT_EQ(device_scale_factor_,
569 child_layer_impl->HighResTiling()->contents_scale());
571 switch (impl->active_tree()->source_frame_number()) {
573 // Gesture scroll on impl thread.
574 InputHandler::ScrollStatus status = impl->ScrollBegin(
575 gfx::ToCeiledPoint(expected_scroll_layer_impl->position() -
576 gfx::Vector2dF(0.5f, 0.5f)),
577 InputHandler::Gesture);
578 EXPECT_EQ(InputHandler::ScrollStarted, status);
579 impl->ScrollBy(gfx::Point(), scroll_amount_);
582 // Check the scroll is applied as a delta.
583 EXPECT_VECTOR_EQ(initial_offset_,
584 expected_scroll_layer_impl->scroll_offset());
585 EXPECT_VECTOR_EQ(scroll_amount_,
586 expected_scroll_layer_impl->ScrollDelta());
590 // Wheel scroll on impl thread.
591 InputHandler::ScrollStatus status = impl->ScrollBegin(
592 gfx::ToCeiledPoint(expected_scroll_layer_impl->position() +
593 gfx::Vector2dF(0.5f, 0.5f)),
594 InputHandler::Wheel);
595 EXPECT_EQ(InputHandler::ScrollStarted, status);
596 impl->ScrollBy(gfx::Point(), scroll_amount_);
599 // Check the scroll is applied as a delta.
600 EXPECT_VECTOR_EQ(javascript_scroll_,
601 expected_scroll_layer_impl->scroll_offset());
602 EXPECT_VECTOR_EQ(scroll_amount_,
603 expected_scroll_layer_impl->ScrollDelta());
608 EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_,
609 expected_scroll_layer_impl->scroll_offset());
610 EXPECT_VECTOR_EQ(gfx::Vector2d(),
611 expected_scroll_layer_impl->ScrollDelta());
618 virtual void AfterTest() OVERRIDE {
619 if (scroll_child_layer_) {
620 EXPECT_EQ(0, num_scrolls_);
621 EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_,
622 final_scroll_offset_);
624 EXPECT_EQ(2, num_scrolls_);
625 EXPECT_VECTOR_EQ(gfx::Vector2d(), final_scroll_offset_);
630 float device_scale_factor_;
631 bool scroll_child_layer_;
633 gfx::Vector2d initial_offset_;
634 gfx::Vector2d javascript_scroll_;
635 gfx::Vector2d scroll_amount_;
637 gfx::Vector2d final_scroll_offset_;
639 FakeContentLayerClient fake_content_layer_client_;
641 scoped_refptr<Layer> root_scroll_layer_;
642 scoped_refptr<Layer> child_layer_;
643 scoped_refptr<Layer> expected_scroll_layer_;
644 scoped_refptr<Layer> expected_no_scroll_layer_;
647 TEST_F(LayerTreeHostScrollTestCaseWithChild,
648 DeviceScaleFactor1_ScrollChild_DirectRenderer) {
649 device_scale_factor_ = 1.f;
650 scroll_child_layer_ = true;
651 RunTest(true, false, true);
654 TEST_F(LayerTreeHostScrollTestCaseWithChild,
655 DeviceScaleFactor1_ScrollChild_DelegatingRenderer) {
656 device_scale_factor_ = 1.f;
657 scroll_child_layer_ = true;
658 RunTest(true, true, true);
661 TEST_F(LayerTreeHostScrollTestCaseWithChild,
662 DeviceScaleFactor15_ScrollChild_DirectRenderer) {
663 device_scale_factor_ = 1.5f;
664 scroll_child_layer_ = true;
665 RunTest(true, false, true);
668 TEST_F(LayerTreeHostScrollTestCaseWithChild,
669 DeviceScaleFactor15_ScrollChild_DelegatingRenderer) {
670 device_scale_factor_ = 1.5f;
671 scroll_child_layer_ = true;
672 RunTest(true, true, true);
675 TEST_F(LayerTreeHostScrollTestCaseWithChild,
676 DeviceScaleFactor2_ScrollChild_DirectRenderer) {
677 device_scale_factor_ = 2.f;
678 scroll_child_layer_ = true;
679 RunTest(true, false, true);
682 TEST_F(LayerTreeHostScrollTestCaseWithChild,
683 DeviceScaleFactor2_ScrollChild_DelegatingRenderer) {
684 device_scale_factor_ = 2.f;
685 scroll_child_layer_ = true;
686 RunTest(true, true, true);
689 TEST_F(LayerTreeHostScrollTestCaseWithChild,
690 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer) {
691 device_scale_factor_ = 1.f;
692 scroll_child_layer_ = false;
693 RunTest(true, false, true);
696 TEST_F(LayerTreeHostScrollTestCaseWithChild,
697 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer) {
698 device_scale_factor_ = 1.f;
699 scroll_child_layer_ = false;
700 RunTest(true, true, true);
703 TEST_F(LayerTreeHostScrollTestCaseWithChild,
704 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer) {
705 device_scale_factor_ = 1.5f;
706 scroll_child_layer_ = false;
707 RunTest(true, false, true);
710 TEST_F(LayerTreeHostScrollTestCaseWithChild,
711 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer) {
712 device_scale_factor_ = 1.5f;
713 scroll_child_layer_ = false;
714 RunTest(true, true, true);
717 TEST_F(LayerTreeHostScrollTestCaseWithChild,
718 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer) {
719 device_scale_factor_ = 2.f;
720 scroll_child_layer_ = false;
721 RunTest(true, false, true);
724 TEST_F(LayerTreeHostScrollTestCaseWithChild,
725 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer) {
726 device_scale_factor_ = 2.f;
727 scroll_child_layer_ = false;
728 RunTest(true, true, true);
731 class ImplSidePaintingScrollTest : public LayerTreeHostScrollTest {
733 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
734 settings->impl_side_painting = true;
737 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
738 if (impl->pending_tree())
739 impl->SetNeedsRedraw();
743 class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest {
745 ImplSidePaintingScrollTestSimple()
746 : initial_scroll_(10, 20),
747 main_thread_scroll_(40, 5),
748 impl_thread_scroll1_(2, -1),
749 impl_thread_scroll2_(-3, 10),
752 virtual void SetupTree() OVERRIDE {
753 LayerTreeHostScrollTest::SetupTree();
754 Layer* root_layer = layer_tree_host()->root_layer();
755 scoped_refptr<Layer> root_scroll_layer = Layer::Create();
756 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
757 root_scroll_layer->SetScrollOffset(initial_scroll_);
758 root_scroll_layer->SetBounds(
759 gfx::Size(root_layer->bounds().width() + 100,
760 root_layer->bounds().height() + 100));
761 root_scroll_layer->SetIsDrawable(true);
762 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
763 root_layer->AddChild(root_scroll_layer);
765 layer_tree_host()->RegisterViewportLayers(
766 root_layer, root_scroll_layer, NULL);
767 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
770 virtual void BeginTest() OVERRIDE {
771 PostSetNeedsCommitToMainThread();
774 virtual void Layout() OVERRIDE {
775 Layer* root = layer_tree_host()->root_layer();
776 Layer* scroll_layer = root->children()[0];
777 if (!layer_tree_host()->source_frame_number()) {
778 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
780 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(),
781 initial_scroll_ + impl_thread_scroll1_);
783 // Pretend like Javascript updated the scroll position itself with a
784 // change of main_thread_scroll.
785 scroll_layer->SetScrollOffset(initial_scroll_ + main_thread_scroll_ +
786 impl_thread_scroll1_);
790 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
791 // We force a second draw here of the first commit before activating
792 // the second commit.
793 if (impl->active_tree()->source_frame_number() == 0)
794 impl->SetNeedsRedraw();
797 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
798 ImplSidePaintingScrollTest::DrawLayersOnThread(impl);
800 LayerImpl* root = impl->active_tree()->root_layer();
801 LayerImpl* scroll_layer = root->children()[0];
802 LayerImpl* pending_root =
803 impl->active_tree()->FindPendingTreeLayerById(root->id());
805 switch (impl->active_tree()->source_frame_number()) {
807 if (!impl->pending_tree()) {
808 impl->BlockNotifyReadyToActivateForTesting(true);
809 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
810 scroll_layer->ScrollBy(impl_thread_scroll1_);
812 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
813 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll1_);
814 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
815 PostSetNeedsCommitToMainThread();
817 // CommitCompleteOnThread will trigger this function again
818 // and cause us to take the else clause.
820 impl->BlockNotifyReadyToActivateForTesting(false);
821 ASSERT_TRUE(pending_root);
822 EXPECT_EQ(impl->pending_tree()->source_frame_number(), 1);
824 scroll_layer->ScrollBy(impl_thread_scroll2_);
825 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
826 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
827 impl_thread_scroll1_ + impl_thread_scroll2_);
828 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(),
829 impl_thread_scroll1_);
831 LayerImpl* pending_scroll_layer = pending_root->children()[0];
833 pending_scroll_layer->scroll_offset(),
834 initial_scroll_ + main_thread_scroll_ + impl_thread_scroll1_);
835 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(),
836 impl_thread_scroll2_);
837 EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
842 EXPECT_FALSE(impl->pending_tree());
844 scroll_layer->scroll_offset(),
845 initial_scroll_ + main_thread_scroll_ + impl_thread_scroll1_);
846 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll2_);
847 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
853 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
854 float scale) OVERRIDE {
858 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); }
861 gfx::Vector2d initial_scroll_;
862 gfx::Vector2d main_thread_scroll_;
863 gfx::Vector2d impl_thread_scroll1_;
864 gfx::Vector2d impl_thread_scroll2_;
868 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple);
870 // This test makes sure that layers pick up scrolls that occur between
871 // beginning a commit and finishing a commit (aka scroll deltas not
872 // included in sent scroll delta) still apply to layers that don't
874 class ImplSidePaintingScrollTestImplOnlyScroll
875 : public ImplSidePaintingScrollTest {
877 ImplSidePaintingScrollTestImplOnlyScroll()
878 : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3) {}
880 virtual void SetupTree() OVERRIDE {
881 LayerTreeHostScrollTest::SetupTree();
882 Layer* root_layer = layer_tree_host()->root_layer();
883 scoped_refptr<Layer> root_scroll_layer = Layer::Create();
884 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
885 root_scroll_layer->SetScrollOffset(initial_scroll_);
886 root_scroll_layer->SetBounds(
887 gfx::Size(root_layer->bounds().width() + 100,
888 root_layer->bounds().height() + 100));
889 root_scroll_layer->SetIsDrawable(true);
890 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
891 root_layer->AddChild(root_scroll_layer);
893 layer_tree_host()->RegisterViewportLayers(
894 root_layer, root_scroll_layer, NULL);
895 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
898 virtual void BeginTest() OVERRIDE {
899 PostSetNeedsCommitToMainThread();
902 virtual void WillCommit() OVERRIDE {
903 Layer* root = layer_tree_host()->root_layer();
904 Layer* scroll_layer = root->children()[0];
905 switch (layer_tree_host()->source_frame_number()) {
907 EXPECT_TRUE(scroll_layer->needs_push_properties());
910 // Even if this layer doesn't need push properties, it should
911 // still pick up scrolls that happen on the active layer during
913 EXPECT_FALSE(scroll_layer->needs_push_properties());
918 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
919 // Scroll after the 2nd commit has started.
920 if (impl->active_tree()->source_frame_number() == 0) {
921 LayerImpl* active_root = impl->active_tree()->root_layer();
922 LayerImpl* active_scroll_layer = active_root->children()[0];
923 ASSERT_TRUE(active_root);
924 ASSERT_TRUE(active_scroll_layer);
925 active_scroll_layer->ScrollBy(impl_thread_scroll_);
929 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
930 // We force a second draw here of the first commit before activating
931 // the second commit.
932 LayerImpl* active_root = impl->active_tree()->root_layer();
933 LayerImpl* active_scroll_layer =
934 active_root ? active_root->children()[0] : NULL;
935 LayerImpl* pending_root = impl->pending_tree()->root_layer();
936 LayerImpl* pending_scroll_layer = pending_root->children()[0];
938 ASSERT_TRUE(pending_root);
939 ASSERT_TRUE(pending_scroll_layer);
940 switch (impl->pending_tree()->source_frame_number()) {
942 EXPECT_VECTOR_EQ(pending_scroll_layer->scroll_offset(),
944 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d());
945 EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
947 EXPECT_FALSE(active_root);
950 // Even though the scroll happened during the commit, both layers
951 // should have the appropriate scroll delta.
952 EXPECT_VECTOR_EQ(pending_scroll_layer->scroll_offset(),
954 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(),
955 impl_thread_scroll_);
956 EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
958 ASSERT_TRUE(active_root);
959 EXPECT_VECTOR_EQ(active_scroll_layer->scroll_offset(), initial_scroll_);
960 EXPECT_VECTOR_EQ(active_scroll_layer->ScrollDelta(),
961 impl_thread_scroll_);
962 EXPECT_VECTOR_EQ(active_scroll_layer->sent_scroll_delta(),
966 // On the next commit, this delta should have been sent and applied.
967 EXPECT_VECTOR_EQ(pending_scroll_layer->scroll_offset(),
968 initial_scroll_ + impl_thread_scroll_);
969 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d());
970 EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
977 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
978 ImplSidePaintingScrollTest::DrawLayersOnThread(impl);
980 LayerImpl* root = impl->active_tree()->root_layer();
981 LayerImpl* scroll_layer = root->children()[0];
983 switch (impl->active_tree()->source_frame_number()) {
985 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
986 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
987 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
988 PostSetNeedsCommitToMainThread();
991 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
992 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll_);
993 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
994 PostSetNeedsCommitToMainThread();
999 virtual void AfterTest() OVERRIDE {}
1002 gfx::Vector2d initial_scroll_;
1003 gfx::Vector2d impl_thread_scroll_;
1006 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll);
1008 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
1009 : public LayerTreeHostScrollTest {
1011 LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
1013 virtual void SetupTree() OVERRIDE {
1014 LayerTreeTest::SetupTree();
1015 scoped_refptr<Layer> scroll_layer = Layer::Create();
1016 layer_tree_host()->root_layer()->AddChild(scroll_layer);
1019 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1021 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1022 LayerImpl* root = impl->active_tree()->root_layer();
1023 LayerImpl* scroll_layer = root->children()[0];
1024 scroll_layer->SetScrollClipLayer(root->id());
1026 // Set max_scroll_offset = (100, 100).
1027 scroll_layer->SetBounds(
1028 gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
1029 EXPECT_EQ(InputHandler::ScrollStarted,
1030 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f),
1031 InputHandler::Gesture));
1033 // Set max_scroll_offset = (0, 0).
1034 scroll_layer->SetBounds(root->bounds());
1035 EXPECT_EQ(InputHandler::ScrollIgnored,
1036 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f),
1037 InputHandler::Gesture));
1039 // Set max_scroll_offset = (-100, -100).
1040 scroll_layer->SetBounds(gfx::Size());
1041 EXPECT_EQ(InputHandler::ScrollIgnored,
1042 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f),
1043 InputHandler::Gesture));
1048 virtual void AfterTest() OVERRIDE {}
1051 SINGLE_AND_MULTI_THREAD_TEST_F(
1052 LayerTreeHostScrollTestScrollZeroMaxScrollOffset);
1054 class ThreadCheckingInputHandlerClient : public InputHandlerClient {
1056 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner* runner,
1057 bool* received_stop_flinging)
1058 : task_runner_(runner), received_stop_flinging_(received_stop_flinging) {}
1060 virtual void WillShutdown() OVERRIDE {
1061 if (!received_stop_flinging_)
1062 ADD_FAILURE() << "WillShutdown() called before fling stopped";
1065 virtual void Animate(base::TimeTicks time) OVERRIDE {
1066 if (!task_runner_->BelongsToCurrentThread())
1067 ADD_FAILURE() << "Animate called on wrong thread";
1070 virtual void MainThreadHasStoppedFlinging() OVERRIDE {
1071 if (!task_runner_->BelongsToCurrentThread())
1072 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
1073 *received_stop_flinging_ = true;
1076 virtual void DidOverscroll(
1077 const gfx::PointF& causal_event_viewport_point,
1078 const gfx::Vector2dF& accumulated_overscroll,
1079 const gfx::Vector2dF& latest_overscroll_delta) OVERRIDE {
1080 if (!task_runner_->BelongsToCurrentThread())
1081 ADD_FAILURE() << "DidOverscroll called on wrong thread";
1085 base::SingleThreadTaskRunner* task_runner_;
1086 bool* received_stop_flinging_;
1089 void BindInputHandlerOnCompositorThread(
1090 const base::WeakPtr<InputHandler>& input_handler,
1091 ThreadCheckingInputHandlerClient* client) {
1092 input_handler->BindToClient(client);
1095 TEST(LayerTreeHostFlingTest, DidStopFlingingThread) {
1096 base::Thread impl_thread("cc");
1097 ASSERT_TRUE(impl_thread.Start());
1099 bool received_stop_flinging = false;
1100 LayerTreeSettings settings;
1102 ThreadCheckingInputHandlerClient input_handler_client(
1103 impl_thread.message_loop_proxy().get(), &received_stop_flinging);
1104 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1106 ASSERT_TRUE(impl_thread.message_loop_proxy().get());
1107 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1108 new TestSharedBitmapManager());
1109 scoped_ptr<LayerTreeHost> layer_tree_host =
1110 LayerTreeHost::CreateThreaded(&client,
1111 shared_bitmap_manager.get(),
1113 base::MessageLoopProxy::current(),
1114 impl_thread.message_loop_proxy());
1116 impl_thread.message_loop_proxy()
1117 ->PostTask(FROM_HERE,
1118 base::Bind(&BindInputHandlerOnCompositorThread,
1119 layer_tree_host->GetInputHandler(),
1120 base::Unretained(&input_handler_client)));
1122 layer_tree_host->DidStopFlinging();
1123 layer_tree_host.reset();
1125 EXPECT_TRUE(received_stop_flinging);
1128 class LayerTreeHostScrollTestLayerStructureChange
1129 : public LayerTreeHostScrollTest {
1131 LayerTreeHostScrollTestLayerStructureChange()
1132 : scroll_destroy_whole_tree_(false) {}
1134 virtual void SetupTree() OVERRIDE {
1135 scoped_refptr<Layer> root_layer = Layer::Create();
1136 root_layer->SetBounds(gfx::Size(10, 10));
1138 Layer* root_scroll_layer =
1139 CreateScrollLayer(root_layer.get(), &root_scroll_layer_client_);
1140 CreateScrollLayer(root_layer.get(), &sibling_scroll_layer_client_);
1141 CreateScrollLayer(root_scroll_layer, &child_scroll_layer_client_);
1143 layer_tree_host()->SetRootLayer(root_layer);
1144 LayerTreeHostScrollTest::SetupTree();
1147 virtual void BeginTest() OVERRIDE {
1148 PostSetNeedsCommitToMainThread();
1151 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1152 LayerImpl* root = impl->active_tree()->root_layer();
1153 switch (impl->active_tree()->source_frame_number()) {
1155 root->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1156 root->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1157 root->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5));
1158 PostSetNeedsCommitToMainThread();
1166 virtual void AfterTest() OVERRIDE {}
1168 virtual void DidScroll(Layer* layer) {
1169 if (scroll_destroy_whole_tree_) {
1170 layer_tree_host()->SetRootLayer(NULL);
1174 layer->RemoveFromParent();
1178 class FakeLayerScrollClient {
1181 owner_->DidScroll(layer_);
1183 LayerTreeHostScrollTestLayerStructureChange* owner_;
1187 Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) {
1188 scoped_refptr<PictureLayer> scroll_layer =
1189 PictureLayer::Create(&fake_content_layer_client_);
1190 scroll_layer->SetBounds(gfx::Size(110, 110));
1191 scroll_layer->SetPosition(gfx::Point(0, 0));
1192 scroll_layer->SetIsDrawable(true);
1193 scroll_layer->SetScrollClipLayerId(parent->id());
1194 scroll_layer->SetBounds(gfx::Size(parent->bounds().width() + 100,
1195 parent->bounds().height() + 100));
1196 scroll_layer->set_did_scroll_callback(base::Bind(
1197 &FakeLayerScrollClient::DidScroll, base::Unretained(client)));
1198 client->owner_ = this;
1199 client->layer_ = scroll_layer.get();
1200 parent->AddChild(scroll_layer);
1201 return scroll_layer.get();
1204 FakeLayerScrollClient root_scroll_layer_client_;
1205 FakeLayerScrollClient sibling_scroll_layer_client_;
1206 FakeLayerScrollClient child_scroll_layer_client_;
1208 FakeContentLayerClient fake_content_layer_client_;
1210 bool scroll_destroy_whole_tree_;
1213 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyLayer) {
1214 RunTest(true, false, true);
1217 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) {
1218 scroll_destroy_whole_tree_ = true;
1219 RunTest(true, false, true);