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/geometry/point_conversions.h"
20 #include "ui/gfx/geometry/size_conversions.h"
21 #include "ui/gfx/geometry/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 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 void Layout() override
{
52 Layer
* root
= layer_tree_host()->root_layer();
53 Layer
* scroll_layer
= root
->children()[0].get();
54 if (!layer_tree_host()->source_frame_number()) {
55 EXPECT_VECTOR_EQ(initial_scroll_
, scroll_layer
->scroll_offset());
57 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_
,
59 scroll_layer
->scroll_offset());
61 // Pretend like Javascript updated the scroll position itself.
62 scroll_layer
->SetScrollOffset(second_scroll_
);
66 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
67 LayerImpl
* root
= impl
->active_tree()->root_layer();
68 LayerImpl
* scroll_layer
= root
->children()[0];
69 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer
->ScrollDelta());
71 scroll_layer
->SetScrollClipLayer(root
->id());
72 scroll_layer
->SetBounds(
73 gfx::Size(root
->bounds().width() + 100, root
->bounds().height() + 100));
74 scroll_layer
->ScrollBy(scroll_amount_
);
76 switch (impl
->active_tree()->source_frame_number()) {
78 EXPECT_VECTOR_EQ(initial_scroll_
, scroll_layer
->scroll_offset());
79 EXPECT_VECTOR_EQ(scroll_amount_
, scroll_layer
->ScrollDelta());
80 PostSetNeedsCommitToMainThread();
83 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), second_scroll_
);
84 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
90 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
92 float top_controls_delta
) override
{
96 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
99 gfx::ScrollOffset initial_scroll_
;
100 gfx::ScrollOffset second_scroll_
;
101 gfx::Vector2dF scroll_amount_
;
105 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple
);
107 class LayerTreeHostScrollTestScrollMultipleRedraw
108 : public LayerTreeHostScrollTest
{
110 LayerTreeHostScrollTestScrollMultipleRedraw()
111 : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
113 void BeginTest() override
{
114 Layer
* root_layer
= layer_tree_host()->root_layer();
115 scroll_layer_
= Layer::Create();
116 root_layer
->AddChild(scroll_layer_
);
117 // Create an effective max_scroll_offset of (100, 100).
118 scroll_layer_
->SetBounds(gfx::Size(root_layer
->bounds().width() + 100,
119 root_layer
->bounds().height() + 100));
120 scroll_layer_
->SetIsDrawable(true);
121 scroll_layer_
->SetIsContainerForFixedPositionLayers(true);
122 scroll_layer_
->SetScrollClipLayerId(root_layer
->id());
123 scroll_layer_
->SetScrollOffset(initial_scroll_
);
124 layer_tree_host()->RegisterViewportLayers(root_layer
, scroll_layer_
, NULL
);
125 PostSetNeedsCommitToMainThread();
128 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
129 switch (layer_tree_host()->source_frame_number()) {
131 EXPECT_VECTOR_EQ(scroll_layer_
->scroll_offset(), initial_scroll_
);
135 scroll_layer_
->scroll_offset(),
136 gfx::ScrollOffsetWithDelta(initial_scroll_
,
137 scroll_amount_
+ scroll_amount_
));
140 scroll_layer_
->scroll_offset(),
141 gfx::ScrollOffsetWithDelta(initial_scroll_
,
142 scroll_amount_
+ scroll_amount_
));
147 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
148 LayerImpl
* scroll_layer
=
149 impl
->active_tree()->LayerById(scroll_layer_
->id());
150 if (impl
->active_tree()->source_frame_number() == 0 &&
151 impl
->SourceAnimationFrameNumber() == 1) {
152 // First draw after first commit.
153 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
154 scroll_layer
->ScrollBy(scroll_amount_
);
155 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
157 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
158 PostSetNeedsRedrawToMainThread();
159 } else if (impl
->active_tree()->source_frame_number() == 0 &&
160 impl
->SourceAnimationFrameNumber() == 2) {
161 // Second draw after first commit.
162 EXPECT_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
163 scroll_layer
->ScrollBy(scroll_amount_
);
164 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
165 scroll_amount_
+ scroll_amount_
);
167 EXPECT_VECTOR_EQ(scroll_layer_
->scroll_offset(), initial_scroll_
);
168 PostSetNeedsCommitToMainThread();
169 } else if (impl
->active_tree()->source_frame_number() == 1) {
170 // Third or later draw after second commit.
171 EXPECT_GE(impl
->SourceAnimationFrameNumber(), 3);
172 EXPECT_VECTOR_EQ(scroll_layer_
->ScrollDelta(), gfx::Vector2d());
174 scroll_layer_
->scroll_offset(),
175 gfx::ScrollOffsetWithDelta(initial_scroll_
,
176 scroll_amount_
+ scroll_amount_
));
181 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
183 float top_controls_delta
) override
{
187 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
190 gfx::ScrollOffset initial_scroll_
;
191 gfx::Vector2dF scroll_amount_
;
193 scoped_refptr
<Layer
> scroll_layer_
;
196 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw
);
198 class LayerTreeHostScrollTestScrollAbortedCommit
199 : public LayerTreeHostScrollTest
{
201 LayerTreeHostScrollTestScrollAbortedCommit()
202 : initial_scroll_(50, 60),
204 second_main_scroll_(14, -3),
206 num_will_begin_main_frames_(0),
207 num_did_begin_main_frames_(0),
208 num_will_commits_(0),
210 num_impl_commits_(0),
211 num_impl_scrolls_(0) {}
213 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
215 void SetupTree() override
{
216 LayerTreeHostScrollTest::SetupTree();
217 Layer
* root_layer
= layer_tree_host()->root_layer();
218 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
219 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
220 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
221 root_scroll_layer
->SetBounds(gfx::Size(200, 200));
222 root_scroll_layer
->SetIsDrawable(true);
223 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
224 root_layer
->AddChild(root_scroll_layer
);
226 layer_tree_host()->RegisterViewportLayers(
227 root_layer
, root_scroll_layer
, NULL
);
228 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
231 void WillBeginMainFrame() override
{
232 num_will_begin_main_frames_
++;
233 Layer
* root_scroll_layer
=
234 layer_tree_host()->root_layer()->children()[0].get();
235 switch (num_will_begin_main_frames_
) {
237 // This will not be aborted because of the initial prop changes.
238 EXPECT_EQ(0, num_impl_scrolls_
);
239 EXPECT_EQ(0, layer_tree_host()->source_frame_number());
240 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(), initial_scroll_
);
241 EXPECT_EQ(1.f
, layer_tree_host()->page_scale_factor());
244 // This commit will be aborted, and another commit will be
245 // initiated from the redraw.
246 EXPECT_EQ(1, num_impl_scrolls_
);
247 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
249 root_scroll_layer
->scroll_offset(),
250 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_scroll_
));
251 EXPECT_EQ(impl_scale_
, layer_tree_host()->page_scale_factor());
252 PostSetNeedsRedrawToMainThread();
255 // This commit will not be aborted because of the scroll change.
256 EXPECT_EQ(2, num_impl_scrolls_
);
257 // The source frame number still increases even with the abort.
258 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
260 root_scroll_layer
->scroll_offset(),
261 gfx::ScrollOffsetWithDelta(initial_scroll_
,
262 impl_scroll_
+ impl_scroll_
));
263 EXPECT_EQ(impl_scale_
* impl_scale_
,
264 layer_tree_host()->page_scale_factor());
265 root_scroll_layer
->SetScrollOffset(gfx::ScrollOffsetWithDelta(
266 root_scroll_layer
->scroll_offset(), second_main_scroll_
));
269 // This commit will also be aborted.
270 EXPECT_EQ(3, num_impl_scrolls_
);
271 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
272 gfx::Vector2dF delta
=
273 impl_scroll_
+ impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
274 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
275 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
277 // End the test by drawing to verify this commit is also aborted.
278 PostSetNeedsRedrawToMainThread();
283 void DidBeginMainFrame() override
{ num_did_begin_main_frames_
++; }
285 void WillCommit() override
{ num_will_commits_
++; }
287 void DidCommit() override
{ num_did_commits_
++; }
289 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
293 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
294 LayerImpl
* root_scroll_layer
=
295 impl
->active_tree()->root_layer()->children()[0];
297 if (impl
->active_tree()->source_frame_number() == 0 &&
298 impl
->SourceAnimationFrameNumber() == 1) {
300 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
301 root_scroll_layer
->ScrollBy(impl_scroll_
);
302 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
303 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(), initial_scroll_
);
305 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
306 EXPECT_EQ(1.f
, impl
->active_tree()->total_page_scale_factor());
307 impl
->active_tree()->SetPageScaleDelta(impl_scale_
);
308 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
309 EXPECT_EQ(impl_scale_
, impl
->active_tree()->total_page_scale_factor());
311 // To simplify the testing flow, don't redraw here, just commit.
312 impl
->SetNeedsCommit();
313 } else if (impl
->active_tree()->source_frame_number() == 0 &&
314 impl
->SourceAnimationFrameNumber() == 2) {
315 // Test a second draw after an aborted commit.
316 // The scroll/scale values should be baked into the offset/scale factor
317 // since the main thread consumed but aborted the begin frame.
318 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
319 root_scroll_layer
->ScrollBy(impl_scroll_
);
320 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
322 root_scroll_layer
->scroll_offset(),
323 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_scroll_
));
325 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
326 EXPECT_EQ(impl_scale_
, impl
->active_tree()->total_page_scale_factor());
327 impl
->active_tree()->SetPageScaleDelta(impl_scale_
);
328 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
329 EXPECT_EQ(impl_scale_
* impl_scale_
,
330 impl
->active_tree()->total_page_scale_factor());
332 impl
->SetNeedsCommit();
333 } else if (impl
->active_tree()->source_frame_number() == 1) {
334 // Commit for source frame 1 is aborted.
336 } else if (impl
->active_tree()->source_frame_number() == 2 &&
337 impl
->SourceAnimationFrameNumber() == 3) {
338 // Third draw after the second full commit.
339 EXPECT_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
340 root_scroll_layer
->ScrollBy(impl_scroll_
);
341 impl
->SetNeedsCommit();
342 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
343 gfx::Vector2dF delta
= impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
344 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
345 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
346 } else if (impl
->active_tree()->source_frame_number() == 2 &&
347 impl
->SourceAnimationFrameNumber() == 4) {
348 // Final draw after the second aborted commit.
349 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
350 gfx::Vector2dF delta
=
351 impl_scroll_
+ impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
352 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
353 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
356 // Commit for source frame 3 is aborted.
361 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
363 float top_controls_delta
) override
{
367 void AfterTest() override
{
368 EXPECT_EQ(3, num_impl_scrolls_
);
369 // Verify that the embedder sees aborted commits as real commits.
370 EXPECT_EQ(4, num_will_begin_main_frames_
);
371 EXPECT_EQ(4, num_did_begin_main_frames_
);
372 EXPECT_EQ(4, num_will_commits_
);
373 EXPECT_EQ(4, num_did_commits_
);
374 // ...but the compositor thread only sees two real ones.
375 EXPECT_EQ(2, num_impl_commits_
);
379 gfx::ScrollOffset initial_scroll_
;
380 gfx::Vector2dF impl_scroll_
;
381 gfx::Vector2dF second_main_scroll_
;
383 int num_will_begin_main_frames_
;
384 int num_did_begin_main_frames_
;
385 int num_will_commits_
;
386 int num_did_commits_
;
387 int num_impl_commits_
;
388 int num_impl_scrolls_
;
391 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit
);
393 class LayerTreeHostScrollTestFractionalScroll
: public LayerTreeHostScrollTest
{
395 LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
397 void SetupTree() override
{
398 LayerTreeHostScrollTest::SetupTree();
399 Layer
* root_layer
= layer_tree_host()->root_layer();
400 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
401 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
402 root_scroll_layer
->SetBounds(
403 gfx::Size(root_layer
->bounds().width() + 100,
404 root_layer
->bounds().height() + 100));
405 root_scroll_layer
->SetIsDrawable(true);
406 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
407 root_layer
->AddChild(root_scroll_layer
);
409 layer_tree_host()->RegisterViewportLayers(
410 root_layer
, root_scroll_layer
, NULL
);
411 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
414 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
416 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
417 LayerImpl
* root
= impl
->active_tree()->root_layer();
418 LayerImpl
* scroll_layer
= root
->children()[0];
420 // Check that a fractional scroll delta is correctly accumulated over
422 switch (impl
->active_tree()->source_frame_number()) {
424 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), gfx::Vector2d(0, 0));
425 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d(0, 0));
426 PostSetNeedsCommitToMainThread();
429 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(),
430 gfx::ToFlooredVector2d(scroll_amount_
));
431 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
432 gfx::Vector2dF(fmod(scroll_amount_
.x(), 1.0f
), 0.0f
));
433 PostSetNeedsCommitToMainThread();
437 scroll_layer
->scroll_offset(),
438 gfx::ToFlooredVector2d(scroll_amount_
+ scroll_amount_
));
440 scroll_layer
->ScrollDelta(),
441 gfx::Vector2dF(fmod(2.0f
* scroll_amount_
.x(), 1.0f
), 0.0f
));
445 scroll_layer
->ScrollBy(scroll_amount_
);
448 void AfterTest() override
{}
451 gfx::Vector2dF scroll_amount_
;
454 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll
);
456 class LayerTreeHostScrollTestCaseWithChild
: public LayerTreeHostScrollTest
{
458 LayerTreeHostScrollTestCaseWithChild()
459 : initial_offset_(10, 20),
460 javascript_scroll_(40, 5),
461 scroll_amount_(2, -1),
464 void SetupTree() override
{
465 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_
);
467 scoped_refptr
<Layer
> root_layer
= Layer::Create();
468 root_layer
->SetBounds(gfx::Size(10, 10));
470 root_scroll_layer_
= FakePictureLayer::Create(&fake_content_layer_client_
);
471 root_scroll_layer_
->SetBounds(gfx::Size(110, 110));
473 root_scroll_layer_
->SetPosition(gfx::Point());
475 root_scroll_layer_
->SetIsDrawable(true);
476 root_scroll_layer_
->SetScrollClipLayerId(root_layer
->id());
477 root_scroll_layer_
->SetIsContainerForFixedPositionLayers(true);
478 root_layer
->AddChild(root_scroll_layer_
);
480 child_layer_
= FakePictureLayer::Create(&fake_content_layer_client_
);
481 child_layer_
->set_did_scroll_callback(
482 base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll
,
483 base::Unretained(this)));
484 child_layer_
->SetBounds(gfx::Size(110, 110));
486 if (scroll_child_layer_
) {
487 // Scrolls on the child layer will happen at 5, 5. If they are treated
488 // like device pixels, and device scale factor is 2, then they will
489 // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
490 child_layer_
->SetPosition(gfx::Point(5, 5));
492 // Adjust the child layer horizontally so that scrolls will never hit it.
493 child_layer_
->SetPosition(gfx::Point(60, 5));
496 child_layer_
->SetIsDrawable(true);
497 child_layer_
->SetScrollClipLayerId(root_layer
->id());
498 child_layer_
->SetBounds(root_scroll_layer_
->bounds());
499 root_scroll_layer_
->AddChild(child_layer_
);
501 if (scroll_child_layer_
) {
502 expected_scroll_layer_
= child_layer_
;
503 expected_no_scroll_layer_
= root_scroll_layer_
;
505 expected_scroll_layer_
= root_scroll_layer_
;
506 expected_no_scroll_layer_
= child_layer_
;
509 expected_scroll_layer_
->SetScrollOffset(initial_offset_
);
511 layer_tree_host()->SetRootLayer(root_layer
);
512 layer_tree_host()->RegisterViewportLayers(
513 root_layer
, root_scroll_layer_
, NULL
);
514 LayerTreeHostScrollTest::SetupTree();
517 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
519 void WillCommit() override
{
520 // Keep the test committing (otherwise the early out for no update
521 // will stall the test).
522 if (layer_tree_host()->source_frame_number() < 2) {
523 layer_tree_host()->SetNeedsCommit();
528 final_scroll_offset_
= expected_scroll_layer_
->scroll_offset();
531 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
533 float top_controls_delta
) override
{
537 void Layout() override
{
538 EXPECT_VECTOR_EQ(gfx::Vector2d(),
539 expected_no_scroll_layer_
->scroll_offset());
541 switch (layer_tree_host()->source_frame_number()) {
543 EXPECT_VECTOR_EQ(initial_offset_
,
544 expected_scroll_layer_
->scroll_offset());
548 gfx::ScrollOffsetWithDelta(initial_offset_
, scroll_amount_
),
549 expected_scroll_layer_
->scroll_offset());
551 // Pretend like Javascript updated the scroll position itself.
552 expected_scroll_layer_
->SetScrollOffset(javascript_scroll_
);
555 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_
,
557 expected_scroll_layer_
->scroll_offset());
562 void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) override
{
563 LayerImpl
* root_impl
= impl
->active_tree()->root_layer();
564 FakePictureLayerImpl
* root_scroll_layer_impl
=
565 static_cast<FakePictureLayerImpl
*>(root_impl
->children()[0]);
566 FakePictureLayerImpl
* child_layer_impl
= static_cast<FakePictureLayerImpl
*>(
567 root_scroll_layer_impl
->children()[0]);
569 LayerImpl
* expected_scroll_layer_impl
= NULL
;
570 LayerImpl
* expected_no_scroll_layer_impl
= NULL
;
571 if (scroll_child_layer_
) {
572 expected_scroll_layer_impl
= child_layer_impl
;
573 expected_no_scroll_layer_impl
= root_scroll_layer_impl
;
575 expected_scroll_layer_impl
= root_scroll_layer_impl
;
576 expected_no_scroll_layer_impl
= child_layer_impl
;
579 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl
->ScrollDelta());
580 EXPECT_VECTOR_EQ(gfx::Vector2d(),
581 expected_no_scroll_layer_impl
->ScrollDelta());
583 // Ensure device scale factor matches the active tree.
584 EXPECT_EQ(device_scale_factor_
, impl
->active_tree()->device_scale_factor());
585 switch (impl
->active_tree()->source_frame_number()) {
587 // Gesture scroll on impl thread.
588 InputHandler::ScrollStatus status
= impl
->ScrollBegin(
589 gfx::ToCeiledPoint(expected_scroll_layer_impl
->position() -
590 gfx::Vector2dF(0.5f
, 0.5f
)),
591 InputHandler::Gesture
);
592 EXPECT_EQ(InputHandler::ScrollStarted
, status
);
593 impl
->ScrollBy(gfx::Point(), scroll_amount_
);
596 // Check the scroll is applied as a delta.
597 EXPECT_VECTOR_EQ(initial_offset_
,
598 expected_scroll_layer_impl
->scroll_offset());
599 EXPECT_VECTOR_EQ(scroll_amount_
,
600 expected_scroll_layer_impl
->ScrollDelta());
604 // Wheel scroll on impl thread.
605 InputHandler::ScrollStatus status
= impl
->ScrollBegin(
606 gfx::ToCeiledPoint(expected_scroll_layer_impl
->position() +
607 gfx::Vector2dF(0.5f
, 0.5f
)),
608 InputHandler::Wheel
);
609 EXPECT_EQ(InputHandler::ScrollStarted
, status
);
610 impl
->ScrollBy(gfx::Point(), scroll_amount_
);
613 // Check the scroll is applied as a delta.
614 EXPECT_VECTOR_EQ(javascript_scroll_
,
615 expected_scroll_layer_impl
->scroll_offset());
616 EXPECT_VECTOR_EQ(scroll_amount_
,
617 expected_scroll_layer_impl
->ScrollDelta());
622 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_
,
624 expected_scroll_layer_impl
->scroll_offset());
625 EXPECT_VECTOR_EQ(gfx::Vector2d(),
626 expected_scroll_layer_impl
->ScrollDelta());
633 void AfterTest() override
{
634 if (scroll_child_layer_
) {
635 EXPECT_EQ(0, num_scrolls_
);
636 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_
,
638 final_scroll_offset_
);
640 EXPECT_EQ(2, num_scrolls_
);
641 EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_
);
646 float device_scale_factor_
;
647 bool scroll_child_layer_
;
649 gfx::ScrollOffset initial_offset_
;
650 gfx::ScrollOffset javascript_scroll_
;
651 gfx::Vector2d scroll_amount_
;
653 gfx::ScrollOffset final_scroll_offset_
;
655 FakeContentLayerClient fake_content_layer_client_
;
657 scoped_refptr
<Layer
> root_scroll_layer_
;
658 scoped_refptr
<Layer
> child_layer_
;
659 scoped_refptr
<Layer
> expected_scroll_layer_
;
660 scoped_refptr
<Layer
> expected_no_scroll_layer_
;
663 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
664 DeviceScaleFactor1_ScrollChild_DirectRenderer
) {
665 device_scale_factor_
= 1.f
;
666 scroll_child_layer_
= true;
667 RunTest(true, false, true);
670 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
671 DeviceScaleFactor1_ScrollChild_DelegatingRenderer
) {
672 device_scale_factor_
= 1.f
;
673 scroll_child_layer_
= true;
674 RunTest(true, true, true);
677 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
678 DeviceScaleFactor15_ScrollChild_DirectRenderer
) {
679 device_scale_factor_
= 1.5f
;
680 scroll_child_layer_
= true;
681 RunTest(true, false, true);
684 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
685 DeviceScaleFactor15_ScrollChild_DelegatingRenderer
) {
686 device_scale_factor_
= 1.5f
;
687 scroll_child_layer_
= true;
688 RunTest(true, true, true);
691 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
692 DeviceScaleFactor2_ScrollChild_DirectRenderer
) {
693 device_scale_factor_
= 2.f
;
694 scroll_child_layer_
= true;
695 RunTest(true, false, true);
698 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
699 DeviceScaleFactor2_ScrollChild_DelegatingRenderer
) {
700 device_scale_factor_
= 2.f
;
701 scroll_child_layer_
= true;
702 RunTest(true, true, true);
705 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
706 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer
) {
707 device_scale_factor_
= 1.f
;
708 scroll_child_layer_
= false;
709 RunTest(true, false, true);
712 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
713 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer
) {
714 device_scale_factor_
= 1.f
;
715 scroll_child_layer_
= false;
716 RunTest(true, true, true);
719 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
720 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer
) {
721 device_scale_factor_
= 1.5f
;
722 scroll_child_layer_
= false;
723 RunTest(true, false, true);
726 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
727 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer
) {
728 device_scale_factor_
= 1.5f
;
729 scroll_child_layer_
= false;
730 RunTest(true, true, true);
733 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
734 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer
) {
735 device_scale_factor_
= 2.f
;
736 scroll_child_layer_
= false;
737 RunTest(true, false, true);
740 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
741 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer
) {
742 device_scale_factor_
= 2.f
;
743 scroll_child_layer_
= false;
744 RunTest(true, true, true);
747 class ImplSidePaintingScrollTest
: public LayerTreeHostScrollTest
{
749 void InitializeSettings(LayerTreeSettings
* settings
) override
{
750 settings
->impl_side_painting
= true;
753 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
754 if (impl
->pending_tree())
755 impl
->SetNeedsRedraw();
759 class ImplSidePaintingScrollTestSimple
: public ImplSidePaintingScrollTest
{
761 ImplSidePaintingScrollTestSimple()
762 : initial_scroll_(10, 20),
763 main_thread_scroll_(40, 5),
764 impl_thread_scroll1_(2, -1),
765 impl_thread_scroll2_(-3, 10),
768 void SetupTree() override
{
769 LayerTreeHostScrollTest::SetupTree();
770 Layer
* root_layer
= layer_tree_host()->root_layer();
771 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
772 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
773 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
774 root_scroll_layer
->SetBounds(
775 gfx::Size(root_layer
->bounds().width() + 100,
776 root_layer
->bounds().height() + 100));
777 root_scroll_layer
->SetIsDrawable(true);
778 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
779 root_layer
->AddChild(root_scroll_layer
);
781 layer_tree_host()->RegisterViewportLayers(
782 root_layer
, root_scroll_layer
, NULL
);
783 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
786 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
788 void Layout() override
{
789 Layer
* root
= layer_tree_host()->root_layer();
790 Layer
* scroll_layer
= root
->children()[0].get();
791 if (!layer_tree_host()->source_frame_number()) {
792 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
795 scroll_layer
->scroll_offset(),
796 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_thread_scroll1_
));
798 // Pretend like Javascript updated the scroll position itself with a
799 // change of main_thread_scroll.
800 scroll_layer
->SetScrollOffset(
801 gfx::ScrollOffsetWithDelta(
802 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
806 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
807 // We force a second draw here of the first commit before activating
808 // the second commit.
809 if (impl
->active_tree()->source_frame_number() == 0)
810 impl
->SetNeedsRedraw();
813 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
814 ImplSidePaintingScrollTest::DrawLayersOnThread(impl
);
816 LayerImpl
* root
= impl
->active_tree()->root_layer();
817 LayerImpl
* scroll_layer
= root
->children()[0];
818 LayerImpl
* pending_root
=
819 impl
->active_tree()->FindPendingTreeLayerById(root
->id());
821 switch (impl
->active_tree()->source_frame_number()) {
823 if (!impl
->pending_tree()) {
824 impl
->BlockNotifyReadyToActivateForTesting(true);
825 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
826 scroll_layer
->ScrollBy(impl_thread_scroll1_
);
828 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
829 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll1_
);
830 EXPECT_VECTOR_EQ(scroll_layer
->sent_scroll_delta(), gfx::Vector2d());
831 PostSetNeedsCommitToMainThread();
833 // CommitCompleteOnThread will trigger this function again
834 // and cause us to take the else clause.
836 impl
->BlockNotifyReadyToActivateForTesting(false);
837 ASSERT_TRUE(pending_root
);
838 EXPECT_EQ(impl
->pending_tree()->source_frame_number(), 1);
840 scroll_layer
->ScrollBy(impl_thread_scroll2_
);
841 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
842 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
843 impl_thread_scroll1_
+ impl_thread_scroll2_
);
844 EXPECT_VECTOR_EQ(scroll_layer
->sent_scroll_delta(),
845 impl_thread_scroll1_
);
847 LayerImpl
* pending_scroll_layer
= pending_root
->children()[0];
849 pending_scroll_layer
->scroll_offset(),
850 gfx::ScrollOffsetWithDelta(
851 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
852 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(),
853 impl_thread_scroll2_
);
854 EXPECT_VECTOR_EQ(pending_scroll_layer
->sent_scroll_delta(),
859 EXPECT_FALSE(impl
->pending_tree());
861 scroll_layer
->scroll_offset(),
862 gfx::ScrollOffsetWithDelta(
863 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
864 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll2_
);
865 EXPECT_VECTOR_EQ(scroll_layer
->sent_scroll_delta(), gfx::Vector2d());
871 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
873 float top_controls_delta
) override
{
877 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
880 gfx::ScrollOffset initial_scroll_
;
881 gfx::Vector2dF main_thread_scroll_
;
882 gfx::Vector2dF impl_thread_scroll1_
;
883 gfx::Vector2dF impl_thread_scroll2_
;
887 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple
);
889 // This test makes sure that layers pick up scrolls that occur between
890 // beginning a commit and finishing a commit (aka scroll deltas not
891 // included in sent scroll delta) still apply to layers that don't
893 class ImplSidePaintingScrollTestImplOnlyScroll
894 : public ImplSidePaintingScrollTest
{
896 ImplSidePaintingScrollTestImplOnlyScroll()
897 : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3) {}
899 void SetupTree() override
{
900 LayerTreeHostScrollTest::SetupTree();
901 Layer
* root_layer
= layer_tree_host()->root_layer();
902 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
903 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
904 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
905 root_scroll_layer
->SetBounds(
906 gfx::Size(root_layer
->bounds().width() + 100,
907 root_layer
->bounds().height() + 100));
908 root_scroll_layer
->SetIsDrawable(true);
909 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
910 root_layer
->AddChild(root_scroll_layer
);
912 layer_tree_host()->RegisterViewportLayers(
913 root_layer
, root_scroll_layer
, NULL
);
914 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
917 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
919 void WillCommit() override
{
920 Layer
* root
= layer_tree_host()->root_layer();
921 Layer
* scroll_layer
= root
->children()[0].get();
922 switch (layer_tree_host()->source_frame_number()) {
924 EXPECT_TRUE(scroll_layer
->needs_push_properties());
927 // Even if this layer doesn't need push properties, it should
928 // still pick up scrolls that happen on the active layer during
930 EXPECT_FALSE(scroll_layer
->needs_push_properties());
935 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
936 // Scroll after the 2nd commit has started.
937 if (impl
->active_tree()->source_frame_number() == 0) {
938 LayerImpl
* active_root
= impl
->active_tree()->root_layer();
939 LayerImpl
* active_scroll_layer
= active_root
->children()[0];
940 ASSERT_TRUE(active_root
);
941 ASSERT_TRUE(active_scroll_layer
);
942 active_scroll_layer
->ScrollBy(impl_thread_scroll_
);
946 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
947 // We force a second draw here of the first commit before activating
948 // the second commit.
949 LayerImpl
* active_root
= impl
->active_tree()->root_layer();
950 LayerImpl
* active_scroll_layer
=
951 active_root
? active_root
->children()[0] : NULL
;
952 LayerImpl
* pending_root
= impl
->pending_tree()->root_layer();
953 LayerImpl
* pending_scroll_layer
= pending_root
->children()[0];
955 ASSERT_TRUE(pending_root
);
956 ASSERT_TRUE(pending_scroll_layer
);
957 switch (impl
->pending_tree()->source_frame_number()) {
959 EXPECT_VECTOR_EQ(pending_scroll_layer
->scroll_offset(),
961 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(), gfx::Vector2d());
962 EXPECT_VECTOR_EQ(pending_scroll_layer
->sent_scroll_delta(),
964 EXPECT_FALSE(active_root
);
967 // Even though the scroll happened during the commit, both layers
968 // should have the appropriate scroll delta.
969 EXPECT_VECTOR_EQ(pending_scroll_layer
->scroll_offset(),
971 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(),
972 impl_thread_scroll_
);
973 EXPECT_VECTOR_EQ(pending_scroll_layer
->sent_scroll_delta(),
975 ASSERT_TRUE(active_root
);
976 EXPECT_VECTOR_EQ(active_scroll_layer
->scroll_offset(), initial_scroll_
);
977 EXPECT_VECTOR_EQ(active_scroll_layer
->ScrollDelta(),
978 impl_thread_scroll_
);
979 EXPECT_VECTOR_EQ(active_scroll_layer
->sent_scroll_delta(),
983 // On the next commit, this delta should have been sent and applied.
984 EXPECT_VECTOR_EQ(pending_scroll_layer
->scroll_offset(),
985 gfx::ScrollOffsetWithDelta(initial_scroll_
,
986 impl_thread_scroll_
));
987 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(), gfx::Vector2d());
988 EXPECT_VECTOR_EQ(pending_scroll_layer
->sent_scroll_delta(),
995 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
996 ImplSidePaintingScrollTest::DrawLayersOnThread(impl
);
998 LayerImpl
* root
= impl
->active_tree()->root_layer();
999 LayerImpl
* scroll_layer
= root
->children()[0];
1001 switch (impl
->active_tree()->source_frame_number()) {
1003 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
1004 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
1005 EXPECT_VECTOR_EQ(scroll_layer
->sent_scroll_delta(), gfx::Vector2d());
1006 PostSetNeedsCommitToMainThread();
1009 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
1010 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll_
);
1011 EXPECT_VECTOR_EQ(scroll_layer
->sent_scroll_delta(), gfx::Vector2d());
1012 PostSetNeedsCommitToMainThread();
1017 void AfterTest() override
{}
1020 gfx::ScrollOffset initial_scroll_
;
1021 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));
1047 EXPECT_EQ(InputHandler::ScrollStarted
,
1048 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
),
1049 InputHandler::Gesture
));
1051 // Set max_scroll_offset = (0, 0).
1052 scroll_layer
->SetBounds(root
->bounds());
1053 EXPECT_EQ(InputHandler::ScrollIgnored
,
1054 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
),
1055 InputHandler::Gesture
));
1057 // Set max_scroll_offset = (-100, -100).
1058 scroll_layer
->SetBounds(gfx::Size());
1059 EXPECT_EQ(InputHandler::ScrollIgnored
,
1060 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
),
1061 InputHandler::Gesture
));
1066 void AfterTest() override
{}
1069 SINGLE_AND_MULTI_THREAD_TEST_F(
1070 LayerTreeHostScrollTestScrollZeroMaxScrollOffset
);
1072 class ThreadCheckingInputHandlerClient
: public InputHandlerClient
{
1074 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner
* runner
,
1075 bool* received_stop_flinging
)
1076 : task_runner_(runner
), received_stop_flinging_(received_stop_flinging
) {}
1078 void WillShutdown() override
{
1079 if (!received_stop_flinging_
)
1080 ADD_FAILURE() << "WillShutdown() called before fling stopped";
1083 void Animate(base::TimeTicks time
) override
{
1084 if (!task_runner_
->BelongsToCurrentThread())
1085 ADD_FAILURE() << "Animate called on wrong thread";
1088 void MainThreadHasStoppedFlinging() override
{
1089 if (!task_runner_
->BelongsToCurrentThread())
1090 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
1091 *received_stop_flinging_
= true;
1094 void DidOverscroll(const gfx::PointF
& causal_event_viewport_point
,
1095 const gfx::Vector2dF
& accumulated_overscroll
,
1096 const gfx::Vector2dF
& latest_overscroll_delta
) override
{
1097 if (!task_runner_
->BelongsToCurrentThread())
1098 ADD_FAILURE() << "DidOverscroll called on wrong thread";
1102 base::SingleThreadTaskRunner
* task_runner_
;
1103 bool* received_stop_flinging_
;
1106 void BindInputHandlerOnCompositorThread(
1107 const base::WeakPtr
<InputHandler
>& input_handler
,
1108 ThreadCheckingInputHandlerClient
* client
) {
1109 input_handler
->BindToClient(client
);
1112 TEST(LayerTreeHostFlingTest
, DidStopFlingingThread
) {
1113 base::Thread
impl_thread("cc");
1114 ASSERT_TRUE(impl_thread
.Start());
1116 bool received_stop_flinging
= false;
1117 LayerTreeSettings settings
;
1119 ThreadCheckingInputHandlerClient
input_handler_client(
1120 impl_thread
.message_loop_proxy().get(), &received_stop_flinging
);
1121 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1123 ASSERT_TRUE(impl_thread
.message_loop_proxy().get());
1124 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1125 new TestSharedBitmapManager());
1126 scoped_ptr
<LayerTreeHost
> layer_tree_host
=
1127 LayerTreeHost::CreateThreaded(&client
,
1128 shared_bitmap_manager
.get(),
1131 base::MessageLoopProxy::current(),
1132 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);