1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host.h"
7 #include "base/location.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "cc/layers/layer.h"
12 #include "cc/layers/layer_impl.h"
13 #include "cc/layers/picture_layer.h"
14 #include "cc/scheduler/begin_frame_source.h"
15 #include "cc/test/fake_content_layer_client.h"
16 #include "cc/test/fake_layer_tree_host_client.h"
17 #include "cc/test/fake_picture_layer.h"
18 #include "cc/test/fake_picture_layer_impl.h"
19 #include "cc/test/geometry_test_utils.h"
20 #include "cc/test/layer_tree_test.h"
21 #include "cc/test/test_shared_bitmap_manager.h"
22 #include "cc/trees/layer_tree_impl.h"
23 #include "ui/gfx/geometry/point_conversions.h"
24 #include "ui/gfx/geometry/size_conversions.h"
25 #include "ui/gfx/geometry/vector2d_conversions.h"
30 class LayerTreeHostScrollTest
: public LayerTreeTest
{};
32 class LayerTreeHostScrollTestScrollSimple
: public LayerTreeHostScrollTest
{
34 LayerTreeHostScrollTestScrollSimple()
35 : initial_scroll_(10, 20),
36 second_scroll_(40, 5),
37 scroll_amount_(2, -1),
40 void BeginTest() override
{
41 Layer
* root_layer
= layer_tree_host()->root_layer();
42 scoped_refptr
<Layer
> scroll_layer
= Layer::Create();
43 root_layer
->AddChild(scroll_layer
);
44 // Create an effective max_scroll_offset of (100, 100).
45 scroll_layer
->SetBounds(gfx::Size(root_layer
->bounds().width() + 100,
46 root_layer
->bounds().height() + 100));
47 scroll_layer
->SetIsDrawable(true);
48 scroll_layer
->SetIsContainerForFixedPositionLayers(true);
49 scroll_layer
->SetScrollClipLayerId(root_layer
->id());
50 scroll_layer
->SetScrollOffset(initial_scroll_
);
51 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
, scroll_layer
,
53 PostSetNeedsCommitToMainThread();
56 void Layout() override
{
57 Layer
* root
= layer_tree_host()->root_layer();
58 Layer
* scroll_layer
= root
->children()[0].get();
59 if (!layer_tree_host()->source_frame_number()) {
60 EXPECT_VECTOR_EQ(initial_scroll_
, scroll_layer
->scroll_offset());
62 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_
,
64 scroll_layer
->scroll_offset());
66 // Pretend like Javascript updated the scroll position itself.
67 scroll_layer
->SetScrollOffset(second_scroll_
);
71 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
72 LayerImpl
* root
= impl
->active_tree()->root_layer();
73 LayerImpl
* scroll_layer
= root
->children()[0];
74 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer
->ScrollDelta());
76 scroll_layer
->SetScrollClipLayer(root
->id());
77 scroll_layer
->SetBounds(
78 gfx::Size(root
->bounds().width() + 100, root
->bounds().height() + 100));
79 scroll_layer
->ScrollBy(scroll_amount_
);
81 switch (impl
->active_tree()->source_frame_number()) {
83 EXPECT_VECTOR_EQ(initial_scroll_
, scroll_layer
->BaseScrollOffset());
84 EXPECT_VECTOR_EQ(scroll_amount_
, scroll_layer
->ScrollDelta());
85 PostSetNeedsCommitToMainThread();
88 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), second_scroll_
);
89 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
95 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
97 float top_controls_delta
) override
{
101 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
104 gfx::ScrollOffset initial_scroll_
;
105 gfx::ScrollOffset second_scroll_
;
106 gfx::Vector2dF scroll_amount_
;
110 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple
);
112 class LayerTreeHostScrollTestScrollMultipleRedraw
113 : public LayerTreeHostScrollTest
{
115 LayerTreeHostScrollTestScrollMultipleRedraw()
116 : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
118 void BeginTest() override
{
119 Layer
* root_layer
= layer_tree_host()->root_layer();
120 scroll_layer_
= Layer::Create();
121 root_layer
->AddChild(scroll_layer_
);
122 // Create an effective max_scroll_offset of (100, 100).
123 scroll_layer_
->SetBounds(gfx::Size(root_layer
->bounds().width() + 100,
124 root_layer
->bounds().height() + 100));
125 scroll_layer_
->SetIsDrawable(true);
126 scroll_layer_
->SetIsContainerForFixedPositionLayers(true);
127 scroll_layer_
->SetScrollClipLayerId(root_layer
->id());
128 scroll_layer_
->SetScrollOffset(initial_scroll_
);
129 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
, scroll_layer_
,
131 PostSetNeedsCommitToMainThread();
134 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
135 switch (layer_tree_host()->source_frame_number()) {
137 EXPECT_VECTOR_EQ(scroll_layer_
->scroll_offset(), initial_scroll_
);
141 scroll_layer_
->scroll_offset(),
142 gfx::ScrollOffsetWithDelta(initial_scroll_
,
143 scroll_amount_
+ scroll_amount_
));
146 scroll_layer_
->scroll_offset(),
147 gfx::ScrollOffsetWithDelta(initial_scroll_
,
148 scroll_amount_
+ scroll_amount_
));
153 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
154 LayerImpl
* scroll_layer
=
155 impl
->active_tree()->LayerById(scroll_layer_
->id());
156 if (impl
->active_tree()->source_frame_number() == 0 &&
157 impl
->SourceAnimationFrameNumber() == 1) {
158 // First draw after first commit.
159 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
160 scroll_layer
->ScrollBy(scroll_amount_
);
161 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
163 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
164 PostSetNeedsRedrawToMainThread();
165 } else if (impl
->active_tree()->source_frame_number() == 0 &&
166 impl
->SourceAnimationFrameNumber() == 2) {
167 // Second draw after first commit.
168 EXPECT_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
169 scroll_layer
->ScrollBy(scroll_amount_
);
170 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
171 scroll_amount_
+ scroll_amount_
);
173 EXPECT_VECTOR_EQ(scroll_layer_
->scroll_offset(), initial_scroll_
);
174 PostSetNeedsCommitToMainThread();
175 } else if (impl
->active_tree()->source_frame_number() == 1) {
176 // Third or later draw after second commit.
177 EXPECT_GE(impl
->SourceAnimationFrameNumber(), 3);
178 EXPECT_VECTOR_EQ(scroll_layer_
->ScrollDelta(), gfx::Vector2d());
180 scroll_layer_
->scroll_offset(),
181 gfx::ScrollOffsetWithDelta(initial_scroll_
,
182 scroll_amount_
+ scroll_amount_
));
187 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
189 float top_controls_delta
) override
{
193 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
196 gfx::ScrollOffset initial_scroll_
;
197 gfx::Vector2dF scroll_amount_
;
199 scoped_refptr
<Layer
> scroll_layer_
;
202 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw
);
204 class LayerTreeHostScrollTestScrollAbortedCommit
205 : public LayerTreeHostScrollTest
{
207 LayerTreeHostScrollTestScrollAbortedCommit()
208 : initial_scroll_(50, 60),
210 second_main_scroll_(14, -3),
212 num_will_begin_main_frames_(0),
213 num_did_begin_main_frames_(0),
214 num_will_commits_(0),
216 num_impl_commits_(0),
217 num_impl_scrolls_(0) {}
219 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
221 void SetupTree() override
{
222 LayerTreeHostScrollTest::SetupTree();
223 Layer
* root_layer
= layer_tree_host()->root_layer();
224 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
225 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
226 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
227 root_scroll_layer
->SetBounds(gfx::Size(200, 200));
228 root_scroll_layer
->SetIsDrawable(true);
229 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
230 root_layer
->AddChild(root_scroll_layer
);
232 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
233 root_scroll_layer
, NULL
);
234 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
237 void WillBeginMainFrame() override
{
238 num_will_begin_main_frames_
++;
239 Layer
* root_scroll_layer
=
240 layer_tree_host()->root_layer()->children()[0].get();
241 switch (num_will_begin_main_frames_
) {
243 // This will not be aborted because of the initial prop changes.
244 EXPECT_EQ(0, num_impl_scrolls_
);
245 EXPECT_EQ(0, layer_tree_host()->source_frame_number());
246 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(), initial_scroll_
);
247 EXPECT_EQ(1.f
, layer_tree_host()->page_scale_factor());
250 // This commit will be aborted, and another commit will be
251 // initiated from the redraw.
252 EXPECT_EQ(1, num_impl_scrolls_
);
253 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
255 root_scroll_layer
->scroll_offset(),
256 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_scroll_
));
257 EXPECT_EQ(impl_scale_
, layer_tree_host()->page_scale_factor());
258 PostSetNeedsRedrawToMainThread();
261 // This commit will not be aborted because of the scroll change.
262 EXPECT_EQ(2, num_impl_scrolls_
);
263 // The source frame number still increases even with the abort.
264 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
266 root_scroll_layer
->scroll_offset(),
267 gfx::ScrollOffsetWithDelta(initial_scroll_
,
268 impl_scroll_
+ impl_scroll_
));
269 EXPECT_EQ(impl_scale_
* impl_scale_
,
270 layer_tree_host()->page_scale_factor());
271 root_scroll_layer
->SetScrollOffset(gfx::ScrollOffsetWithDelta(
272 root_scroll_layer
->scroll_offset(), second_main_scroll_
));
275 // This commit will also be aborted.
276 EXPECT_EQ(3, num_impl_scrolls_
);
277 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
278 gfx::Vector2dF delta
=
279 impl_scroll_
+ impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
280 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
281 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
283 // End the test by drawing to verify this commit is also aborted.
284 PostSetNeedsRedrawToMainThread();
289 void DidBeginMainFrame() override
{ num_did_begin_main_frames_
++; }
291 void WillCommit() override
{ num_will_commits_
++; }
293 void DidCommit() override
{ num_did_commits_
++; }
295 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
299 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
300 LayerImpl
* root_scroll_layer
=
301 impl
->active_tree()->root_layer()->children()[0];
303 if (impl
->active_tree()->source_frame_number() == 0 &&
304 impl
->SourceAnimationFrameNumber() == 1) {
306 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
307 root_scroll_layer
->ScrollBy(impl_scroll_
);
308 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
309 EXPECT_VECTOR_EQ(root_scroll_layer
->BaseScrollOffset(), initial_scroll_
);
311 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
312 EXPECT_EQ(1.f
, impl
->active_tree()->current_page_scale_factor());
313 impl
->SetPageScaleOnActiveTree(impl_scale_
);
314 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
315 EXPECT_EQ(impl_scale_
, impl
->active_tree()->current_page_scale_factor());
317 // To simplify the testing flow, don't redraw here, just commit.
318 impl
->SetNeedsCommit();
319 } else if (impl
->active_tree()->source_frame_number() == 0 &&
320 impl
->SourceAnimationFrameNumber() == 2) {
321 // Test a second draw after an aborted commit.
322 // The scroll/scale values should be baked into the offset/scale factor
323 // since the main thread consumed but aborted the begin frame.
324 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
325 root_scroll_layer
->ScrollBy(impl_scroll_
);
326 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
328 root_scroll_layer
->BaseScrollOffset(),
329 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_scroll_
));
331 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
332 EXPECT_EQ(impl_scale_
, impl
->active_tree()->current_page_scale_factor());
333 impl
->SetPageScaleOnActiveTree(impl_scale_
* impl_scale_
);
334 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
335 EXPECT_EQ(impl_scale_
* impl_scale_
,
336 impl
->active_tree()->current_page_scale_factor());
338 impl
->SetNeedsCommit();
339 } else if (impl
->active_tree()->source_frame_number() == 1) {
340 // Commit for source frame 1 is aborted.
342 } else if (impl
->active_tree()->source_frame_number() == 2 &&
343 impl
->SourceAnimationFrameNumber() == 3) {
344 // Third draw after the second full commit.
345 EXPECT_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
346 root_scroll_layer
->ScrollBy(impl_scroll_
);
347 impl
->SetNeedsCommit();
348 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
349 gfx::Vector2dF delta
= impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
350 EXPECT_VECTOR_EQ(root_scroll_layer
->BaseScrollOffset(),
351 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
352 } else if (impl
->active_tree()->source_frame_number() == 2 &&
353 impl
->SourceAnimationFrameNumber() == 4) {
354 // Final draw after the second aborted commit.
355 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
356 gfx::Vector2dF delta
=
357 impl_scroll_
+ impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
358 EXPECT_VECTOR_EQ(root_scroll_layer
->BaseScrollOffset(),
359 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
362 // Commit for source frame 3 is aborted.
367 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
369 float top_controls_delta
) override
{
373 void AfterTest() override
{
374 EXPECT_EQ(3, num_impl_scrolls_
);
375 // Verify that the embedder sees aborted commits as real commits.
376 EXPECT_EQ(4, num_will_begin_main_frames_
);
377 EXPECT_EQ(4, num_did_begin_main_frames_
);
378 EXPECT_EQ(4, num_will_commits_
);
379 EXPECT_EQ(4, num_did_commits_
);
380 // ...but the compositor thread only sees two real ones.
381 EXPECT_EQ(2, num_impl_commits_
);
385 gfx::ScrollOffset initial_scroll_
;
386 gfx::Vector2dF impl_scroll_
;
387 gfx::Vector2dF second_main_scroll_
;
389 int num_will_begin_main_frames_
;
390 int num_did_begin_main_frames_
;
391 int num_will_commits_
;
392 int num_did_commits_
;
393 int num_impl_commits_
;
394 int num_impl_scrolls_
;
397 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit
);
399 class LayerTreeHostScrollTestFractionalScroll
: public LayerTreeHostScrollTest
{
401 LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
403 void SetupTree() override
{
404 LayerTreeHostScrollTest::SetupTree();
405 Layer
* root_layer
= layer_tree_host()->root_layer();
406 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
407 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
408 root_scroll_layer
->SetBounds(
409 gfx::Size(root_layer
->bounds().width() + 100,
410 root_layer
->bounds().height() + 100));
411 root_scroll_layer
->SetIsDrawable(true);
412 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
413 root_layer
->AddChild(root_scroll_layer
);
415 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
416 root_scroll_layer
, NULL
);
417 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
420 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
422 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
423 LayerImpl
* root
= impl
->active_tree()->root_layer();
424 LayerImpl
* scroll_layer
= root
->children()[0];
426 // Check that a fractional scroll delta is correctly accumulated over
428 switch (impl
->active_tree()->source_frame_number()) {
430 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), gfx::Vector2d(0, 0));
431 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d(0, 0));
432 PostSetNeedsCommitToMainThread();
435 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(),
436 gfx::ToFlooredVector2d(scroll_amount_
));
437 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
438 gfx::Vector2dF(fmod(scroll_amount_
.x(), 1.0f
), 0.0f
));
439 PostSetNeedsCommitToMainThread();
443 scroll_layer
->BaseScrollOffset(),
444 gfx::ToFlooredVector2d(scroll_amount_
+ scroll_amount_
));
446 scroll_layer
->ScrollDelta(),
447 gfx::Vector2dF(fmod(2.0f
* scroll_amount_
.x(), 1.0f
), 0.0f
));
451 scroll_layer
->ScrollBy(scroll_amount_
);
454 void AfterTest() override
{}
457 gfx::Vector2dF scroll_amount_
;
460 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll
);
462 class LayerTreeHostScrollTestCaseWithChild
: public LayerTreeHostScrollTest
{
464 LayerTreeHostScrollTestCaseWithChild()
465 : initial_offset_(10, 20),
466 javascript_scroll_(40, 5),
467 scroll_amount_(2, -1),
470 void SetupTree() override
{
471 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_
);
473 scoped_refptr
<Layer
> root_layer
= Layer::Create();
474 root_layer
->SetBounds(gfx::Size(10, 10));
476 root_scroll_layer_
= FakePictureLayer::Create(&fake_content_layer_client_
);
477 root_scroll_layer_
->SetBounds(gfx::Size(110, 110));
479 root_scroll_layer_
->SetPosition(gfx::Point());
481 root_scroll_layer_
->SetIsDrawable(true);
482 root_scroll_layer_
->SetScrollClipLayerId(root_layer
->id());
483 root_scroll_layer_
->SetIsContainerForFixedPositionLayers(true);
484 root_layer
->AddChild(root_scroll_layer_
);
486 child_layer_
= FakePictureLayer::Create(&fake_content_layer_client_
);
487 child_layer_
->set_did_scroll_callback(
488 base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll
,
489 base::Unretained(this)));
490 child_layer_
->SetBounds(gfx::Size(110, 110));
492 if (scroll_child_layer_
) {
493 // Scrolls on the child layer will happen at 5, 5. If they are treated
494 // like device pixels, and device scale factor is 2, then they will
495 // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
496 child_layer_
->SetPosition(gfx::Point(5, 5));
498 // Adjust the child layer horizontally so that scrolls will never hit it.
499 child_layer_
->SetPosition(gfx::Point(60, 5));
502 child_layer_
->SetIsDrawable(true);
503 child_layer_
->SetScrollClipLayerId(root_layer
->id());
504 child_layer_
->SetBounds(root_scroll_layer_
->bounds());
505 root_scroll_layer_
->AddChild(child_layer_
);
507 if (scroll_child_layer_
) {
508 expected_scroll_layer_
= child_layer_
;
509 expected_no_scroll_layer_
= root_scroll_layer_
;
511 expected_scroll_layer_
= root_scroll_layer_
;
512 expected_no_scroll_layer_
= child_layer_
;
515 expected_scroll_layer_
->SetScrollOffset(initial_offset_
);
517 layer_tree_host()->SetRootLayer(root_layer
);
518 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
519 root_scroll_layer_
, NULL
);
520 LayerTreeHostScrollTest::SetupTree();
523 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
525 void WillCommit() override
{
526 // Keep the test committing (otherwise the early out for no update
527 // will stall the test).
528 if (layer_tree_host()->source_frame_number() < 2) {
529 layer_tree_host()->SetNeedsCommit();
534 final_scroll_offset_
= expected_scroll_layer_
->scroll_offset();
537 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
539 float top_controls_delta
) override
{
543 void Layout() override
{
544 EXPECT_VECTOR_EQ(gfx::Vector2d(),
545 expected_no_scroll_layer_
->scroll_offset());
547 switch (layer_tree_host()->source_frame_number()) {
549 EXPECT_VECTOR_EQ(initial_offset_
,
550 expected_scroll_layer_
->scroll_offset());
554 gfx::ScrollOffsetWithDelta(initial_offset_
, scroll_amount_
),
555 expected_scroll_layer_
->scroll_offset());
557 // Pretend like Javascript updated the scroll position itself.
558 expected_scroll_layer_
->SetScrollOffset(javascript_scroll_
);
561 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_
,
563 expected_scroll_layer_
->scroll_offset());
568 void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) override
{
569 LayerImpl
* root_impl
= impl
->active_tree()->root_layer();
570 FakePictureLayerImpl
* root_scroll_layer_impl
=
571 static_cast<FakePictureLayerImpl
*>(root_impl
->children()[0]);
572 FakePictureLayerImpl
* child_layer_impl
= static_cast<FakePictureLayerImpl
*>(
573 root_scroll_layer_impl
->children()[0]);
575 LayerImpl
* expected_scroll_layer_impl
= NULL
;
576 LayerImpl
* expected_no_scroll_layer_impl
= NULL
;
577 if (scroll_child_layer_
) {
578 expected_scroll_layer_impl
= child_layer_impl
;
579 expected_no_scroll_layer_impl
= root_scroll_layer_impl
;
581 expected_scroll_layer_impl
= root_scroll_layer_impl
;
582 expected_no_scroll_layer_impl
= child_layer_impl
;
585 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl
->ScrollDelta());
586 EXPECT_VECTOR_EQ(gfx::Vector2d(),
587 expected_no_scroll_layer_impl
->ScrollDelta());
589 // Ensure device scale factor matches the active tree.
590 EXPECT_EQ(device_scale_factor_
, impl
->active_tree()->device_scale_factor());
591 switch (impl
->active_tree()->source_frame_number()) {
593 // GESTURE scroll on impl thread.
594 InputHandler::ScrollStatus status
= impl
->ScrollBegin(
595 gfx::ToCeiledPoint(expected_scroll_layer_impl
->position() -
596 gfx::Vector2dF(0.5f
, 0.5f
)),
597 InputHandler::GESTURE
);
598 EXPECT_EQ(InputHandler::SCROLL_STARTED
, status
);
599 impl
->ScrollBy(gfx::Point(), scroll_amount_
);
602 // Check the scroll is applied as a delta.
603 EXPECT_VECTOR_EQ(initial_offset_
,
604 expected_scroll_layer_impl
->BaseScrollOffset());
605 EXPECT_VECTOR_EQ(scroll_amount_
,
606 expected_scroll_layer_impl
->ScrollDelta());
610 // WHEEL scroll on impl thread.
611 InputHandler::ScrollStatus status
= impl
->ScrollBegin(
612 gfx::ToCeiledPoint(expected_scroll_layer_impl
->position() +
613 gfx::Vector2dF(0.5f
, 0.5f
)),
614 InputHandler::WHEEL
);
615 EXPECT_EQ(InputHandler::SCROLL_STARTED
, status
);
616 impl
->ScrollBy(gfx::Point(), scroll_amount_
);
619 // Check the scroll is applied as a delta.
620 EXPECT_VECTOR_EQ(javascript_scroll_
,
621 expected_scroll_layer_impl
->BaseScrollOffset());
622 EXPECT_VECTOR_EQ(scroll_amount_
,
623 expected_scroll_layer_impl
->ScrollDelta());
629 gfx::ScrollOffsetWithDelta(javascript_scroll_
, scroll_amount_
),
630 expected_scroll_layer_impl
->BaseScrollOffset());
631 EXPECT_VECTOR_EQ(gfx::Vector2d(),
632 expected_scroll_layer_impl
->ScrollDelta());
639 void AfterTest() override
{
640 if (scroll_child_layer_
) {
641 EXPECT_EQ(0, num_scrolls_
);
642 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_
,
644 final_scroll_offset_
);
646 EXPECT_EQ(2, num_scrolls_
);
647 EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_
);
652 float device_scale_factor_
;
653 bool scroll_child_layer_
;
655 gfx::ScrollOffset initial_offset_
;
656 gfx::ScrollOffset javascript_scroll_
;
657 gfx::Vector2d scroll_amount_
;
659 gfx::ScrollOffset final_scroll_offset_
;
661 FakeContentLayerClient fake_content_layer_client_
;
663 scoped_refptr
<Layer
> root_scroll_layer_
;
664 scoped_refptr
<Layer
> child_layer_
;
665 scoped_refptr
<Layer
> expected_scroll_layer_
;
666 scoped_refptr
<Layer
> expected_no_scroll_layer_
;
669 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
670 DeviceScaleFactor1_ScrollChild_DirectRenderer
) {
671 device_scale_factor_
= 1.f
;
672 scroll_child_layer_
= true;
673 RunTest(true, false, true);
676 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
677 DeviceScaleFactor1_ScrollChild_DelegatingRenderer
) {
678 device_scale_factor_
= 1.f
;
679 scroll_child_layer_
= true;
680 RunTest(true, true, true);
683 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
684 DeviceScaleFactor15_ScrollChild_DirectRenderer
) {
685 device_scale_factor_
= 1.5f
;
686 scroll_child_layer_
= true;
687 RunTest(true, false, true);
690 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
691 DeviceScaleFactor15_ScrollChild_DelegatingRenderer
) {
692 device_scale_factor_
= 1.5f
;
693 scroll_child_layer_
= true;
694 RunTest(true, true, true);
697 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
698 DeviceScaleFactor2_ScrollChild_DirectRenderer
) {
699 device_scale_factor_
= 2.f
;
700 scroll_child_layer_
= true;
701 RunTest(true, false, true);
704 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
705 DeviceScaleFactor2_ScrollChild_DelegatingRenderer
) {
706 device_scale_factor_
= 2.f
;
707 scroll_child_layer_
= true;
708 RunTest(true, true, true);
711 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
712 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer
) {
713 device_scale_factor_
= 1.f
;
714 scroll_child_layer_
= false;
715 RunTest(true, false, true);
718 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
719 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer
) {
720 device_scale_factor_
= 1.f
;
721 scroll_child_layer_
= false;
722 RunTest(true, true, true);
725 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
726 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer
) {
727 device_scale_factor_
= 1.5f
;
728 scroll_child_layer_
= false;
729 RunTest(true, false, true);
732 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
733 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer
) {
734 device_scale_factor_
= 1.5f
;
735 scroll_child_layer_
= false;
736 RunTest(true, true, true);
739 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
740 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer
) {
741 device_scale_factor_
= 2.f
;
742 scroll_child_layer_
= false;
743 RunTest(true, false, true);
746 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
747 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer
) {
748 device_scale_factor_
= 2.f
;
749 scroll_child_layer_
= false;
750 RunTest(true, true, true);
753 class ImplSidePaintingScrollTest
: public LayerTreeHostScrollTest
{
755 void InitializeSettings(LayerTreeSettings
* settings
) override
{
756 settings
->impl_side_painting
= true;
759 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
760 if (impl
->pending_tree())
761 impl
->SetNeedsRedraw();
765 class ImplSidePaintingScrollTestSimple
: public ImplSidePaintingScrollTest
{
767 ImplSidePaintingScrollTestSimple()
768 : initial_scroll_(10, 20),
769 main_thread_scroll_(40, 5),
770 impl_thread_scroll1_(2, -1),
771 impl_thread_scroll2_(-3, 10),
774 void SetupTree() override
{
775 LayerTreeHostScrollTest::SetupTree();
776 Layer
* root_layer
= layer_tree_host()->root_layer();
777 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
778 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
779 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
780 root_scroll_layer
->SetBounds(
781 gfx::Size(root_layer
->bounds().width() + 100,
782 root_layer
->bounds().height() + 100));
783 root_scroll_layer
->SetIsDrawable(true);
784 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
785 root_layer
->AddChild(root_scroll_layer
);
787 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
788 root_scroll_layer
, NULL
);
789 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
792 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
794 void Layout() override
{
795 Layer
* root
= layer_tree_host()->root_layer();
796 Layer
* scroll_layer
= root
->children()[0].get();
797 if (!layer_tree_host()->source_frame_number()) {
798 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
801 scroll_layer
->scroll_offset(),
802 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_thread_scroll1_
));
804 // Pretend like Javascript updated the scroll position itself with a
805 // change of main_thread_scroll.
806 scroll_layer
->SetScrollOffset(
807 gfx::ScrollOffsetWithDelta(
808 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
812 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
813 // We force a second draw here of the first commit before activating
814 // the second commit.
815 if (impl
->active_tree()->source_frame_number() == 0)
816 impl
->SetNeedsRedraw();
819 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
820 ImplSidePaintingScrollTest::DrawLayersOnThread(impl
);
822 LayerImpl
* root
= impl
->active_tree()->root_layer();
823 LayerImpl
* scroll_layer
= root
->children()[0];
824 LayerImpl
* pending_root
=
825 impl
->active_tree()->FindPendingTreeLayerById(root
->id());
827 switch (impl
->active_tree()->source_frame_number()) {
829 if (!impl
->pending_tree()) {
830 impl
->BlockNotifyReadyToActivateForTesting(true);
831 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
832 scroll_layer
->ScrollBy(impl_thread_scroll1_
);
834 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
835 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll1_
);
836 PostSetNeedsCommitToMainThread();
838 // CommitCompleteOnThread will trigger this function again
839 // and cause us to take the else clause.
841 impl
->BlockNotifyReadyToActivateForTesting(false);
842 ASSERT_TRUE(pending_root
);
843 EXPECT_EQ(impl
->pending_tree()->source_frame_number(), 1);
845 scroll_layer
->ScrollBy(impl_thread_scroll2_
);
846 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
847 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
848 impl_thread_scroll1_
+ impl_thread_scroll2_
);
850 LayerImpl
* pending_scroll_layer
= pending_root
->children()[0];
852 pending_scroll_layer
->BaseScrollOffset(),
853 gfx::ScrollOffsetWithDelta(
854 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
855 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(),
856 impl_thread_scroll2_
);
860 EXPECT_FALSE(impl
->pending_tree());
862 scroll_layer
->BaseScrollOffset(),
863 gfx::ScrollOffsetWithDelta(
864 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
865 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll2_
);
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), impl_scale_(2.f
) {}
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(NULL
, root_layer
,
913 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_
);
943 impl
->SetPageScaleOnActiveTree(impl_scale_
);
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
->BaseScrollOffset(),
962 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(), gfx::Vector2d());
963 EXPECT_FALSE(active_root
);
966 // Even though the scroll happened during the commit, both layers
967 // should have the appropriate scroll delta.
968 EXPECT_VECTOR_EQ(pending_scroll_layer
->BaseScrollOffset(),
970 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(),
971 impl_thread_scroll_
);
972 ASSERT_TRUE(active_root
);
973 EXPECT_VECTOR_EQ(active_scroll_layer
->BaseScrollOffset(),
975 EXPECT_VECTOR_EQ(active_scroll_layer
->ScrollDelta(),
976 impl_thread_scroll_
);
979 // On the next commit, this delta should have been sent and applied.
981 pending_scroll_layer
->BaseScrollOffset(),
982 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_thread_scroll_
));
983 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(), gfx::Vector2d());
988 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
989 ImplSidePaintingScrollTest::DrawLayersOnThread(impl
);
991 LayerImpl
* root
= impl
->active_tree()->root_layer();
992 LayerImpl
* scroll_layer
= root
->children()[0];
994 switch (impl
->active_tree()->source_frame_number()) {
996 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
997 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
998 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
999 EXPECT_EQ(1.f
, impl
->active_tree()->current_page_scale_factor());
1000 PostSetNeedsCommitToMainThread();
1003 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
1004 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll_
);
1005 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
1006 EXPECT_EQ(impl_scale_
,
1007 impl
->active_tree()->current_page_scale_factor());
1008 PostSetNeedsCommitToMainThread();
1011 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
1012 EXPECT_EQ(impl_scale_
,
1013 impl
->active_tree()->current_page_scale_factor());
1019 void AfterTest() override
{}
1022 gfx::ScrollOffset initial_scroll_
;
1023 gfx::Vector2dF impl_thread_scroll_
;
1027 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll
);
1029 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
1030 : public LayerTreeHostScrollTest
{
1032 LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
1034 void SetupTree() override
{
1035 LayerTreeTest::SetupTree();
1036 scoped_refptr
<Layer
> scroll_layer
= Layer::Create();
1037 layer_tree_host()->root_layer()->AddChild(scroll_layer
);
1040 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1042 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
1043 LayerImpl
* root
= impl
->active_tree()->root_layer();
1044 LayerImpl
* scroll_layer
= root
->children()[0];
1045 scroll_layer
->SetScrollClipLayer(root
->id());
1047 // Set max_scroll_offset = (100, 100).
1048 scroll_layer
->SetBounds(
1049 gfx::Size(root
->bounds().width() + 100, root
->bounds().height() + 100));
1051 InputHandler::SCROLL_STARTED
,
1052 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
), InputHandler::GESTURE
,
1053 SCROLL_BLOCKS_ON_NONE
));
1055 // Set max_scroll_offset = (0, 0).
1056 scroll_layer
->SetBounds(root
->bounds());
1058 InputHandler::SCROLL_IGNORED
,
1059 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
), InputHandler::GESTURE
,
1060 SCROLL_BLOCKS_ON_NONE
));
1062 // Set max_scroll_offset = (-100, -100).
1063 scroll_layer
->SetBounds(gfx::Size());
1065 InputHandler::SCROLL_IGNORED
,
1066 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
), InputHandler::GESTURE
,
1067 SCROLL_BLOCKS_ON_NONE
));
1072 void AfterTest() override
{}
1075 SINGLE_AND_MULTI_THREAD_TEST_F(
1076 LayerTreeHostScrollTestScrollZeroMaxScrollOffset
);
1078 class ThreadCheckingInputHandlerClient
: public InputHandlerClient
{
1080 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner
* runner
,
1081 bool* received_stop_flinging
)
1082 : task_runner_(runner
), received_stop_flinging_(received_stop_flinging
) {}
1084 void WillShutdown() override
{
1085 if (!received_stop_flinging_
)
1086 ADD_FAILURE() << "WillShutdown() called before fling stopped";
1089 void Animate(base::TimeTicks time
) override
{
1090 if (!task_runner_
->BelongsToCurrentThread())
1091 ADD_FAILURE() << "Animate called on wrong thread";
1094 void MainThreadHasStoppedFlinging() override
{
1095 if (!task_runner_
->BelongsToCurrentThread())
1096 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
1097 *received_stop_flinging_
= true;
1100 void ReconcileElasticOverscrollAndRootScroll() override
{
1101 if (!task_runner_
->BelongsToCurrentThread()) {
1102 ADD_FAILURE() << "ReconcileElasticOverscrollAndRootScroll called on "
1108 base::SingleThreadTaskRunner
* task_runner_
;
1109 bool* received_stop_flinging_
;
1112 void BindInputHandlerOnCompositorThread(
1113 const base::WeakPtr
<InputHandler
>& input_handler
,
1114 ThreadCheckingInputHandlerClient
* client
) {
1115 input_handler
->BindToClient(client
);
1118 TEST(LayerTreeHostFlingTest
, DidStopFlingingThread
) {
1119 base::Thread
impl_thread("cc");
1120 ASSERT_TRUE(impl_thread
.Start());
1122 bool received_stop_flinging
= false;
1123 LayerTreeSettings settings
;
1125 ThreadCheckingInputHandlerClient
input_handler_client(
1126 impl_thread
.task_runner().get(), &received_stop_flinging
);
1127 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1129 ASSERT_TRUE(impl_thread
.task_runner().get());
1130 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1131 new TestSharedBitmapManager());
1133 LayerTreeHost::InitParams params
;
1134 params
.client
= &client
;
1135 params
.shared_bitmap_manager
= shared_bitmap_manager
.get();
1136 params
.settings
= &settings
;
1137 params
.main_task_runner
= base::ThreadTaskRunnerHandle::Get();
1138 scoped_ptr
<LayerTreeHost
> layer_tree_host
=
1139 LayerTreeHost::CreateThreaded(impl_thread
.task_runner(), ¶ms
);
1141 impl_thread
.task_runner()->PostTask(
1142 FROM_HERE
, base::Bind(&BindInputHandlerOnCompositorThread
,
1143 layer_tree_host
->GetInputHandler(),
1144 base::Unretained(&input_handler_client
)));
1146 layer_tree_host
->DidStopFlinging();
1147 layer_tree_host
= nullptr;
1149 EXPECT_TRUE(received_stop_flinging
);
1152 class LayerTreeHostScrollTestLayerStructureChange
1153 : public LayerTreeHostScrollTest
{
1155 LayerTreeHostScrollTestLayerStructureChange()
1156 : scroll_destroy_whole_tree_(false) {}
1158 void SetupTree() override
{
1159 scoped_refptr
<Layer
> root_layer
= Layer::Create();
1160 root_layer
->SetBounds(gfx::Size(10, 10));
1162 Layer
* root_scroll_layer
=
1163 CreateScrollLayer(root_layer
.get(), &root_scroll_layer_client_
);
1164 CreateScrollLayer(root_layer
.get(), &sibling_scroll_layer_client_
);
1165 CreateScrollLayer(root_scroll_layer
, &child_scroll_layer_client_
);
1167 layer_tree_host()->SetRootLayer(root_layer
);
1168 LayerTreeHostScrollTest::SetupTree();
1171 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1173 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
1174 LayerImpl
* root
= impl
->active_tree()->root_layer();
1175 switch (impl
->active_tree()->source_frame_number()) {
1177 root
->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1178 root
->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1179 root
->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5));
1180 PostSetNeedsCommitToMainThread();
1188 void AfterTest() override
{}
1190 virtual void DidScroll(Layer
* layer
) {
1191 if (scroll_destroy_whole_tree_
) {
1192 layer_tree_host()->SetRootLayer(NULL
);
1196 layer
->RemoveFromParent();
1200 class FakeLayerScrollClient
{
1203 owner_
->DidScroll(layer_
);
1205 LayerTreeHostScrollTestLayerStructureChange
* owner_
;
1209 Layer
* CreateScrollLayer(Layer
* parent
, FakeLayerScrollClient
* client
) {
1210 scoped_refptr
<PictureLayer
> scroll_layer
=
1211 PictureLayer::Create(&fake_content_layer_client_
);
1212 scroll_layer
->SetBounds(gfx::Size(110, 110));
1213 scroll_layer
->SetPosition(gfx::Point(0, 0));
1214 scroll_layer
->SetIsDrawable(true);
1215 scroll_layer
->SetScrollClipLayerId(parent
->id());
1216 scroll_layer
->SetBounds(gfx::Size(parent
->bounds().width() + 100,
1217 parent
->bounds().height() + 100));
1218 scroll_layer
->set_did_scroll_callback(base::Bind(
1219 &FakeLayerScrollClient::DidScroll
, base::Unretained(client
)));
1220 client
->owner_
= this;
1221 client
->layer_
= scroll_layer
.get();
1222 parent
->AddChild(scroll_layer
);
1223 return scroll_layer
.get();
1226 FakeLayerScrollClient root_scroll_layer_client_
;
1227 FakeLayerScrollClient sibling_scroll_layer_client_
;
1228 FakeLayerScrollClient child_scroll_layer_client_
;
1230 FakeContentLayerClient fake_content_layer_client_
;
1232 bool scroll_destroy_whole_tree_
;
1235 TEST_F(LayerTreeHostScrollTestLayerStructureChange
, ScrollDestroyLayer
) {
1236 RunTest(true, false, true);
1239 TEST_F(LayerTreeHostScrollTestLayerStructureChange
, ScrollDestroyWholeTree
) {
1240 scroll_destroy_whole_tree_
= true;
1241 RunTest(true, false, true);