1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host.h"
7 #include "base/memory/weak_ptr.h"
8 #include "cc/layers/layer.h"
9 #include "cc/layers/layer_impl.h"
10 #include "cc/layers/picture_layer.h"
11 #include "cc/scheduler/begin_frame_source.h"
12 #include "cc/test/fake_content_layer_client.h"
13 #include "cc/test/fake_layer_tree_host_client.h"
14 #include "cc/test/fake_picture_layer.h"
15 #include "cc/test/fake_picture_layer_impl.h"
16 #include "cc/test/geometry_test_utils.h"
17 #include "cc/test/layer_tree_test.h"
18 #include "cc/test/test_shared_bitmap_manager.h"
19 #include "cc/trees/layer_tree_impl.h"
20 #include "ui/gfx/geometry/point_conversions.h"
21 #include "ui/gfx/geometry/size_conversions.h"
22 #include "ui/gfx/geometry/vector2d_conversions.h"
27 class LayerTreeHostScrollTest
: public LayerTreeTest
{};
29 class LayerTreeHostScrollTestScrollSimple
: public LayerTreeHostScrollTest
{
31 LayerTreeHostScrollTestScrollSimple()
32 : initial_scroll_(10, 20),
33 second_scroll_(40, 5),
34 scroll_amount_(2, -1),
37 void BeginTest() override
{
38 Layer
* root_layer
= layer_tree_host()->root_layer();
39 scoped_refptr
<Layer
> scroll_layer
= Layer::Create();
40 root_layer
->AddChild(scroll_layer
);
41 // Create an effective max_scroll_offset of (100, 100).
42 scroll_layer
->SetBounds(gfx::Size(root_layer
->bounds().width() + 100,
43 root_layer
->bounds().height() + 100));
44 scroll_layer
->SetIsDrawable(true);
45 scroll_layer
->SetIsContainerForFixedPositionLayers(true);
46 scroll_layer
->SetScrollClipLayerId(root_layer
->id());
47 scroll_layer
->SetScrollOffset(initial_scroll_
);
48 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
, scroll_layer
,
50 PostSetNeedsCommitToMainThread();
53 void Layout() override
{
54 Layer
* root
= layer_tree_host()->root_layer();
55 Layer
* scroll_layer
= root
->children()[0].get();
56 if (!layer_tree_host()->source_frame_number()) {
57 EXPECT_VECTOR_EQ(initial_scroll_
, scroll_layer
->scroll_offset());
59 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_
,
61 scroll_layer
->scroll_offset());
63 // Pretend like Javascript updated the scroll position itself.
64 scroll_layer
->SetScrollOffset(second_scroll_
);
68 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
69 LayerImpl
* root
= impl
->active_tree()->root_layer();
70 LayerImpl
* scroll_layer
= root
->children()[0];
71 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer
->ScrollDelta());
73 scroll_layer
->SetScrollClipLayer(root
->id());
74 scroll_layer
->SetBounds(
75 gfx::Size(root
->bounds().width() + 100, root
->bounds().height() + 100));
76 scroll_layer
->ScrollBy(scroll_amount_
);
78 switch (impl
->active_tree()->source_frame_number()) {
80 EXPECT_VECTOR_EQ(initial_scroll_
, scroll_layer
->BaseScrollOffset());
81 EXPECT_VECTOR_EQ(scroll_amount_
, scroll_layer
->ScrollDelta());
82 PostSetNeedsCommitToMainThread();
85 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), second_scroll_
);
86 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
92 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
94 float top_controls_delta
) override
{
98 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
101 gfx::ScrollOffset initial_scroll_
;
102 gfx::ScrollOffset second_scroll_
;
103 gfx::Vector2dF scroll_amount_
;
107 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple
);
109 class LayerTreeHostScrollTestScrollMultipleRedraw
110 : public LayerTreeHostScrollTest
{
112 LayerTreeHostScrollTestScrollMultipleRedraw()
113 : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
115 void BeginTest() override
{
116 Layer
* root_layer
= layer_tree_host()->root_layer();
117 scroll_layer_
= Layer::Create();
118 root_layer
->AddChild(scroll_layer_
);
119 // Create an effective max_scroll_offset of (100, 100).
120 scroll_layer_
->SetBounds(gfx::Size(root_layer
->bounds().width() + 100,
121 root_layer
->bounds().height() + 100));
122 scroll_layer_
->SetIsDrawable(true);
123 scroll_layer_
->SetIsContainerForFixedPositionLayers(true);
124 scroll_layer_
->SetScrollClipLayerId(root_layer
->id());
125 scroll_layer_
->SetScrollOffset(initial_scroll_
);
126 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
, scroll_layer_
,
128 PostSetNeedsCommitToMainThread();
131 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
132 switch (layer_tree_host()->source_frame_number()) {
134 EXPECT_VECTOR_EQ(scroll_layer_
->scroll_offset(), initial_scroll_
);
138 scroll_layer_
->scroll_offset(),
139 gfx::ScrollOffsetWithDelta(initial_scroll_
,
140 scroll_amount_
+ scroll_amount_
));
143 scroll_layer_
->scroll_offset(),
144 gfx::ScrollOffsetWithDelta(initial_scroll_
,
145 scroll_amount_
+ scroll_amount_
));
150 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
151 LayerImpl
* scroll_layer
=
152 impl
->active_tree()->LayerById(scroll_layer_
->id());
153 if (impl
->active_tree()->source_frame_number() == 0 &&
154 impl
->SourceAnimationFrameNumber() == 1) {
155 // First draw after first commit.
156 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
157 scroll_layer
->ScrollBy(scroll_amount_
);
158 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
160 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
161 PostSetNeedsRedrawToMainThread();
162 } else if (impl
->active_tree()->source_frame_number() == 0 &&
163 impl
->SourceAnimationFrameNumber() == 2) {
164 // Second draw after first commit.
165 EXPECT_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
166 scroll_layer
->ScrollBy(scroll_amount_
);
167 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
168 scroll_amount_
+ scroll_amount_
);
170 EXPECT_VECTOR_EQ(scroll_layer_
->scroll_offset(), initial_scroll_
);
171 PostSetNeedsCommitToMainThread();
172 } else if (impl
->active_tree()->source_frame_number() == 1) {
173 // Third or later draw after second commit.
174 EXPECT_GE(impl
->SourceAnimationFrameNumber(), 3);
175 EXPECT_VECTOR_EQ(scroll_layer_
->ScrollDelta(), gfx::Vector2d());
177 scroll_layer_
->scroll_offset(),
178 gfx::ScrollOffsetWithDelta(initial_scroll_
,
179 scroll_amount_
+ scroll_amount_
));
184 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
186 float top_controls_delta
) override
{
190 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
193 gfx::ScrollOffset initial_scroll_
;
194 gfx::Vector2dF scroll_amount_
;
196 scoped_refptr
<Layer
> scroll_layer_
;
199 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw
);
201 class LayerTreeHostScrollTestScrollAbortedCommit
202 : public LayerTreeHostScrollTest
{
204 LayerTreeHostScrollTestScrollAbortedCommit()
205 : initial_scroll_(50, 60),
207 second_main_scroll_(14, -3),
209 num_will_begin_main_frames_(0),
210 num_did_begin_main_frames_(0),
211 num_will_commits_(0),
213 num_impl_commits_(0),
214 num_impl_scrolls_(0) {}
216 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
218 void SetupTree() override
{
219 LayerTreeHostScrollTest::SetupTree();
220 Layer
* root_layer
= layer_tree_host()->root_layer();
221 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
222 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
223 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
224 root_scroll_layer
->SetBounds(gfx::Size(200, 200));
225 root_scroll_layer
->SetIsDrawable(true);
226 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
227 root_layer
->AddChild(root_scroll_layer
);
229 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
230 root_scroll_layer
, NULL
);
231 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
234 void WillBeginMainFrame() override
{
235 num_will_begin_main_frames_
++;
236 Layer
* root_scroll_layer
=
237 layer_tree_host()->root_layer()->children()[0].get();
238 switch (num_will_begin_main_frames_
) {
240 // This will not be aborted because of the initial prop changes.
241 EXPECT_EQ(0, num_impl_scrolls_
);
242 EXPECT_EQ(0, layer_tree_host()->source_frame_number());
243 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(), initial_scroll_
);
244 EXPECT_EQ(1.f
, layer_tree_host()->page_scale_factor());
247 // This commit will be aborted, and another commit will be
248 // initiated from the redraw.
249 EXPECT_EQ(1, num_impl_scrolls_
);
250 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
252 root_scroll_layer
->scroll_offset(),
253 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_scroll_
));
254 EXPECT_EQ(impl_scale_
, layer_tree_host()->page_scale_factor());
255 PostSetNeedsRedrawToMainThread();
258 // This commit will not be aborted because of the scroll change.
259 EXPECT_EQ(2, num_impl_scrolls_
);
260 // The source frame number still increases even with the abort.
261 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
263 root_scroll_layer
->scroll_offset(),
264 gfx::ScrollOffsetWithDelta(initial_scroll_
,
265 impl_scroll_
+ impl_scroll_
));
266 EXPECT_EQ(impl_scale_
* impl_scale_
,
267 layer_tree_host()->page_scale_factor());
268 root_scroll_layer
->SetScrollOffset(gfx::ScrollOffsetWithDelta(
269 root_scroll_layer
->scroll_offset(), second_main_scroll_
));
272 // This commit will also be aborted.
273 EXPECT_EQ(3, num_impl_scrolls_
);
274 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
275 gfx::Vector2dF delta
=
276 impl_scroll_
+ impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
277 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
278 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
280 // End the test by drawing to verify this commit is also aborted.
281 PostSetNeedsRedrawToMainThread();
286 void DidBeginMainFrame() override
{ num_did_begin_main_frames_
++; }
288 void WillCommit() override
{ num_will_commits_
++; }
290 void DidCommit() override
{ num_did_commits_
++; }
292 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
296 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
297 LayerImpl
* root_scroll_layer
=
298 impl
->active_tree()->root_layer()->children()[0];
300 if (impl
->active_tree()->source_frame_number() == 0 &&
301 impl
->SourceAnimationFrameNumber() == 1) {
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
->BaseScrollOffset(), initial_scroll_
);
308 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
309 EXPECT_EQ(1.f
, impl
->active_tree()->current_page_scale_factor());
310 impl
->SetPageScaleOnActiveTree(impl_scale_
);
311 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
312 EXPECT_EQ(impl_scale_
, impl
->active_tree()->current_page_scale_factor());
314 // To simplify the testing flow, don't redraw here, just commit.
315 impl
->SetNeedsCommit();
316 } else if (impl
->active_tree()->source_frame_number() == 0 &&
317 impl
->SourceAnimationFrameNumber() == 2) {
318 // Test a second draw after an aborted commit.
319 // The scroll/scale values should be baked into the offset/scale factor
320 // since the main thread consumed but aborted the begin frame.
321 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
322 root_scroll_layer
->ScrollBy(impl_scroll_
);
323 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
325 root_scroll_layer
->BaseScrollOffset(),
326 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_scroll_
));
328 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
329 EXPECT_EQ(impl_scale_
, impl
->active_tree()->current_page_scale_factor());
330 impl
->SetPageScaleOnActiveTree(impl_scale_
* impl_scale_
);
331 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
332 EXPECT_EQ(impl_scale_
* impl_scale_
,
333 impl
->active_tree()->current_page_scale_factor());
335 impl
->SetNeedsCommit();
336 } else if (impl
->active_tree()->source_frame_number() == 1) {
337 // Commit for source frame 1 is aborted.
339 } else if (impl
->active_tree()->source_frame_number() == 2 &&
340 impl
->SourceAnimationFrameNumber() == 3) {
341 // Third draw after the second full commit.
342 EXPECT_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
343 root_scroll_layer
->ScrollBy(impl_scroll_
);
344 impl
->SetNeedsCommit();
345 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
346 gfx::Vector2dF delta
= impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
347 EXPECT_VECTOR_EQ(root_scroll_layer
->BaseScrollOffset(),
348 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
349 } else if (impl
->active_tree()->source_frame_number() == 2 &&
350 impl
->SourceAnimationFrameNumber() == 4) {
351 // Final draw after the second aborted commit.
352 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
353 gfx::Vector2dF delta
=
354 impl_scroll_
+ impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
355 EXPECT_VECTOR_EQ(root_scroll_layer
->BaseScrollOffset(),
356 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
359 // Commit for source frame 3 is aborted.
364 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
366 float top_controls_delta
) override
{
370 void AfterTest() override
{
371 EXPECT_EQ(3, num_impl_scrolls_
);
372 // Verify that the embedder sees aborted commits as real commits.
373 EXPECT_EQ(4, num_will_begin_main_frames_
);
374 EXPECT_EQ(4, num_did_begin_main_frames_
);
375 EXPECT_EQ(4, num_will_commits_
);
376 EXPECT_EQ(4, num_did_commits_
);
377 // ...but the compositor thread only sees two real ones.
378 EXPECT_EQ(2, num_impl_commits_
);
382 gfx::ScrollOffset initial_scroll_
;
383 gfx::Vector2dF impl_scroll_
;
384 gfx::Vector2dF second_main_scroll_
;
386 int num_will_begin_main_frames_
;
387 int num_did_begin_main_frames_
;
388 int num_will_commits_
;
389 int num_did_commits_
;
390 int num_impl_commits_
;
391 int num_impl_scrolls_
;
394 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit
);
396 class LayerTreeHostScrollTestFractionalScroll
: public LayerTreeHostScrollTest
{
398 LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
400 void SetupTree() override
{
401 LayerTreeHostScrollTest::SetupTree();
402 Layer
* root_layer
= layer_tree_host()->root_layer();
403 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
404 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
405 root_scroll_layer
->SetBounds(
406 gfx::Size(root_layer
->bounds().width() + 100,
407 root_layer
->bounds().height() + 100));
408 root_scroll_layer
->SetIsDrawable(true);
409 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
410 root_layer
->AddChild(root_scroll_layer
);
412 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
413 root_scroll_layer
, NULL
);
414 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
417 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
419 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
420 LayerImpl
* root
= impl
->active_tree()->root_layer();
421 LayerImpl
* scroll_layer
= root
->children()[0];
423 // Check that a fractional scroll delta is correctly accumulated over
425 switch (impl
->active_tree()->source_frame_number()) {
427 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), gfx::Vector2d(0, 0));
428 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d(0, 0));
429 PostSetNeedsCommitToMainThread();
432 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(),
433 gfx::ToFlooredVector2d(scroll_amount_
));
434 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
435 gfx::Vector2dF(fmod(scroll_amount_
.x(), 1.0f
), 0.0f
));
436 PostSetNeedsCommitToMainThread();
440 scroll_layer
->BaseScrollOffset(),
441 gfx::ToFlooredVector2d(scroll_amount_
+ scroll_amount_
));
443 scroll_layer
->ScrollDelta(),
444 gfx::Vector2dF(fmod(2.0f
* scroll_amount_
.x(), 1.0f
), 0.0f
));
448 scroll_layer
->ScrollBy(scroll_amount_
);
451 void AfterTest() override
{}
454 gfx::Vector2dF scroll_amount_
;
457 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll
);
459 class LayerTreeHostScrollTestCaseWithChild
: public LayerTreeHostScrollTest
{
461 LayerTreeHostScrollTestCaseWithChild()
462 : initial_offset_(10, 20),
463 javascript_scroll_(40, 5),
464 scroll_amount_(2, -1),
467 void SetupTree() override
{
468 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_
);
470 scoped_refptr
<Layer
> root_layer
= Layer::Create();
471 root_layer
->SetBounds(gfx::Size(10, 10));
473 root_scroll_layer_
= FakePictureLayer::Create(&fake_content_layer_client_
);
474 root_scroll_layer_
->SetBounds(gfx::Size(110, 110));
476 root_scroll_layer_
->SetPosition(gfx::Point());
478 root_scroll_layer_
->SetIsDrawable(true);
479 root_scroll_layer_
->SetScrollClipLayerId(root_layer
->id());
480 root_scroll_layer_
->SetIsContainerForFixedPositionLayers(true);
481 root_layer
->AddChild(root_scroll_layer_
);
483 child_layer_
= FakePictureLayer::Create(&fake_content_layer_client_
);
484 child_layer_
->set_did_scroll_callback(
485 base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll
,
486 base::Unretained(this)));
487 child_layer_
->SetBounds(gfx::Size(110, 110));
489 if (scroll_child_layer_
) {
490 // Scrolls on the child layer will happen at 5, 5. If they are treated
491 // like device pixels, and device scale factor is 2, then they will
492 // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
493 child_layer_
->SetPosition(gfx::Point(5, 5));
495 // Adjust the child layer horizontally so that scrolls will never hit it.
496 child_layer_
->SetPosition(gfx::Point(60, 5));
499 child_layer_
->SetIsDrawable(true);
500 child_layer_
->SetScrollClipLayerId(root_layer
->id());
501 child_layer_
->SetBounds(root_scroll_layer_
->bounds());
502 root_scroll_layer_
->AddChild(child_layer_
);
504 if (scroll_child_layer_
) {
505 expected_scroll_layer_
= child_layer_
;
506 expected_no_scroll_layer_
= root_scroll_layer_
;
508 expected_scroll_layer_
= root_scroll_layer_
;
509 expected_no_scroll_layer_
= child_layer_
;
512 expected_scroll_layer_
->SetScrollOffset(initial_offset_
);
514 layer_tree_host()->SetRootLayer(root_layer
);
515 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
516 root_scroll_layer_
, NULL
);
517 LayerTreeHostScrollTest::SetupTree();
520 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
522 void WillCommit() override
{
523 // Keep the test committing (otherwise the early out for no update
524 // will stall the test).
525 if (layer_tree_host()->source_frame_number() < 2) {
526 layer_tree_host()->SetNeedsCommit();
531 final_scroll_offset_
= expected_scroll_layer_
->scroll_offset();
534 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
536 float top_controls_delta
) override
{
540 void Layout() override
{
541 EXPECT_VECTOR_EQ(gfx::Vector2d(),
542 expected_no_scroll_layer_
->scroll_offset());
544 switch (layer_tree_host()->source_frame_number()) {
546 EXPECT_VECTOR_EQ(initial_offset_
,
547 expected_scroll_layer_
->scroll_offset());
551 gfx::ScrollOffsetWithDelta(initial_offset_
, scroll_amount_
),
552 expected_scroll_layer_
->scroll_offset());
554 // Pretend like Javascript updated the scroll position itself.
555 expected_scroll_layer_
->SetScrollOffset(javascript_scroll_
);
558 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_
,
560 expected_scroll_layer_
->scroll_offset());
565 void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) override
{
566 LayerImpl
* root_impl
= impl
->active_tree()->root_layer();
567 FakePictureLayerImpl
* root_scroll_layer_impl
=
568 static_cast<FakePictureLayerImpl
*>(root_impl
->children()[0]);
569 FakePictureLayerImpl
* child_layer_impl
= static_cast<FakePictureLayerImpl
*>(
570 root_scroll_layer_impl
->children()[0]);
572 LayerImpl
* expected_scroll_layer_impl
= NULL
;
573 LayerImpl
* expected_no_scroll_layer_impl
= NULL
;
574 if (scroll_child_layer_
) {
575 expected_scroll_layer_impl
= child_layer_impl
;
576 expected_no_scroll_layer_impl
= root_scroll_layer_impl
;
578 expected_scroll_layer_impl
= root_scroll_layer_impl
;
579 expected_no_scroll_layer_impl
= child_layer_impl
;
582 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl
->ScrollDelta());
583 EXPECT_VECTOR_EQ(gfx::Vector2d(),
584 expected_no_scroll_layer_impl
->ScrollDelta());
586 // Ensure device scale factor matches the active tree.
587 EXPECT_EQ(device_scale_factor_
, impl
->active_tree()->device_scale_factor());
588 switch (impl
->active_tree()->source_frame_number()) {
590 // GESTURE 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::GESTURE
);
595 EXPECT_EQ(InputHandler::SCROLL_STARTED
, status
);
596 impl
->ScrollBy(gfx::Point(), scroll_amount_
);
599 // Check the scroll is applied as a delta.
600 EXPECT_VECTOR_EQ(initial_offset_
,
601 expected_scroll_layer_impl
->BaseScrollOffset());
602 EXPECT_VECTOR_EQ(scroll_amount_
,
603 expected_scroll_layer_impl
->ScrollDelta());
607 // WHEEL scroll on impl thread.
608 InputHandler::ScrollStatus status
= impl
->ScrollBegin(
609 gfx::ToCeiledPoint(expected_scroll_layer_impl
->position() +
610 gfx::Vector2dF(0.5f
, 0.5f
)),
611 InputHandler::WHEEL
);
612 EXPECT_EQ(InputHandler::SCROLL_STARTED
, status
);
613 impl
->ScrollBy(gfx::Point(), scroll_amount_
);
616 // Check the scroll is applied as a delta.
617 EXPECT_VECTOR_EQ(javascript_scroll_
,
618 expected_scroll_layer_impl
->BaseScrollOffset());
619 EXPECT_VECTOR_EQ(scroll_amount_
,
620 expected_scroll_layer_impl
->ScrollDelta());
626 gfx::ScrollOffsetWithDelta(javascript_scroll_
, scroll_amount_
),
627 expected_scroll_layer_impl
->BaseScrollOffset());
628 EXPECT_VECTOR_EQ(gfx::Vector2d(),
629 expected_scroll_layer_impl
->ScrollDelta());
636 void AfterTest() override
{
637 if (scroll_child_layer_
) {
638 EXPECT_EQ(0, num_scrolls_
);
639 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_
,
641 final_scroll_offset_
);
643 EXPECT_EQ(2, num_scrolls_
);
644 EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_
);
649 float device_scale_factor_
;
650 bool scroll_child_layer_
;
652 gfx::ScrollOffset initial_offset_
;
653 gfx::ScrollOffset javascript_scroll_
;
654 gfx::Vector2d scroll_amount_
;
656 gfx::ScrollOffset final_scroll_offset_
;
658 FakeContentLayerClient fake_content_layer_client_
;
660 scoped_refptr
<Layer
> root_scroll_layer_
;
661 scoped_refptr
<Layer
> child_layer_
;
662 scoped_refptr
<Layer
> expected_scroll_layer_
;
663 scoped_refptr
<Layer
> expected_no_scroll_layer_
;
666 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
667 DeviceScaleFactor1_ScrollChild_DirectRenderer
) {
668 device_scale_factor_
= 1.f
;
669 scroll_child_layer_
= true;
670 RunTest(true, false, true);
673 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
674 DeviceScaleFactor1_ScrollChild_DelegatingRenderer
) {
675 device_scale_factor_
= 1.f
;
676 scroll_child_layer_
= true;
677 RunTest(true, true, true);
680 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
681 DeviceScaleFactor15_ScrollChild_DirectRenderer
) {
682 device_scale_factor_
= 1.5f
;
683 scroll_child_layer_
= true;
684 RunTest(true, false, true);
687 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
688 DeviceScaleFactor15_ScrollChild_DelegatingRenderer
) {
689 device_scale_factor_
= 1.5f
;
690 scroll_child_layer_
= true;
691 RunTest(true, true, true);
694 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
695 DeviceScaleFactor2_ScrollChild_DirectRenderer
) {
696 device_scale_factor_
= 2.f
;
697 scroll_child_layer_
= true;
698 RunTest(true, false, true);
701 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
702 DeviceScaleFactor2_ScrollChild_DelegatingRenderer
) {
703 device_scale_factor_
= 2.f
;
704 scroll_child_layer_
= true;
705 RunTest(true, true, true);
708 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
709 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer
) {
710 device_scale_factor_
= 1.f
;
711 scroll_child_layer_
= false;
712 RunTest(true, false, true);
715 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
716 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer
) {
717 device_scale_factor_
= 1.f
;
718 scroll_child_layer_
= false;
719 RunTest(true, true, true);
722 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
723 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer
) {
724 device_scale_factor_
= 1.5f
;
725 scroll_child_layer_
= false;
726 RunTest(true, false, true);
729 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
730 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer
) {
731 device_scale_factor_
= 1.5f
;
732 scroll_child_layer_
= false;
733 RunTest(true, true, true);
736 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
737 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer
) {
738 device_scale_factor_
= 2.f
;
739 scroll_child_layer_
= false;
740 RunTest(true, false, true);
743 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
744 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer
) {
745 device_scale_factor_
= 2.f
;
746 scroll_child_layer_
= false;
747 RunTest(true, true, true);
750 class ImplSidePaintingScrollTest
: public LayerTreeHostScrollTest
{
752 void InitializeSettings(LayerTreeSettings
* settings
) override
{
753 settings
->impl_side_painting
= true;
756 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
757 if (impl
->pending_tree())
758 impl
->SetNeedsRedraw();
762 class ImplSidePaintingScrollTestSimple
: public ImplSidePaintingScrollTest
{
764 ImplSidePaintingScrollTestSimple()
765 : initial_scroll_(10, 20),
766 main_thread_scroll_(40, 5),
767 impl_thread_scroll1_(2, -1),
768 impl_thread_scroll2_(-3, 10),
771 void SetupTree() override
{
772 LayerTreeHostScrollTest::SetupTree();
773 Layer
* root_layer
= layer_tree_host()->root_layer();
774 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
775 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
776 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
777 root_scroll_layer
->SetBounds(
778 gfx::Size(root_layer
->bounds().width() + 100,
779 root_layer
->bounds().height() + 100));
780 root_scroll_layer
->SetIsDrawable(true);
781 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
782 root_layer
->AddChild(root_scroll_layer
);
784 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
785 root_scroll_layer
, NULL
);
786 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
789 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
791 void Layout() override
{
792 Layer
* root
= layer_tree_host()->root_layer();
793 Layer
* scroll_layer
= root
->children()[0].get();
794 if (!layer_tree_host()->source_frame_number()) {
795 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
798 scroll_layer
->scroll_offset(),
799 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_thread_scroll1_
));
801 // Pretend like Javascript updated the scroll position itself with a
802 // change of main_thread_scroll.
803 scroll_layer
->SetScrollOffset(
804 gfx::ScrollOffsetWithDelta(
805 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
809 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
810 // We force a second draw here of the first commit before activating
811 // the second commit.
812 if (impl
->active_tree()->source_frame_number() == 0)
813 impl
->SetNeedsRedraw();
816 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
817 ImplSidePaintingScrollTest::DrawLayersOnThread(impl
);
819 LayerImpl
* root
= impl
->active_tree()->root_layer();
820 LayerImpl
* scroll_layer
= root
->children()[0];
821 LayerImpl
* pending_root
=
822 impl
->active_tree()->FindPendingTreeLayerById(root
->id());
824 switch (impl
->active_tree()->source_frame_number()) {
826 if (!impl
->pending_tree()) {
827 impl
->BlockNotifyReadyToActivateForTesting(true);
828 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
829 scroll_layer
->ScrollBy(impl_thread_scroll1_
);
831 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
832 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll1_
);
833 PostSetNeedsCommitToMainThread();
835 // CommitCompleteOnThread will trigger this function again
836 // and cause us to take the else clause.
838 impl
->BlockNotifyReadyToActivateForTesting(false);
839 ASSERT_TRUE(pending_root
);
840 EXPECT_EQ(impl
->pending_tree()->source_frame_number(), 1);
842 scroll_layer
->ScrollBy(impl_thread_scroll2_
);
843 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
844 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
845 impl_thread_scroll1_
+ impl_thread_scroll2_
);
847 LayerImpl
* pending_scroll_layer
= pending_root
->children()[0];
849 pending_scroll_layer
->BaseScrollOffset(),
850 gfx::ScrollOffsetWithDelta(
851 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
852 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(),
853 impl_thread_scroll2_
);
857 EXPECT_FALSE(impl
->pending_tree());
859 scroll_layer
->BaseScrollOffset(),
860 gfx::ScrollOffsetWithDelta(
861 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
862 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll2_
);
868 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
870 float top_controls_delta
) override
{
874 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
877 gfx::ScrollOffset initial_scroll_
;
878 gfx::Vector2dF main_thread_scroll_
;
879 gfx::Vector2dF impl_thread_scroll1_
;
880 gfx::Vector2dF impl_thread_scroll2_
;
884 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple
);
886 // This test makes sure that layers pick up scrolls that occur between
887 // beginning a commit and finishing a commit (aka scroll deltas not
888 // included in sent scroll delta) still apply to layers that don't
890 class ImplSidePaintingScrollTestImplOnlyScroll
891 : public ImplSidePaintingScrollTest
{
893 ImplSidePaintingScrollTestImplOnlyScroll()
894 : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3), impl_scale_(2.f
) {}
896 void SetupTree() override
{
897 LayerTreeHostScrollTest::SetupTree();
898 Layer
* root_layer
= layer_tree_host()->root_layer();
899 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
900 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
901 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
902 root_scroll_layer
->SetBounds(
903 gfx::Size(root_layer
->bounds().width() + 100,
904 root_layer
->bounds().height() + 100));
905 root_scroll_layer
->SetIsDrawable(true);
906 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
907 root_layer
->AddChild(root_scroll_layer
);
909 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
910 root_scroll_layer
, NULL
);
911 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
914 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
916 void WillCommit() override
{
917 Layer
* root
= layer_tree_host()->root_layer();
918 Layer
* scroll_layer
= root
->children()[0].get();
919 switch (layer_tree_host()->source_frame_number()) {
921 EXPECT_TRUE(scroll_layer
->needs_push_properties());
924 // Even if this layer doesn't need push properties, it should
925 // still pick up scrolls that happen on the active layer during
927 EXPECT_FALSE(scroll_layer
->needs_push_properties());
932 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
933 // Scroll after the 2nd commit has started.
934 if (impl
->active_tree()->source_frame_number() == 0) {
935 LayerImpl
* active_root
= impl
->active_tree()->root_layer();
936 LayerImpl
* active_scroll_layer
= active_root
->children()[0];
937 ASSERT_TRUE(active_root
);
938 ASSERT_TRUE(active_scroll_layer
);
939 active_scroll_layer
->ScrollBy(impl_thread_scroll_
);
940 impl
->SetPageScaleOnActiveTree(impl_scale_
);
944 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
945 // We force a second draw here of the first commit before activating
946 // the second commit.
947 LayerImpl
* active_root
= impl
->active_tree()->root_layer();
948 LayerImpl
* active_scroll_layer
=
949 active_root
? active_root
->children()[0] : NULL
;
950 LayerImpl
* pending_root
= impl
->pending_tree()->root_layer();
951 LayerImpl
* pending_scroll_layer
= pending_root
->children()[0];
953 ASSERT_TRUE(pending_root
);
954 ASSERT_TRUE(pending_scroll_layer
);
955 switch (impl
->pending_tree()->source_frame_number()) {
957 EXPECT_VECTOR_EQ(pending_scroll_layer
->BaseScrollOffset(),
959 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(), gfx::Vector2d());
960 EXPECT_FALSE(active_root
);
963 // Even though the scroll happened during the commit, both layers
964 // should have the appropriate scroll delta.
965 EXPECT_VECTOR_EQ(pending_scroll_layer
->BaseScrollOffset(),
967 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(),
968 impl_thread_scroll_
);
969 ASSERT_TRUE(active_root
);
970 EXPECT_VECTOR_EQ(active_scroll_layer
->BaseScrollOffset(),
972 EXPECT_VECTOR_EQ(active_scroll_layer
->ScrollDelta(),
973 impl_thread_scroll_
);
976 // On the next commit, this delta should have been sent and applied.
978 pending_scroll_layer
->BaseScrollOffset(),
979 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_thread_scroll_
));
980 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(), gfx::Vector2d());
985 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
986 ImplSidePaintingScrollTest::DrawLayersOnThread(impl
);
988 LayerImpl
* root
= impl
->active_tree()->root_layer();
989 LayerImpl
* scroll_layer
= root
->children()[0];
991 switch (impl
->active_tree()->source_frame_number()) {
993 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
994 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
995 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
996 EXPECT_EQ(1.f
, impl
->active_tree()->current_page_scale_factor());
997 PostSetNeedsCommitToMainThread();
1000 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
1001 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll_
);
1002 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
1003 EXPECT_EQ(impl_scale_
,
1004 impl
->active_tree()->current_page_scale_factor());
1005 PostSetNeedsCommitToMainThread();
1008 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
1009 EXPECT_EQ(impl_scale_
,
1010 impl
->active_tree()->current_page_scale_factor());
1016 void AfterTest() override
{}
1019 gfx::ScrollOffset initial_scroll_
;
1020 gfx::Vector2dF impl_thread_scroll_
;
1024 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll
);
1026 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
1027 : public LayerTreeHostScrollTest
{
1029 LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
1031 void SetupTree() override
{
1032 LayerTreeTest::SetupTree();
1033 scoped_refptr
<Layer
> scroll_layer
= Layer::Create();
1034 layer_tree_host()->root_layer()->AddChild(scroll_layer
);
1037 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1039 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
1040 LayerImpl
* root
= impl
->active_tree()->root_layer();
1041 LayerImpl
* scroll_layer
= root
->children()[0];
1042 scroll_layer
->SetScrollClipLayer(root
->id());
1044 // Set max_scroll_offset = (100, 100).
1045 scroll_layer
->SetBounds(
1046 gfx::Size(root
->bounds().width() + 100, root
->bounds().height() + 100));
1048 InputHandler::SCROLL_STARTED
,
1049 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
), InputHandler::GESTURE
,
1050 SCROLL_BLOCKS_ON_NONE
));
1052 // Set max_scroll_offset = (0, 0).
1053 scroll_layer
->SetBounds(root
->bounds());
1055 InputHandler::SCROLL_IGNORED
,
1056 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
), InputHandler::GESTURE
,
1057 SCROLL_BLOCKS_ON_NONE
));
1059 // Set max_scroll_offset = (-100, -100).
1060 scroll_layer
->SetBounds(gfx::Size());
1062 InputHandler::SCROLL_IGNORED
,
1063 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
), InputHandler::GESTURE
,
1064 SCROLL_BLOCKS_ON_NONE
));
1069 void AfterTest() override
{}
1072 SINGLE_AND_MULTI_THREAD_TEST_F(
1073 LayerTreeHostScrollTestScrollZeroMaxScrollOffset
);
1075 class ThreadCheckingInputHandlerClient
: public InputHandlerClient
{
1077 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner
* runner
,
1078 bool* received_stop_flinging
)
1079 : task_runner_(runner
), received_stop_flinging_(received_stop_flinging
) {}
1081 void WillShutdown() override
{
1082 if (!received_stop_flinging_
)
1083 ADD_FAILURE() << "WillShutdown() called before fling stopped";
1086 void Animate(base::TimeTicks time
) override
{
1087 if (!task_runner_
->BelongsToCurrentThread())
1088 ADD_FAILURE() << "Animate called on wrong thread";
1091 void MainThreadHasStoppedFlinging() override
{
1092 if (!task_runner_
->BelongsToCurrentThread())
1093 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
1094 *received_stop_flinging_
= true;
1097 void ReconcileElasticOverscrollAndRootScroll() override
{
1098 if (!task_runner_
->BelongsToCurrentThread()) {
1099 ADD_FAILURE() << "ReconcileElasticOverscrollAndRootScroll called on "
1105 base::SingleThreadTaskRunner
* task_runner_
;
1106 bool* received_stop_flinging_
;
1109 void BindInputHandlerOnCompositorThread(
1110 const base::WeakPtr
<InputHandler
>& input_handler
,
1111 ThreadCheckingInputHandlerClient
* client
) {
1112 input_handler
->BindToClient(client
);
1115 TEST(LayerTreeHostFlingTest
, DidStopFlingingThread
) {
1116 base::Thread
impl_thread("cc");
1117 ASSERT_TRUE(impl_thread
.Start());
1119 bool received_stop_flinging
= false;
1120 LayerTreeSettings settings
;
1122 ThreadCheckingInputHandlerClient
input_handler_client(
1123 impl_thread
.message_loop_proxy().get(), &received_stop_flinging
);
1124 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1126 ASSERT_TRUE(impl_thread
.message_loop_proxy().get());
1127 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1128 new TestSharedBitmapManager());
1129 scoped_ptr
<LayerTreeHost
> layer_tree_host
= LayerTreeHost::CreateThreaded(
1130 &client
, shared_bitmap_manager
.get(), NULL
, NULL
, settings
,
1131 base::MessageLoopProxy::current(), impl_thread
.message_loop_proxy(),
1134 impl_thread
.message_loop_proxy()
1135 ->PostTask(FROM_HERE
,
1136 base::Bind(&BindInputHandlerOnCompositorThread
,
1137 layer_tree_host
->GetInputHandler(),
1138 base::Unretained(&input_handler_client
)));
1140 layer_tree_host
->DidStopFlinging();
1141 layer_tree_host
= nullptr;
1143 EXPECT_TRUE(received_stop_flinging
);
1146 class LayerTreeHostScrollTestLayerStructureChange
1147 : public LayerTreeHostScrollTest
{
1149 LayerTreeHostScrollTestLayerStructureChange()
1150 : scroll_destroy_whole_tree_(false) {}
1152 void SetupTree() override
{
1153 scoped_refptr
<Layer
> root_layer
= Layer::Create();
1154 root_layer
->SetBounds(gfx::Size(10, 10));
1156 Layer
* root_scroll_layer
=
1157 CreateScrollLayer(root_layer
.get(), &root_scroll_layer_client_
);
1158 CreateScrollLayer(root_layer
.get(), &sibling_scroll_layer_client_
);
1159 CreateScrollLayer(root_scroll_layer
, &child_scroll_layer_client_
);
1161 layer_tree_host()->SetRootLayer(root_layer
);
1162 LayerTreeHostScrollTest::SetupTree();
1165 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1167 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
1168 LayerImpl
* root
= impl
->active_tree()->root_layer();
1169 switch (impl
->active_tree()->source_frame_number()) {
1171 root
->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1172 root
->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1173 root
->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5));
1174 PostSetNeedsCommitToMainThread();
1182 void AfterTest() override
{}
1184 virtual void DidScroll(Layer
* layer
) {
1185 if (scroll_destroy_whole_tree_
) {
1186 layer_tree_host()->SetRootLayer(NULL
);
1190 layer
->RemoveFromParent();
1194 class FakeLayerScrollClient
{
1197 owner_
->DidScroll(layer_
);
1199 LayerTreeHostScrollTestLayerStructureChange
* owner_
;
1203 Layer
* CreateScrollLayer(Layer
* parent
, FakeLayerScrollClient
* client
) {
1204 scoped_refptr
<PictureLayer
> scroll_layer
=
1205 PictureLayer::Create(&fake_content_layer_client_
);
1206 scroll_layer
->SetBounds(gfx::Size(110, 110));
1207 scroll_layer
->SetPosition(gfx::Point(0, 0));
1208 scroll_layer
->SetIsDrawable(true);
1209 scroll_layer
->SetScrollClipLayerId(parent
->id());
1210 scroll_layer
->SetBounds(gfx::Size(parent
->bounds().width() + 100,
1211 parent
->bounds().height() + 100));
1212 scroll_layer
->set_did_scroll_callback(base::Bind(
1213 &FakeLayerScrollClient::DidScroll
, base::Unretained(client
)));
1214 client
->owner_
= this;
1215 client
->layer_
= scroll_layer
.get();
1216 parent
->AddChild(scroll_layer
);
1217 return scroll_layer
.get();
1220 FakeLayerScrollClient root_scroll_layer_client_
;
1221 FakeLayerScrollClient sibling_scroll_layer_client_
;
1222 FakeLayerScrollClient child_scroll_layer_client_
;
1224 FakeContentLayerClient fake_content_layer_client_
;
1226 bool scroll_destroy_whole_tree_
;
1229 TEST_F(LayerTreeHostScrollTestLayerStructureChange
, ScrollDestroyLayer
) {
1230 RunTest(true, false, true);
1233 TEST_F(LayerTreeHostScrollTestLayerStructureChange
, ScrollDestroyWholeTree
) {
1234 scroll_destroy_whole_tree_
= true;
1235 RunTest(true, false, true);