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(root_layer
, scroll_layer
, NULL
);
49 PostSetNeedsCommitToMainThread();
52 void Layout() override
{
53 Layer
* root
= layer_tree_host()->root_layer();
54 Layer
* scroll_layer
= root
->children()[0].get();
55 if (!layer_tree_host()->source_frame_number()) {
56 EXPECT_VECTOR_EQ(initial_scroll_
, scroll_layer
->scroll_offset());
58 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_
,
60 scroll_layer
->scroll_offset());
62 // Pretend like Javascript updated the scroll position itself.
63 scroll_layer
->SetScrollOffset(second_scroll_
);
67 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
68 LayerImpl
* root
= impl
->active_tree()->root_layer();
69 LayerImpl
* scroll_layer
= root
->children()[0];
70 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer
->ScrollDelta());
72 scroll_layer
->SetScrollClipLayer(root
->id());
73 scroll_layer
->SetBounds(
74 gfx::Size(root
->bounds().width() + 100, root
->bounds().height() + 100));
75 scroll_layer
->ScrollBy(scroll_amount_
);
77 switch (impl
->active_tree()->source_frame_number()) {
79 EXPECT_VECTOR_EQ(initial_scroll_
, scroll_layer
->scroll_offset());
80 EXPECT_VECTOR_EQ(scroll_amount_
, scroll_layer
->ScrollDelta());
81 PostSetNeedsCommitToMainThread();
84 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), second_scroll_
);
85 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
91 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
93 float top_controls_delta
) override
{
97 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
100 gfx::ScrollOffset initial_scroll_
;
101 gfx::ScrollOffset second_scroll_
;
102 gfx::Vector2dF scroll_amount_
;
106 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple
);
108 class LayerTreeHostScrollTestScrollMultipleRedraw
109 : public LayerTreeHostScrollTest
{
111 LayerTreeHostScrollTestScrollMultipleRedraw()
112 : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
114 void BeginTest() override
{
115 Layer
* root_layer
= layer_tree_host()->root_layer();
116 scroll_layer_
= Layer::Create();
117 root_layer
->AddChild(scroll_layer_
);
118 // Create an effective max_scroll_offset of (100, 100).
119 scroll_layer_
->SetBounds(gfx::Size(root_layer
->bounds().width() + 100,
120 root_layer
->bounds().height() + 100));
121 scroll_layer_
->SetIsDrawable(true);
122 scroll_layer_
->SetIsContainerForFixedPositionLayers(true);
123 scroll_layer_
->SetScrollClipLayerId(root_layer
->id());
124 scroll_layer_
->SetScrollOffset(initial_scroll_
);
125 layer_tree_host()->RegisterViewportLayers(root_layer
, scroll_layer_
, NULL
);
126 PostSetNeedsCommitToMainThread();
129 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
130 switch (layer_tree_host()->source_frame_number()) {
132 EXPECT_VECTOR_EQ(scroll_layer_
->scroll_offset(), initial_scroll_
);
136 scroll_layer_
->scroll_offset(),
137 gfx::ScrollOffsetWithDelta(initial_scroll_
,
138 scroll_amount_
+ scroll_amount_
));
141 scroll_layer_
->scroll_offset(),
142 gfx::ScrollOffsetWithDelta(initial_scroll_
,
143 scroll_amount_
+ scroll_amount_
));
148 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
149 LayerImpl
* scroll_layer
=
150 impl
->active_tree()->LayerById(scroll_layer_
->id());
151 if (impl
->active_tree()->source_frame_number() == 0 &&
152 impl
->SourceAnimationFrameNumber() == 1) {
153 // First draw after first commit.
154 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
155 scroll_layer
->ScrollBy(scroll_amount_
);
156 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
158 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
159 PostSetNeedsRedrawToMainThread();
160 } else if (impl
->active_tree()->source_frame_number() == 0 &&
161 impl
->SourceAnimationFrameNumber() == 2) {
162 // Second draw after first commit.
163 EXPECT_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
164 scroll_layer
->ScrollBy(scroll_amount_
);
165 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
166 scroll_amount_
+ scroll_amount_
);
168 EXPECT_VECTOR_EQ(scroll_layer_
->scroll_offset(), initial_scroll_
);
169 PostSetNeedsCommitToMainThread();
170 } else if (impl
->active_tree()->source_frame_number() == 1) {
171 // Third or later draw after second commit.
172 EXPECT_GE(impl
->SourceAnimationFrameNumber(), 3);
173 EXPECT_VECTOR_EQ(scroll_layer_
->ScrollDelta(), gfx::Vector2d());
175 scroll_layer_
->scroll_offset(),
176 gfx::ScrollOffsetWithDelta(initial_scroll_
,
177 scroll_amount_
+ scroll_amount_
));
182 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
184 float top_controls_delta
) override
{
188 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
191 gfx::ScrollOffset initial_scroll_
;
192 gfx::Vector2dF scroll_amount_
;
194 scoped_refptr
<Layer
> scroll_layer_
;
197 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw
);
199 class LayerTreeHostScrollTestScrollAbortedCommit
200 : public LayerTreeHostScrollTest
{
202 LayerTreeHostScrollTestScrollAbortedCommit()
203 : initial_scroll_(50, 60),
205 second_main_scroll_(14, -3),
207 num_will_begin_main_frames_(0),
208 num_did_begin_main_frames_(0),
209 num_will_commits_(0),
211 num_impl_commits_(0),
212 num_impl_scrolls_(0) {}
214 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
216 void SetupTree() override
{
217 LayerTreeHostScrollTest::SetupTree();
218 Layer
* root_layer
= layer_tree_host()->root_layer();
219 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
220 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
221 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
222 root_scroll_layer
->SetBounds(gfx::Size(200, 200));
223 root_scroll_layer
->SetIsDrawable(true);
224 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
225 root_layer
->AddChild(root_scroll_layer
);
227 layer_tree_host()->RegisterViewportLayers(
228 root_layer
, root_scroll_layer
, NULL
);
229 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
232 void WillBeginMainFrame() override
{
233 num_will_begin_main_frames_
++;
234 Layer
* root_scroll_layer
=
235 layer_tree_host()->root_layer()->children()[0].get();
236 switch (num_will_begin_main_frames_
) {
238 // This will not be aborted because of the initial prop changes.
239 EXPECT_EQ(0, num_impl_scrolls_
);
240 EXPECT_EQ(0, layer_tree_host()->source_frame_number());
241 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(), initial_scroll_
);
242 EXPECT_EQ(1.f
, layer_tree_host()->page_scale_factor());
245 // This commit will be aborted, and another commit will be
246 // initiated from the redraw.
247 EXPECT_EQ(1, num_impl_scrolls_
);
248 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
250 root_scroll_layer
->scroll_offset(),
251 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_scroll_
));
252 EXPECT_EQ(impl_scale_
, layer_tree_host()->page_scale_factor());
253 PostSetNeedsRedrawToMainThread();
256 // This commit will not be aborted because of the scroll change.
257 EXPECT_EQ(2, num_impl_scrolls_
);
258 // The source frame number still increases even with the abort.
259 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
261 root_scroll_layer
->scroll_offset(),
262 gfx::ScrollOffsetWithDelta(initial_scroll_
,
263 impl_scroll_
+ impl_scroll_
));
264 EXPECT_EQ(impl_scale_
* impl_scale_
,
265 layer_tree_host()->page_scale_factor());
266 root_scroll_layer
->SetScrollOffset(gfx::ScrollOffsetWithDelta(
267 root_scroll_layer
->scroll_offset(), second_main_scroll_
));
270 // This commit will also be aborted.
271 EXPECT_EQ(3, num_impl_scrolls_
);
272 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
273 gfx::Vector2dF delta
=
274 impl_scroll_
+ impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
275 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
276 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
278 // End the test by drawing to verify this commit is also aborted.
279 PostSetNeedsRedrawToMainThread();
284 void DidBeginMainFrame() override
{ num_did_begin_main_frames_
++; }
286 void WillCommit() override
{ num_will_commits_
++; }
288 void DidCommit() override
{ num_did_commits_
++; }
290 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
294 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
295 LayerImpl
* root_scroll_layer
=
296 impl
->active_tree()->root_layer()->children()[0];
298 if (impl
->active_tree()->source_frame_number() == 0 &&
299 impl
->SourceAnimationFrameNumber() == 1) {
301 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
302 root_scroll_layer
->ScrollBy(impl_scroll_
);
303 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
304 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(), initial_scroll_
);
306 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
307 EXPECT_EQ(1.f
, impl
->active_tree()->total_page_scale_factor());
308 impl
->active_tree()->SetPageScaleDelta(impl_scale_
);
309 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
310 EXPECT_EQ(impl_scale_
, impl
->active_tree()->total_page_scale_factor());
312 // To simplify the testing flow, don't redraw here, just commit.
313 impl
->SetNeedsCommit();
314 } else if (impl
->active_tree()->source_frame_number() == 0 &&
315 impl
->SourceAnimationFrameNumber() == 2) {
316 // Test a second draw after an aborted commit.
317 // The scroll/scale values should be baked into the offset/scale factor
318 // since the main thread consumed but aborted the begin frame.
319 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
320 root_scroll_layer
->ScrollBy(impl_scroll_
);
321 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
323 root_scroll_layer
->scroll_offset(),
324 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_scroll_
));
326 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
327 EXPECT_EQ(impl_scale_
, impl
->active_tree()->total_page_scale_factor());
328 impl
->active_tree()->SetPageScaleDelta(impl_scale_
);
329 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
330 EXPECT_EQ(impl_scale_
* impl_scale_
,
331 impl
->active_tree()->total_page_scale_factor());
333 impl
->SetNeedsCommit();
334 } else if (impl
->active_tree()->source_frame_number() == 1) {
335 // Commit for source frame 1 is aborted.
337 } else if (impl
->active_tree()->source_frame_number() == 2 &&
338 impl
->SourceAnimationFrameNumber() == 3) {
339 // Third draw after the second full commit.
340 EXPECT_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
341 root_scroll_layer
->ScrollBy(impl_scroll_
);
342 impl
->SetNeedsCommit();
343 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
344 gfx::Vector2dF delta
= impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
345 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
346 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
347 } else if (impl
->active_tree()->source_frame_number() == 2 &&
348 impl
->SourceAnimationFrameNumber() == 4) {
349 // Final draw after the second aborted commit.
350 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
351 gfx::Vector2dF delta
=
352 impl_scroll_
+ impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
353 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
354 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
357 // Commit for source frame 3 is aborted.
362 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
364 float top_controls_delta
) override
{
368 void AfterTest() override
{
369 EXPECT_EQ(3, num_impl_scrolls_
);
370 // Verify that the embedder sees aborted commits as real commits.
371 EXPECT_EQ(4, num_will_begin_main_frames_
);
372 EXPECT_EQ(4, num_did_begin_main_frames_
);
373 EXPECT_EQ(4, num_will_commits_
);
374 EXPECT_EQ(4, num_did_commits_
);
375 // ...but the compositor thread only sees two real ones.
376 EXPECT_EQ(2, num_impl_commits_
);
380 gfx::ScrollOffset initial_scroll_
;
381 gfx::Vector2dF impl_scroll_
;
382 gfx::Vector2dF second_main_scroll_
;
384 int num_will_begin_main_frames_
;
385 int num_did_begin_main_frames_
;
386 int num_will_commits_
;
387 int num_did_commits_
;
388 int num_impl_commits_
;
389 int num_impl_scrolls_
;
392 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit
);
394 class LayerTreeHostScrollTestFractionalScroll
: public LayerTreeHostScrollTest
{
396 LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
398 void SetupTree() override
{
399 LayerTreeHostScrollTest::SetupTree();
400 Layer
* root_layer
= layer_tree_host()->root_layer();
401 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
402 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
403 root_scroll_layer
->SetBounds(
404 gfx::Size(root_layer
->bounds().width() + 100,
405 root_layer
->bounds().height() + 100));
406 root_scroll_layer
->SetIsDrawable(true);
407 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
408 root_layer
->AddChild(root_scroll_layer
);
410 layer_tree_host()->RegisterViewportLayers(
411 root_layer
, root_scroll_layer
, NULL
);
412 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
415 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
417 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
418 LayerImpl
* root
= impl
->active_tree()->root_layer();
419 LayerImpl
* scroll_layer
= root
->children()[0];
421 // Check that a fractional scroll delta is correctly accumulated over
423 switch (impl
->active_tree()->source_frame_number()) {
425 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), gfx::Vector2d(0, 0));
426 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d(0, 0));
427 PostSetNeedsCommitToMainThread();
430 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(),
431 gfx::ToFlooredVector2d(scroll_amount_
));
432 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
433 gfx::Vector2dF(fmod(scroll_amount_
.x(), 1.0f
), 0.0f
));
434 PostSetNeedsCommitToMainThread();
438 scroll_layer
->scroll_offset(),
439 gfx::ToFlooredVector2d(scroll_amount_
+ scroll_amount_
));
441 scroll_layer
->ScrollDelta(),
442 gfx::Vector2dF(fmod(2.0f
* scroll_amount_
.x(), 1.0f
), 0.0f
));
446 scroll_layer
->ScrollBy(scroll_amount_
);
449 void AfterTest() override
{}
452 gfx::Vector2dF scroll_amount_
;
455 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll
);
457 class LayerTreeHostScrollTestCaseWithChild
: public LayerTreeHostScrollTest
{
459 LayerTreeHostScrollTestCaseWithChild()
460 : initial_offset_(10, 20),
461 javascript_scroll_(40, 5),
462 scroll_amount_(2, -1),
465 void SetupTree() override
{
466 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_
);
468 scoped_refptr
<Layer
> root_layer
= Layer::Create();
469 root_layer
->SetBounds(gfx::Size(10, 10));
471 root_scroll_layer_
= FakePictureLayer::Create(&fake_content_layer_client_
);
472 root_scroll_layer_
->SetBounds(gfx::Size(110, 110));
474 root_scroll_layer_
->SetPosition(gfx::Point());
476 root_scroll_layer_
->SetIsDrawable(true);
477 root_scroll_layer_
->SetScrollClipLayerId(root_layer
->id());
478 root_scroll_layer_
->SetIsContainerForFixedPositionLayers(true);
479 root_layer
->AddChild(root_scroll_layer_
);
481 child_layer_
= FakePictureLayer::Create(&fake_content_layer_client_
);
482 child_layer_
->set_did_scroll_callback(
483 base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll
,
484 base::Unretained(this)));
485 child_layer_
->SetBounds(gfx::Size(110, 110));
487 if (scroll_child_layer_
) {
488 // Scrolls on the child layer will happen at 5, 5. If they are treated
489 // like device pixels, and device scale factor is 2, then they will
490 // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
491 child_layer_
->SetPosition(gfx::Point(5, 5));
493 // Adjust the child layer horizontally so that scrolls will never hit it.
494 child_layer_
->SetPosition(gfx::Point(60, 5));
497 child_layer_
->SetIsDrawable(true);
498 child_layer_
->SetScrollClipLayerId(root_layer
->id());
499 child_layer_
->SetBounds(root_scroll_layer_
->bounds());
500 root_scroll_layer_
->AddChild(child_layer_
);
502 if (scroll_child_layer_
) {
503 expected_scroll_layer_
= child_layer_
;
504 expected_no_scroll_layer_
= root_scroll_layer_
;
506 expected_scroll_layer_
= root_scroll_layer_
;
507 expected_no_scroll_layer_
= child_layer_
;
510 expected_scroll_layer_
->SetScrollOffset(initial_offset_
);
512 layer_tree_host()->SetRootLayer(root_layer
);
513 layer_tree_host()->RegisterViewportLayers(
514 root_layer
, root_scroll_layer_
, NULL
);
515 LayerTreeHostScrollTest::SetupTree();
518 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
520 void WillCommit() override
{
521 // Keep the test committing (otherwise the early out for no update
522 // will stall the test).
523 if (layer_tree_host()->source_frame_number() < 2) {
524 layer_tree_host()->SetNeedsCommit();
529 final_scroll_offset_
= expected_scroll_layer_
->scroll_offset();
532 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
534 float top_controls_delta
) override
{
538 void Layout() override
{
539 EXPECT_VECTOR_EQ(gfx::Vector2d(),
540 expected_no_scroll_layer_
->scroll_offset());
542 switch (layer_tree_host()->source_frame_number()) {
544 EXPECT_VECTOR_EQ(initial_offset_
,
545 expected_scroll_layer_
->scroll_offset());
549 gfx::ScrollOffsetWithDelta(initial_offset_
, scroll_amount_
),
550 expected_scroll_layer_
->scroll_offset());
552 // Pretend like Javascript updated the scroll position itself.
553 expected_scroll_layer_
->SetScrollOffset(javascript_scroll_
);
556 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_
,
558 expected_scroll_layer_
->scroll_offset());
563 void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) override
{
564 LayerImpl
* root_impl
= impl
->active_tree()->root_layer();
565 FakePictureLayerImpl
* root_scroll_layer_impl
=
566 static_cast<FakePictureLayerImpl
*>(root_impl
->children()[0]);
567 FakePictureLayerImpl
* child_layer_impl
= static_cast<FakePictureLayerImpl
*>(
568 root_scroll_layer_impl
->children()[0]);
570 LayerImpl
* expected_scroll_layer_impl
= NULL
;
571 LayerImpl
* expected_no_scroll_layer_impl
= NULL
;
572 if (scroll_child_layer_
) {
573 expected_scroll_layer_impl
= child_layer_impl
;
574 expected_no_scroll_layer_impl
= root_scroll_layer_impl
;
576 expected_scroll_layer_impl
= root_scroll_layer_impl
;
577 expected_no_scroll_layer_impl
= child_layer_impl
;
580 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl
->ScrollDelta());
581 EXPECT_VECTOR_EQ(gfx::Vector2d(),
582 expected_no_scroll_layer_impl
->ScrollDelta());
584 // Ensure device scale factor matches the active tree.
585 EXPECT_EQ(device_scale_factor_
, impl
->active_tree()->device_scale_factor());
586 switch (impl
->active_tree()->source_frame_number()) {
588 // Gesture scroll on impl thread.
589 InputHandler::ScrollStatus status
= impl
->ScrollBegin(
590 gfx::ToCeiledPoint(expected_scroll_layer_impl
->position() -
591 gfx::Vector2dF(0.5f
, 0.5f
)),
592 InputHandler::Gesture
);
593 EXPECT_EQ(InputHandler::ScrollStarted
, status
);
594 impl
->ScrollBy(gfx::Point(), scroll_amount_
);
597 // Check the scroll is applied as a delta.
598 EXPECT_VECTOR_EQ(initial_offset_
,
599 expected_scroll_layer_impl
->scroll_offset());
600 EXPECT_VECTOR_EQ(scroll_amount_
,
601 expected_scroll_layer_impl
->ScrollDelta());
605 // Wheel scroll on impl thread.
606 InputHandler::ScrollStatus status
= impl
->ScrollBegin(
607 gfx::ToCeiledPoint(expected_scroll_layer_impl
->position() +
608 gfx::Vector2dF(0.5f
, 0.5f
)),
609 InputHandler::Wheel
);
610 EXPECT_EQ(InputHandler::ScrollStarted
, status
);
611 impl
->ScrollBy(gfx::Point(), scroll_amount_
);
614 // Check the scroll is applied as a delta.
615 EXPECT_VECTOR_EQ(javascript_scroll_
,
616 expected_scroll_layer_impl
->scroll_offset());
617 EXPECT_VECTOR_EQ(scroll_amount_
,
618 expected_scroll_layer_impl
->ScrollDelta());
623 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_
,
625 expected_scroll_layer_impl
->scroll_offset());
626 EXPECT_VECTOR_EQ(gfx::Vector2d(),
627 expected_scroll_layer_impl
->ScrollDelta());
634 void AfterTest() override
{
635 if (scroll_child_layer_
) {
636 EXPECT_EQ(0, num_scrolls_
);
637 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_
,
639 final_scroll_offset_
);
641 EXPECT_EQ(2, num_scrolls_
);
642 EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_
);
647 float device_scale_factor_
;
648 bool scroll_child_layer_
;
650 gfx::ScrollOffset initial_offset_
;
651 gfx::ScrollOffset javascript_scroll_
;
652 gfx::Vector2d scroll_amount_
;
654 gfx::ScrollOffset final_scroll_offset_
;
656 FakeContentLayerClient fake_content_layer_client_
;
658 scoped_refptr
<Layer
> root_scroll_layer_
;
659 scoped_refptr
<Layer
> child_layer_
;
660 scoped_refptr
<Layer
> expected_scroll_layer_
;
661 scoped_refptr
<Layer
> expected_no_scroll_layer_
;
664 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
665 DeviceScaleFactor1_ScrollChild_DirectRenderer
) {
666 device_scale_factor_
= 1.f
;
667 scroll_child_layer_
= true;
668 RunTest(true, false, true);
671 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
672 DeviceScaleFactor1_ScrollChild_DelegatingRenderer
) {
673 device_scale_factor_
= 1.f
;
674 scroll_child_layer_
= true;
675 RunTest(true, true, true);
678 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
679 DeviceScaleFactor15_ScrollChild_DirectRenderer
) {
680 device_scale_factor_
= 1.5f
;
681 scroll_child_layer_
= true;
682 RunTest(true, false, true);
685 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
686 DeviceScaleFactor15_ScrollChild_DelegatingRenderer
) {
687 device_scale_factor_
= 1.5f
;
688 scroll_child_layer_
= true;
689 RunTest(true, true, true);
692 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
693 DeviceScaleFactor2_ScrollChild_DirectRenderer
) {
694 device_scale_factor_
= 2.f
;
695 scroll_child_layer_
= true;
696 RunTest(true, false, true);
699 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
700 DeviceScaleFactor2_ScrollChild_DelegatingRenderer
) {
701 device_scale_factor_
= 2.f
;
702 scroll_child_layer_
= true;
703 RunTest(true, true, true);
706 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
707 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer
) {
708 device_scale_factor_
= 1.f
;
709 scroll_child_layer_
= false;
710 RunTest(true, false, true);
713 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
714 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer
) {
715 device_scale_factor_
= 1.f
;
716 scroll_child_layer_
= false;
717 RunTest(true, true, true);
720 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
721 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer
) {
722 device_scale_factor_
= 1.5f
;
723 scroll_child_layer_
= false;
724 RunTest(true, false, true);
727 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
728 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer
) {
729 device_scale_factor_
= 1.5f
;
730 scroll_child_layer_
= false;
731 RunTest(true, true, true);
734 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
735 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer
) {
736 device_scale_factor_
= 2.f
;
737 scroll_child_layer_
= false;
738 RunTest(true, false, true);
741 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
742 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer
) {
743 device_scale_factor_
= 2.f
;
744 scroll_child_layer_
= false;
745 RunTest(true, true, true);
748 class ImplSidePaintingScrollTest
: public LayerTreeHostScrollTest
{
750 void InitializeSettings(LayerTreeSettings
* settings
) override
{
751 settings
->impl_side_painting
= true;
754 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
755 if (impl
->pending_tree())
756 impl
->SetNeedsRedraw();
760 class ImplSidePaintingScrollTestSimple
: public ImplSidePaintingScrollTest
{
762 ImplSidePaintingScrollTestSimple()
763 : initial_scroll_(10, 20),
764 main_thread_scroll_(40, 5),
765 impl_thread_scroll1_(2, -1),
766 impl_thread_scroll2_(-3, 10),
769 void SetupTree() override
{
770 LayerTreeHostScrollTest::SetupTree();
771 Layer
* root_layer
= layer_tree_host()->root_layer();
772 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
773 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
774 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
775 root_scroll_layer
->SetBounds(
776 gfx::Size(root_layer
->bounds().width() + 100,
777 root_layer
->bounds().height() + 100));
778 root_scroll_layer
->SetIsDrawable(true);
779 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
780 root_layer
->AddChild(root_scroll_layer
);
782 layer_tree_host()->RegisterViewportLayers(
783 root_layer
, root_scroll_layer
, NULL
);
784 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
787 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
789 void Layout() override
{
790 Layer
* root
= layer_tree_host()->root_layer();
791 Layer
* scroll_layer
= root
->children()[0].get();
792 if (!layer_tree_host()->source_frame_number()) {
793 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
796 scroll_layer
->scroll_offset(),
797 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_thread_scroll1_
));
799 // Pretend like Javascript updated the scroll position itself with a
800 // change of main_thread_scroll.
801 scroll_layer
->SetScrollOffset(
802 gfx::ScrollOffsetWithDelta(
803 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
807 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
808 // We force a second draw here of the first commit before activating
809 // the second commit.
810 if (impl
->active_tree()->source_frame_number() == 0)
811 impl
->SetNeedsRedraw();
814 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
815 ImplSidePaintingScrollTest::DrawLayersOnThread(impl
);
817 LayerImpl
* root
= impl
->active_tree()->root_layer();
818 LayerImpl
* scroll_layer
= root
->children()[0];
819 LayerImpl
* pending_root
=
820 impl
->active_tree()->FindPendingTreeLayerById(root
->id());
822 switch (impl
->active_tree()->source_frame_number()) {
824 if (!impl
->pending_tree()) {
825 impl
->BlockNotifyReadyToActivateForTesting(true);
826 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
827 scroll_layer
->ScrollBy(impl_thread_scroll1_
);
829 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
830 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll1_
);
831 EXPECT_VECTOR_EQ(scroll_layer
->sent_scroll_delta(), gfx::Vector2d());
832 PostSetNeedsCommitToMainThread();
834 // CommitCompleteOnThread will trigger this function again
835 // and cause us to take the else clause.
837 impl
->BlockNotifyReadyToActivateForTesting(false);
838 ASSERT_TRUE(pending_root
);
839 EXPECT_EQ(impl
->pending_tree()->source_frame_number(), 1);
841 scroll_layer
->ScrollBy(impl_thread_scroll2_
);
842 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
843 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
844 impl_thread_scroll1_
+ impl_thread_scroll2_
);
845 EXPECT_VECTOR_EQ(scroll_layer
->sent_scroll_delta(),
846 impl_thread_scroll1_
);
848 LayerImpl
* pending_scroll_layer
= pending_root
->children()[0];
850 pending_scroll_layer
->scroll_offset(),
851 gfx::ScrollOffsetWithDelta(
852 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
853 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(),
854 impl_thread_scroll2_
);
855 EXPECT_VECTOR_EQ(pending_scroll_layer
->sent_scroll_delta(),
860 EXPECT_FALSE(impl
->pending_tree());
862 scroll_layer
->scroll_offset(),
863 gfx::ScrollOffsetWithDelta(
864 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
865 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll2_
);
866 EXPECT_VECTOR_EQ(scroll_layer
->sent_scroll_delta(), gfx::Vector2d());
872 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
874 float top_controls_delta
) override
{
878 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
881 gfx::ScrollOffset initial_scroll_
;
882 gfx::Vector2dF main_thread_scroll_
;
883 gfx::Vector2dF impl_thread_scroll1_
;
884 gfx::Vector2dF impl_thread_scroll2_
;
888 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple
);
890 // This test makes sure that layers pick up scrolls that occur between
891 // beginning a commit and finishing a commit (aka scroll deltas not
892 // included in sent scroll delta) still apply to layers that don't
894 class ImplSidePaintingScrollTestImplOnlyScroll
895 : public ImplSidePaintingScrollTest
{
897 ImplSidePaintingScrollTestImplOnlyScroll()
898 : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3) {}
900 void SetupTree() override
{
901 LayerTreeHostScrollTest::SetupTree();
902 Layer
* root_layer
= layer_tree_host()->root_layer();
903 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
904 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
905 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
906 root_scroll_layer
->SetBounds(
907 gfx::Size(root_layer
->bounds().width() + 100,
908 root_layer
->bounds().height() + 100));
909 root_scroll_layer
->SetIsDrawable(true);
910 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
911 root_layer
->AddChild(root_scroll_layer
);
913 layer_tree_host()->RegisterViewportLayers(
914 root_layer
, root_scroll_layer
, NULL
);
915 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
918 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
920 void WillCommit() override
{
921 Layer
* root
= layer_tree_host()->root_layer();
922 Layer
* scroll_layer
= root
->children()[0].get();
923 switch (layer_tree_host()->source_frame_number()) {
925 EXPECT_TRUE(scroll_layer
->needs_push_properties());
928 // Even if this layer doesn't need push properties, it should
929 // still pick up scrolls that happen on the active layer during
931 EXPECT_FALSE(scroll_layer
->needs_push_properties());
936 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
937 // Scroll after the 2nd commit has started.
938 if (impl
->active_tree()->source_frame_number() == 0) {
939 LayerImpl
* active_root
= impl
->active_tree()->root_layer();
940 LayerImpl
* active_scroll_layer
= active_root
->children()[0];
941 ASSERT_TRUE(active_root
);
942 ASSERT_TRUE(active_scroll_layer
);
943 active_scroll_layer
->ScrollBy(impl_thread_scroll_
);
947 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
948 // We force a second draw here of the first commit before activating
949 // the second commit.
950 LayerImpl
* active_root
= impl
->active_tree()->root_layer();
951 LayerImpl
* active_scroll_layer
=
952 active_root
? active_root
->children()[0] : NULL
;
953 LayerImpl
* pending_root
= impl
->pending_tree()->root_layer();
954 LayerImpl
* pending_scroll_layer
= pending_root
->children()[0];
956 ASSERT_TRUE(pending_root
);
957 ASSERT_TRUE(pending_scroll_layer
);
958 switch (impl
->pending_tree()->source_frame_number()) {
960 EXPECT_VECTOR_EQ(pending_scroll_layer
->scroll_offset(),
962 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(), gfx::Vector2d());
963 EXPECT_VECTOR_EQ(pending_scroll_layer
->sent_scroll_delta(),
965 EXPECT_FALSE(active_root
);
968 // Even though the scroll happened during the commit, both layers
969 // should have the appropriate scroll delta.
970 EXPECT_VECTOR_EQ(pending_scroll_layer
->scroll_offset(),
972 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(),
973 impl_thread_scroll_
);
974 EXPECT_VECTOR_EQ(pending_scroll_layer
->sent_scroll_delta(),
976 ASSERT_TRUE(active_root
);
977 EXPECT_VECTOR_EQ(active_scroll_layer
->scroll_offset(), initial_scroll_
);
978 EXPECT_VECTOR_EQ(active_scroll_layer
->ScrollDelta(),
979 impl_thread_scroll_
);
980 EXPECT_VECTOR_EQ(active_scroll_layer
->sent_scroll_delta(),
984 // On the next commit, this delta should have been sent and applied.
985 EXPECT_VECTOR_EQ(pending_scroll_layer
->scroll_offset(),
986 gfx::ScrollOffsetWithDelta(initial_scroll_
,
987 impl_thread_scroll_
));
988 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(), gfx::Vector2d());
989 EXPECT_VECTOR_EQ(pending_scroll_layer
->sent_scroll_delta(),
996 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
997 ImplSidePaintingScrollTest::DrawLayersOnThread(impl
);
999 LayerImpl
* root
= impl
->active_tree()->root_layer();
1000 LayerImpl
* scroll_layer
= root
->children()[0];
1002 switch (impl
->active_tree()->source_frame_number()) {
1004 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
1005 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
1006 EXPECT_VECTOR_EQ(scroll_layer
->sent_scroll_delta(), gfx::Vector2d());
1007 PostSetNeedsCommitToMainThread();
1010 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
1011 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll_
);
1012 EXPECT_VECTOR_EQ(scroll_layer
->sent_scroll_delta(), gfx::Vector2d());
1013 PostSetNeedsCommitToMainThread();
1018 void AfterTest() override
{}
1021 gfx::ScrollOffset initial_scroll_
;
1022 gfx::Vector2dF impl_thread_scroll_
;
1025 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll
);
1027 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
1028 : public LayerTreeHostScrollTest
{
1030 LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
1032 void SetupTree() override
{
1033 LayerTreeTest::SetupTree();
1034 scoped_refptr
<Layer
> scroll_layer
= Layer::Create();
1035 layer_tree_host()->root_layer()->AddChild(scroll_layer
);
1038 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1040 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
1041 LayerImpl
* root
= impl
->active_tree()->root_layer();
1042 LayerImpl
* scroll_layer
= root
->children()[0];
1043 scroll_layer
->SetScrollClipLayer(root
->id());
1045 // Set max_scroll_offset = (100, 100).
1046 scroll_layer
->SetBounds(
1047 gfx::Size(root
->bounds().width() + 100, root
->bounds().height() + 100));
1048 EXPECT_EQ(InputHandler::ScrollStarted
,
1049 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
),
1050 InputHandler::Gesture
));
1052 // Set max_scroll_offset = (0, 0).
1053 scroll_layer
->SetBounds(root
->bounds());
1054 EXPECT_EQ(InputHandler::ScrollIgnored
,
1055 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
),
1056 InputHandler::Gesture
));
1058 // Set max_scroll_offset = (-100, -100).
1059 scroll_layer
->SetBounds(gfx::Size());
1060 EXPECT_EQ(InputHandler::ScrollIgnored
,
1061 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
),
1062 InputHandler::Gesture
));
1067 void AfterTest() override
{}
1070 SINGLE_AND_MULTI_THREAD_TEST_F(
1071 LayerTreeHostScrollTestScrollZeroMaxScrollOffset
);
1073 class ThreadCheckingInputHandlerClient
: public InputHandlerClient
{
1075 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner
* runner
,
1076 bool* received_stop_flinging
)
1077 : task_runner_(runner
), received_stop_flinging_(received_stop_flinging
) {}
1079 void WillShutdown() override
{
1080 if (!received_stop_flinging_
)
1081 ADD_FAILURE() << "WillShutdown() called before fling stopped";
1084 void Animate(base::TimeTicks time
) override
{
1085 if (!task_runner_
->BelongsToCurrentThread())
1086 ADD_FAILURE() << "Animate called on wrong thread";
1089 void MainThreadHasStoppedFlinging() override
{
1090 if (!task_runner_
->BelongsToCurrentThread())
1091 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
1092 *received_stop_flinging_
= true;
1096 base::SingleThreadTaskRunner
* task_runner_
;
1097 bool* received_stop_flinging_
;
1100 void BindInputHandlerOnCompositorThread(
1101 const base::WeakPtr
<InputHandler
>& input_handler
,
1102 ThreadCheckingInputHandlerClient
* client
) {
1103 input_handler
->BindToClient(client
);
1106 TEST(LayerTreeHostFlingTest
, DidStopFlingingThread
) {
1107 base::Thread
impl_thread("cc");
1108 ASSERT_TRUE(impl_thread
.Start());
1110 bool received_stop_flinging
= false;
1111 LayerTreeSettings settings
;
1113 ThreadCheckingInputHandlerClient
input_handler_client(
1114 impl_thread
.message_loop_proxy().get(), &received_stop_flinging
);
1115 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1117 ASSERT_TRUE(impl_thread
.message_loop_proxy().get());
1118 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1119 new TestSharedBitmapManager());
1120 scoped_ptr
<LayerTreeHost
> layer_tree_host
=
1121 LayerTreeHost::CreateThreaded(&client
,
1122 shared_bitmap_manager
.get(),
1125 base::MessageLoopProxy::current(),
1126 impl_thread
.message_loop_proxy(),
1129 impl_thread
.message_loop_proxy()
1130 ->PostTask(FROM_HERE
,
1131 base::Bind(&BindInputHandlerOnCompositorThread
,
1132 layer_tree_host
->GetInputHandler(),
1133 base::Unretained(&input_handler_client
)));
1135 layer_tree_host
->DidStopFlinging();
1136 layer_tree_host
= nullptr;
1138 EXPECT_TRUE(received_stop_flinging
);
1141 class LayerTreeHostScrollTestLayerStructureChange
1142 : public LayerTreeHostScrollTest
{
1144 LayerTreeHostScrollTestLayerStructureChange()
1145 : scroll_destroy_whole_tree_(false) {}
1147 void SetupTree() override
{
1148 scoped_refptr
<Layer
> root_layer
= Layer::Create();
1149 root_layer
->SetBounds(gfx::Size(10, 10));
1151 Layer
* root_scroll_layer
=
1152 CreateScrollLayer(root_layer
.get(), &root_scroll_layer_client_
);
1153 CreateScrollLayer(root_layer
.get(), &sibling_scroll_layer_client_
);
1154 CreateScrollLayer(root_scroll_layer
, &child_scroll_layer_client_
);
1156 layer_tree_host()->SetRootLayer(root_layer
);
1157 LayerTreeHostScrollTest::SetupTree();
1160 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1162 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
1163 LayerImpl
* root
= impl
->active_tree()->root_layer();
1164 switch (impl
->active_tree()->source_frame_number()) {
1166 root
->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1167 root
->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1168 root
->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5));
1169 PostSetNeedsCommitToMainThread();
1177 void AfterTest() override
{}
1179 virtual void DidScroll(Layer
* layer
) {
1180 if (scroll_destroy_whole_tree_
) {
1181 layer_tree_host()->SetRootLayer(NULL
);
1185 layer
->RemoveFromParent();
1189 class FakeLayerScrollClient
{
1192 owner_
->DidScroll(layer_
);
1194 LayerTreeHostScrollTestLayerStructureChange
* owner_
;
1198 Layer
* CreateScrollLayer(Layer
* parent
, FakeLayerScrollClient
* client
) {
1199 scoped_refptr
<PictureLayer
> scroll_layer
=
1200 PictureLayer::Create(&fake_content_layer_client_
);
1201 scroll_layer
->SetBounds(gfx::Size(110, 110));
1202 scroll_layer
->SetPosition(gfx::Point(0, 0));
1203 scroll_layer
->SetIsDrawable(true);
1204 scroll_layer
->SetScrollClipLayerId(parent
->id());
1205 scroll_layer
->SetBounds(gfx::Size(parent
->bounds().width() + 100,
1206 parent
->bounds().height() + 100));
1207 scroll_layer
->set_did_scroll_callback(base::Bind(
1208 &FakeLayerScrollClient::DidScroll
, base::Unretained(client
)));
1209 client
->owner_
= this;
1210 client
->layer_
= scroll_layer
.get();
1211 parent
->AddChild(scroll_layer
);
1212 return scroll_layer
.get();
1215 FakeLayerScrollClient root_scroll_layer_client_
;
1216 FakeLayerScrollClient sibling_scroll_layer_client_
;
1217 FakeLayerScrollClient child_scroll_layer_client_
;
1219 FakeContentLayerClient fake_content_layer_client_
;
1221 bool scroll_destroy_whole_tree_
;
1224 TEST_F(LayerTreeHostScrollTestLayerStructureChange
, ScrollDestroyLayer
) {
1225 RunTest(true, false, true);
1228 TEST_F(LayerTreeHostScrollTestLayerStructureChange
, ScrollDestroyWholeTree
) {
1229 scroll_destroy_whole_tree_
= true;
1230 RunTest(true, false, true);