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(layer_settings());
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::Vector2dF
& inner_delta
,
96 const gfx::Vector2dF
& outer_delta
,
97 const gfx::Vector2dF
& elastic_overscroll_delta
,
99 float top_controls_delta
) override
{
103 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
106 gfx::ScrollOffset initial_scroll_
;
107 gfx::ScrollOffset second_scroll_
;
108 gfx::Vector2dF scroll_amount_
;
112 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple
);
114 class LayerTreeHostScrollTestScrollMultipleRedraw
115 : public LayerTreeHostScrollTest
{
117 LayerTreeHostScrollTestScrollMultipleRedraw()
118 : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
120 void BeginTest() override
{
121 Layer
* root_layer
= layer_tree_host()->root_layer();
122 scroll_layer_
= Layer::Create(layer_settings());
123 root_layer
->AddChild(scroll_layer_
);
124 // Create an effective max_scroll_offset of (100, 100).
125 scroll_layer_
->SetBounds(gfx::Size(root_layer
->bounds().width() + 100,
126 root_layer
->bounds().height() + 100));
127 scroll_layer_
->SetIsDrawable(true);
128 scroll_layer_
->SetIsContainerForFixedPositionLayers(true);
129 scroll_layer_
->SetScrollClipLayerId(root_layer
->id());
130 scroll_layer_
->SetScrollOffset(initial_scroll_
);
131 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
, scroll_layer_
,
133 PostSetNeedsCommitToMainThread();
136 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
137 switch (layer_tree_host()->source_frame_number()) {
139 EXPECT_VECTOR_EQ(scroll_layer_
->scroll_offset(), initial_scroll_
);
143 scroll_layer_
->scroll_offset(),
144 gfx::ScrollOffsetWithDelta(initial_scroll_
,
145 scroll_amount_
+ scroll_amount_
));
148 scroll_layer_
->scroll_offset(),
149 gfx::ScrollOffsetWithDelta(initial_scroll_
,
150 scroll_amount_
+ scroll_amount_
));
155 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
156 LayerImpl
* scroll_layer
=
157 impl
->active_tree()->LayerById(scroll_layer_
->id());
158 if (impl
->active_tree()->source_frame_number() == 0 &&
159 impl
->SourceAnimationFrameNumber() == 1) {
160 // First draw after first commit.
161 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
162 scroll_layer
->ScrollBy(scroll_amount_
);
163 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
165 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
166 PostSetNeedsRedrawToMainThread();
167 } else if (impl
->active_tree()->source_frame_number() == 0 &&
168 impl
->SourceAnimationFrameNumber() == 2) {
169 // Second draw after first commit.
170 EXPECT_EQ(scroll_layer
->ScrollDelta(), scroll_amount_
);
171 scroll_layer
->ScrollBy(scroll_amount_
);
172 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
173 scroll_amount_
+ scroll_amount_
);
175 EXPECT_VECTOR_EQ(scroll_layer_
->scroll_offset(), initial_scroll_
);
176 PostSetNeedsCommitToMainThread();
177 } else if (impl
->active_tree()->source_frame_number() == 1) {
178 // Third or later draw after second commit.
179 EXPECT_GE(impl
->SourceAnimationFrameNumber(), 3);
180 EXPECT_VECTOR_EQ(scroll_layer_
->ScrollDelta(), gfx::Vector2d());
182 scroll_layer_
->scroll_offset(),
183 gfx::ScrollOffsetWithDelta(initial_scroll_
,
184 scroll_amount_
+ scroll_amount_
));
189 void ApplyViewportDeltas(const gfx::Vector2dF
& inner_delta
,
190 const gfx::Vector2dF
& outer_delta
,
191 const gfx::Vector2dF
& elastic_overscroll_delta
,
193 float top_controls_delta
) override
{
197 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
200 gfx::ScrollOffset initial_scroll_
;
201 gfx::Vector2dF scroll_amount_
;
203 scoped_refptr
<Layer
> scroll_layer_
;
206 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw
);
208 class LayerTreeHostScrollTestScrollAbortedCommit
209 : public LayerTreeHostScrollTest
{
211 LayerTreeHostScrollTestScrollAbortedCommit()
212 : initial_scroll_(50, 60),
214 second_main_scroll_(14, -3),
216 num_will_begin_main_frames_(0),
217 num_did_begin_main_frames_(0),
218 num_will_commits_(0),
220 num_impl_commits_(0),
221 num_impl_scrolls_(0) {}
223 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
225 void SetupTree() override
{
226 LayerTreeHostScrollTest::SetupTree();
227 Layer
* root_layer
= layer_tree_host()->root_layer();
228 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create(layer_settings());
229 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
230 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
231 root_scroll_layer
->SetBounds(gfx::Size(200, 200));
232 root_scroll_layer
->SetIsDrawable(true);
233 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
234 root_layer
->AddChild(root_scroll_layer
);
236 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
237 root_scroll_layer
, NULL
);
238 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
241 void WillBeginMainFrame() override
{
242 num_will_begin_main_frames_
++;
243 Layer
* root_scroll_layer
=
244 layer_tree_host()->root_layer()->children()[0].get();
245 switch (num_will_begin_main_frames_
) {
247 // This will not be aborted because of the initial prop changes.
248 EXPECT_EQ(0, num_impl_scrolls_
);
249 EXPECT_EQ(0, layer_tree_host()->source_frame_number());
250 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(), initial_scroll_
);
251 EXPECT_EQ(1.f
, layer_tree_host()->page_scale_factor());
254 // This commit will be aborted, and another commit will be
255 // initiated from the redraw.
256 EXPECT_EQ(1, num_impl_scrolls_
);
257 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
259 root_scroll_layer
->scroll_offset(),
260 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_scroll_
));
261 EXPECT_EQ(impl_scale_
, layer_tree_host()->page_scale_factor());
262 PostSetNeedsRedrawToMainThread();
265 // This commit will not be aborted because of the scroll change.
266 EXPECT_EQ(2, num_impl_scrolls_
);
267 // The source frame number still increases even with the abort.
268 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
270 root_scroll_layer
->scroll_offset(),
271 gfx::ScrollOffsetWithDelta(initial_scroll_
,
272 impl_scroll_
+ impl_scroll_
));
273 EXPECT_EQ(impl_scale_
* impl_scale_
,
274 layer_tree_host()->page_scale_factor());
275 root_scroll_layer
->SetScrollOffset(gfx::ScrollOffsetWithDelta(
276 root_scroll_layer
->scroll_offset(), second_main_scroll_
));
279 // This commit will also be aborted.
280 EXPECT_EQ(3, num_impl_scrolls_
);
281 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
282 gfx::Vector2dF delta
=
283 impl_scroll_
+ impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
284 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
285 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
287 // End the test by drawing to verify this commit is also aborted.
288 PostSetNeedsRedrawToMainThread();
293 void DidBeginMainFrame() override
{ num_did_begin_main_frames_
++; }
295 void WillCommit() override
{ num_will_commits_
++; }
297 void DidCommit() override
{ num_did_commits_
++; }
299 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
303 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
304 LayerImpl
* root_scroll_layer
=
305 impl
->active_tree()->root_layer()->children()[0];
307 if (impl
->active_tree()->source_frame_number() == 0 &&
308 impl
->SourceAnimationFrameNumber() == 1) {
310 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
311 root_scroll_layer
->ScrollBy(impl_scroll_
);
312 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
313 EXPECT_VECTOR_EQ(root_scroll_layer
->BaseScrollOffset(), initial_scroll_
);
315 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
316 EXPECT_EQ(1.f
, impl
->active_tree()->current_page_scale_factor());
317 impl
->SetPageScaleOnActiveTree(impl_scale_
);
318 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
319 EXPECT_EQ(impl_scale_
, impl
->active_tree()->current_page_scale_factor());
321 // To simplify the testing flow, don't redraw here, just commit.
322 impl
->SetNeedsCommit();
323 } else if (impl
->active_tree()->source_frame_number() == 0 &&
324 impl
->SourceAnimationFrameNumber() == 2) {
325 // Test a second draw after an aborted commit.
326 // The scroll/scale values should be baked into the offset/scale factor
327 // since the main thread consumed but aborted the begin frame.
328 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
329 root_scroll_layer
->ScrollBy(impl_scroll_
);
330 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
332 root_scroll_layer
->BaseScrollOffset(),
333 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_scroll_
));
335 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
336 EXPECT_EQ(impl_scale_
, impl
->active_tree()->current_page_scale_factor());
337 impl
->SetPageScaleOnActiveTree(impl_scale_
* impl_scale_
);
338 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
339 EXPECT_EQ(impl_scale_
* impl_scale_
,
340 impl
->active_tree()->current_page_scale_factor());
342 impl
->SetNeedsCommit();
343 } else if (impl
->active_tree()->source_frame_number() == 1) {
344 // Commit for source frame 1 is aborted.
346 } else if (impl
->active_tree()->source_frame_number() == 2 &&
347 impl
->SourceAnimationFrameNumber() == 3) {
348 // Third draw after the second full commit.
349 EXPECT_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
350 root_scroll_layer
->ScrollBy(impl_scroll_
);
351 impl
->SetNeedsCommit();
352 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
353 gfx::Vector2dF delta
= impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
354 EXPECT_VECTOR_EQ(root_scroll_layer
->BaseScrollOffset(),
355 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
356 } else if (impl
->active_tree()->source_frame_number() == 2 &&
357 impl
->SourceAnimationFrameNumber() == 4) {
358 // Final draw after the second aborted commit.
359 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
360 gfx::Vector2dF delta
=
361 impl_scroll_
+ impl_scroll_
+ impl_scroll_
+ second_main_scroll_
;
362 EXPECT_VECTOR_EQ(root_scroll_layer
->BaseScrollOffset(),
363 gfx::ScrollOffsetWithDelta(initial_scroll_
, delta
));
366 // Commit for source frame 3 is aborted.
371 void ApplyViewportDeltas(const gfx::Vector2dF
& inner_delta
,
372 const gfx::Vector2dF
& outer_delta
,
373 const gfx::Vector2dF
& elastic_overscroll_delta
,
375 float top_controls_delta
) override
{
379 void AfterTest() override
{
380 EXPECT_EQ(3, num_impl_scrolls_
);
381 // Verify that the embedder sees aborted commits as real commits.
382 EXPECT_EQ(4, num_will_begin_main_frames_
);
383 EXPECT_EQ(4, num_did_begin_main_frames_
);
384 EXPECT_EQ(4, num_will_commits_
);
385 EXPECT_EQ(4, num_did_commits_
);
386 // ...but the compositor thread only sees two real ones.
387 EXPECT_EQ(2, num_impl_commits_
);
391 gfx::ScrollOffset initial_scroll_
;
392 gfx::Vector2dF impl_scroll_
;
393 gfx::Vector2dF second_main_scroll_
;
395 int num_will_begin_main_frames_
;
396 int num_did_begin_main_frames_
;
397 int num_will_commits_
;
398 int num_did_commits_
;
399 int num_impl_commits_
;
400 int num_impl_scrolls_
;
403 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit
);
405 class LayerTreeHostScrollTestFractionalScroll
: public LayerTreeHostScrollTest
{
407 LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
409 void SetupTree() override
{
410 LayerTreeHostScrollTest::SetupTree();
411 Layer
* root_layer
= layer_tree_host()->root_layer();
412 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create(layer_settings());
413 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
414 root_scroll_layer
->SetBounds(
415 gfx::Size(root_layer
->bounds().width() + 100,
416 root_layer
->bounds().height() + 100));
417 root_scroll_layer
->SetIsDrawable(true);
418 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
419 root_layer
->AddChild(root_scroll_layer
);
421 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
422 root_scroll_layer
, NULL
);
423 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
426 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
428 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
429 LayerImpl
* root
= impl
->active_tree()->root_layer();
430 LayerImpl
* scroll_layer
= root
->children()[0];
432 // Check that a fractional scroll delta is correctly accumulated over
434 switch (impl
->active_tree()->source_frame_number()) {
436 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), gfx::Vector2d(0, 0));
437 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d(0, 0));
438 PostSetNeedsCommitToMainThread();
441 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(),
442 gfx::ToFlooredVector2d(scroll_amount_
));
443 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
444 gfx::Vector2dF(fmod(scroll_amount_
.x(), 1.0f
), 0.0f
));
445 PostSetNeedsCommitToMainThread();
449 scroll_layer
->BaseScrollOffset(),
450 gfx::ToFlooredVector2d(scroll_amount_
+ scroll_amount_
));
452 scroll_layer
->ScrollDelta(),
453 gfx::Vector2dF(fmod(2.0f
* scroll_amount_
.x(), 1.0f
), 0.0f
));
457 scroll_layer
->ScrollBy(scroll_amount_
);
460 void AfterTest() override
{}
463 gfx::Vector2dF scroll_amount_
;
466 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll
);
468 class LayerTreeHostScrollTestCaseWithChild
: public LayerTreeHostScrollTest
{
470 LayerTreeHostScrollTestCaseWithChild()
471 : initial_offset_(10, 20),
472 javascript_scroll_(40, 5),
473 scroll_amount_(2, -1),
476 void SetupTree() override
{
477 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_
);
479 scoped_refptr
<Layer
> root_layer
= Layer::Create(layer_settings());
480 root_layer
->SetBounds(gfx::Size(10, 10));
483 FakePictureLayer::Create(layer_settings(), &fake_content_layer_client_
);
484 root_scroll_layer_
->SetBounds(gfx::Size(110, 110));
486 root_scroll_layer_
->SetPosition(gfx::Point());
488 root_scroll_layer_
->SetIsDrawable(true);
489 root_scroll_layer_
->SetScrollClipLayerId(root_layer
->id());
490 root_scroll_layer_
->SetIsContainerForFixedPositionLayers(true);
491 root_layer
->AddChild(root_scroll_layer_
);
494 FakePictureLayer::Create(layer_settings(), &fake_content_layer_client_
);
495 child_layer_
->set_did_scroll_callback(
496 base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll
,
497 base::Unretained(this)));
498 child_layer_
->SetBounds(gfx::Size(110, 110));
500 if (scroll_child_layer_
) {
501 // Scrolls on the child layer will happen at 5, 5. If they are treated
502 // like device pixels, and device scale factor is 2, then they will
503 // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
504 child_layer_
->SetPosition(gfx::Point(5, 5));
506 // Adjust the child layer horizontally so that scrolls will never hit it.
507 child_layer_
->SetPosition(gfx::Point(60, 5));
510 child_layer_
->SetIsDrawable(true);
511 child_layer_
->SetScrollClipLayerId(root_layer
->id());
512 child_layer_
->SetBounds(root_scroll_layer_
->bounds());
513 root_scroll_layer_
->AddChild(child_layer_
);
515 if (scroll_child_layer_
) {
516 expected_scroll_layer_
= child_layer_
;
517 expected_no_scroll_layer_
= root_scroll_layer_
;
519 expected_scroll_layer_
= root_scroll_layer_
;
520 expected_no_scroll_layer_
= child_layer_
;
523 expected_scroll_layer_
->SetScrollOffset(initial_offset_
);
525 layer_tree_host()->SetRootLayer(root_layer
);
526 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
527 root_scroll_layer_
, NULL
);
528 LayerTreeHostScrollTest::SetupTree();
531 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
533 void WillCommit() override
{
534 // Keep the test committing (otherwise the early out for no update
535 // will stall the test).
536 if (layer_tree_host()->source_frame_number() < 2) {
537 layer_tree_host()->SetNeedsCommit();
542 final_scroll_offset_
= expected_scroll_layer_
->scroll_offset();
545 void ApplyViewportDeltas(const gfx::Vector2dF
& inner_delta
,
546 const gfx::Vector2dF
& outer_delta
,
547 const gfx::Vector2dF
& elastic_overscroll_delta
,
549 float top_controls_delta
) override
{
553 void Layout() override
{
554 EXPECT_VECTOR_EQ(gfx::Vector2d(),
555 expected_no_scroll_layer_
->scroll_offset());
557 switch (layer_tree_host()->source_frame_number()) {
559 EXPECT_VECTOR_EQ(initial_offset_
,
560 expected_scroll_layer_
->scroll_offset());
564 gfx::ScrollOffsetWithDelta(initial_offset_
, scroll_amount_
),
565 expected_scroll_layer_
->scroll_offset());
567 // Pretend like Javascript updated the scroll position itself.
568 expected_scroll_layer_
->SetScrollOffset(javascript_scroll_
);
571 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_
,
573 expected_scroll_layer_
->scroll_offset());
578 void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) override
{
579 LayerImpl
* root_impl
= impl
->active_tree()->root_layer();
580 FakePictureLayerImpl
* root_scroll_layer_impl
=
581 static_cast<FakePictureLayerImpl
*>(root_impl
->children()[0]);
582 FakePictureLayerImpl
* child_layer_impl
= static_cast<FakePictureLayerImpl
*>(
583 root_scroll_layer_impl
->children()[0]);
585 LayerImpl
* expected_scroll_layer_impl
= NULL
;
586 LayerImpl
* expected_no_scroll_layer_impl
= NULL
;
587 if (scroll_child_layer_
) {
588 expected_scroll_layer_impl
= child_layer_impl
;
589 expected_no_scroll_layer_impl
= root_scroll_layer_impl
;
591 expected_scroll_layer_impl
= root_scroll_layer_impl
;
592 expected_no_scroll_layer_impl
= child_layer_impl
;
595 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl
->ScrollDelta());
596 EXPECT_VECTOR_EQ(gfx::Vector2d(),
597 expected_no_scroll_layer_impl
->ScrollDelta());
599 // Ensure device scale factor matches the active tree.
600 EXPECT_EQ(device_scale_factor_
, impl
->active_tree()->device_scale_factor());
601 switch (impl
->active_tree()->source_frame_number()) {
603 // GESTURE scroll on impl thread.
604 InputHandler::ScrollStatus status
= impl
->ScrollBegin(
605 gfx::ToCeiledPoint(expected_scroll_layer_impl
->position() -
606 gfx::Vector2dF(0.5f
, 0.5f
)),
607 InputHandler::GESTURE
);
608 EXPECT_EQ(InputHandler::SCROLL_STARTED
, status
);
609 impl
->ScrollBy(gfx::Point(), scroll_amount_
);
612 // Check the scroll is applied as a delta.
613 EXPECT_VECTOR_EQ(initial_offset_
,
614 expected_scroll_layer_impl
->BaseScrollOffset());
615 EXPECT_VECTOR_EQ(scroll_amount_
,
616 expected_scroll_layer_impl
->ScrollDelta());
620 // WHEEL scroll on impl thread.
621 InputHandler::ScrollStatus status
= impl
->ScrollBegin(
622 gfx::ToCeiledPoint(expected_scroll_layer_impl
->position() +
623 gfx::Vector2dF(0.5f
, 0.5f
)),
624 InputHandler::WHEEL
);
625 EXPECT_EQ(InputHandler::SCROLL_STARTED
, status
);
626 impl
->ScrollBy(gfx::Point(), scroll_amount_
);
629 // Check the scroll is applied as a delta.
630 EXPECT_VECTOR_EQ(javascript_scroll_
,
631 expected_scroll_layer_impl
->BaseScrollOffset());
632 EXPECT_VECTOR_EQ(scroll_amount_
,
633 expected_scroll_layer_impl
->ScrollDelta());
639 gfx::ScrollOffsetWithDelta(javascript_scroll_
, scroll_amount_
),
640 expected_scroll_layer_impl
->BaseScrollOffset());
641 EXPECT_VECTOR_EQ(gfx::Vector2d(),
642 expected_scroll_layer_impl
->ScrollDelta());
649 void AfterTest() override
{
650 if (scroll_child_layer_
) {
651 EXPECT_EQ(0, num_scrolls_
);
652 EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_
,
654 final_scroll_offset_
);
656 EXPECT_EQ(2, num_scrolls_
);
657 EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_
);
662 float device_scale_factor_
;
663 bool scroll_child_layer_
;
665 gfx::ScrollOffset initial_offset_
;
666 gfx::ScrollOffset javascript_scroll_
;
667 gfx::Vector2d scroll_amount_
;
669 gfx::ScrollOffset final_scroll_offset_
;
671 FakeContentLayerClient fake_content_layer_client_
;
673 scoped_refptr
<Layer
> root_scroll_layer_
;
674 scoped_refptr
<Layer
> child_layer_
;
675 scoped_refptr
<Layer
> expected_scroll_layer_
;
676 scoped_refptr
<Layer
> expected_no_scroll_layer_
;
679 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
680 DeviceScaleFactor1_ScrollChild_DirectRenderer
) {
681 device_scale_factor_
= 1.f
;
682 scroll_child_layer_
= true;
683 RunTest(true, false, true);
686 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
687 DeviceScaleFactor1_ScrollChild_DelegatingRenderer
) {
688 device_scale_factor_
= 1.f
;
689 scroll_child_layer_
= true;
690 RunTest(true, true, true);
693 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
694 DeviceScaleFactor15_ScrollChild_DirectRenderer
) {
695 device_scale_factor_
= 1.5f
;
696 scroll_child_layer_
= true;
697 RunTest(true, false, true);
700 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
701 DeviceScaleFactor15_ScrollChild_DelegatingRenderer
) {
702 device_scale_factor_
= 1.5f
;
703 scroll_child_layer_
= true;
704 RunTest(true, true, true);
707 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
708 DeviceScaleFactor2_ScrollChild_DirectRenderer
) {
709 device_scale_factor_
= 2.f
;
710 scroll_child_layer_
= true;
711 RunTest(true, false, true);
714 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
715 DeviceScaleFactor2_ScrollChild_DelegatingRenderer
) {
716 device_scale_factor_
= 2.f
;
717 scroll_child_layer_
= true;
718 RunTest(true, true, true);
721 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
722 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer
) {
723 device_scale_factor_
= 1.f
;
724 scroll_child_layer_
= false;
725 RunTest(true, false, true);
728 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
729 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer
) {
730 device_scale_factor_
= 1.f
;
731 scroll_child_layer_
= false;
732 RunTest(true, true, true);
735 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
736 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer
) {
737 device_scale_factor_
= 1.5f
;
738 scroll_child_layer_
= false;
739 RunTest(true, false, true);
742 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
743 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer
) {
744 device_scale_factor_
= 1.5f
;
745 scroll_child_layer_
= false;
746 RunTest(true, true, true);
749 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
750 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer
) {
751 device_scale_factor_
= 2.f
;
752 scroll_child_layer_
= false;
753 RunTest(true, false, true);
756 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
757 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer
) {
758 device_scale_factor_
= 2.f
;
759 scroll_child_layer_
= false;
760 RunTest(true, true, true);
763 class ImplSidePaintingScrollTest
: public LayerTreeHostScrollTest
{
765 void InitializeSettings(LayerTreeSettings
* settings
) override
{
766 settings
->impl_side_painting
= true;
769 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
770 if (impl
->pending_tree())
771 impl
->SetNeedsRedraw();
775 class ImplSidePaintingScrollTestSimple
: public ImplSidePaintingScrollTest
{
777 ImplSidePaintingScrollTestSimple()
778 : initial_scroll_(10, 20),
779 main_thread_scroll_(40, 5),
780 impl_thread_scroll1_(2, -1),
781 impl_thread_scroll2_(-3, 10),
784 void SetupTree() override
{
785 LayerTreeHostScrollTest::SetupTree();
786 Layer
* root_layer
= layer_tree_host()->root_layer();
787 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create(layer_settings());
788 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
789 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
790 root_scroll_layer
->SetBounds(
791 gfx::Size(root_layer
->bounds().width() + 100,
792 root_layer
->bounds().height() + 100));
793 root_scroll_layer
->SetIsDrawable(true);
794 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
795 root_layer
->AddChild(root_scroll_layer
);
797 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
798 root_scroll_layer
, NULL
);
799 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
802 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
804 void Layout() override
{
805 Layer
* root
= layer_tree_host()->root_layer();
806 Layer
* scroll_layer
= root
->children()[0].get();
807 if (!layer_tree_host()->source_frame_number()) {
808 EXPECT_VECTOR_EQ(scroll_layer
->scroll_offset(), initial_scroll_
);
811 scroll_layer
->scroll_offset(),
812 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_thread_scroll1_
));
814 // Pretend like Javascript updated the scroll position itself with a
815 // change of main_thread_scroll.
816 scroll_layer
->SetScrollOffset(
817 gfx::ScrollOffsetWithDelta(
818 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
822 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
823 // We force a second draw here of the first commit before activating
824 // the second commit.
825 if (impl
->active_tree()->source_frame_number() == 0)
826 impl
->SetNeedsRedraw();
829 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
830 ImplSidePaintingScrollTest::DrawLayersOnThread(impl
);
832 LayerImpl
* root
= impl
->active_tree()->root_layer();
833 LayerImpl
* scroll_layer
= root
->children()[0];
834 LayerImpl
* pending_root
=
835 impl
->active_tree()->FindPendingTreeLayerById(root
->id());
837 switch (impl
->active_tree()->source_frame_number()) {
839 if (!impl
->pending_tree()) {
840 impl
->BlockNotifyReadyToActivateForTesting(true);
841 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
842 scroll_layer
->ScrollBy(impl_thread_scroll1_
);
844 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
845 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll1_
);
846 PostSetNeedsCommitToMainThread();
848 // CommitCompleteOnThread will trigger this function again
849 // and cause us to take the else clause.
851 impl
->BlockNotifyReadyToActivateForTesting(false);
852 ASSERT_TRUE(pending_root
);
853 EXPECT_EQ(impl
->pending_tree()->source_frame_number(), 1);
855 scroll_layer
->ScrollBy(impl_thread_scroll2_
);
856 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
857 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(),
858 impl_thread_scroll1_
+ impl_thread_scroll2_
);
860 LayerImpl
* pending_scroll_layer
= pending_root
->children()[0];
862 pending_scroll_layer
->BaseScrollOffset(),
863 gfx::ScrollOffsetWithDelta(
864 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
865 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(),
866 impl_thread_scroll2_
);
870 EXPECT_FALSE(impl
->pending_tree());
872 scroll_layer
->BaseScrollOffset(),
873 gfx::ScrollOffsetWithDelta(
874 initial_scroll_
, main_thread_scroll_
+ impl_thread_scroll1_
));
875 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll2_
);
881 void ApplyViewportDeltas(const gfx::Vector2dF
& inner_delta
,
882 const gfx::Vector2dF
& outer_delta
,
883 const gfx::Vector2dF
& elastic_overscroll_delta
,
885 float top_controls_delta
) override
{
889 void AfterTest() override
{ EXPECT_EQ(1, num_scrolls_
); }
892 gfx::ScrollOffset initial_scroll_
;
893 gfx::Vector2dF main_thread_scroll_
;
894 gfx::Vector2dF impl_thread_scroll1_
;
895 gfx::Vector2dF impl_thread_scroll2_
;
899 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple
);
901 // This test makes sure that layers pick up scrolls that occur between
902 // beginning a commit and finishing a commit (aka scroll deltas not
903 // included in sent scroll delta) still apply to layers that don't
905 class ImplSidePaintingScrollTestImplOnlyScroll
906 : public ImplSidePaintingScrollTest
{
908 ImplSidePaintingScrollTestImplOnlyScroll()
909 : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3), impl_scale_(2.f
) {}
911 void SetupTree() override
{
912 LayerTreeHostScrollTest::SetupTree();
913 Layer
* root_layer
= layer_tree_host()->root_layer();
914 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create(layer_settings());
915 root_scroll_layer
->SetScrollClipLayerId(root_layer
->id());
916 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
917 root_scroll_layer
->SetBounds(
918 gfx::Size(root_layer
->bounds().width() + 100,
919 root_layer
->bounds().height() + 100));
920 root_scroll_layer
->SetIsDrawable(true);
921 root_scroll_layer
->SetIsContainerForFixedPositionLayers(true);
922 root_layer
->AddChild(root_scroll_layer
);
924 layer_tree_host()->RegisterViewportLayers(NULL
, root_layer
,
925 root_scroll_layer
, NULL
);
926 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
929 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
931 void WillCommit() override
{
932 Layer
* root
= layer_tree_host()->root_layer();
933 Layer
* scroll_layer
= root
->children()[0].get();
934 switch (layer_tree_host()->source_frame_number()) {
936 EXPECT_TRUE(scroll_layer
->needs_push_properties());
939 // Even if this layer doesn't need push properties, it should
940 // still pick up scrolls that happen on the active layer during
942 EXPECT_FALSE(scroll_layer
->needs_push_properties());
947 void BeginCommitOnThread(LayerTreeHostImpl
* impl
) override
{
948 // Scroll after the 2nd commit has started.
949 if (impl
->active_tree()->source_frame_number() == 0) {
950 LayerImpl
* active_root
= impl
->active_tree()->root_layer();
951 LayerImpl
* active_scroll_layer
= active_root
->children()[0];
952 ASSERT_TRUE(active_root
);
953 ASSERT_TRUE(active_scroll_layer
);
954 active_scroll_layer
->ScrollBy(impl_thread_scroll_
);
955 impl
->SetPageScaleOnActiveTree(impl_scale_
);
959 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
960 // We force a second draw here of the first commit before activating
961 // the second commit.
962 LayerImpl
* active_root
= impl
->active_tree()->root_layer();
963 LayerImpl
* active_scroll_layer
=
964 active_root
? active_root
->children()[0] : NULL
;
965 LayerImpl
* pending_root
= impl
->pending_tree()->root_layer();
966 LayerImpl
* pending_scroll_layer
= pending_root
->children()[0];
968 ASSERT_TRUE(pending_root
);
969 ASSERT_TRUE(pending_scroll_layer
);
970 switch (impl
->pending_tree()->source_frame_number()) {
972 EXPECT_VECTOR_EQ(pending_scroll_layer
->BaseScrollOffset(),
974 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(), gfx::Vector2d());
975 EXPECT_FALSE(active_root
);
978 // Even though the scroll happened during the commit, both layers
979 // should have the appropriate scroll delta.
980 EXPECT_VECTOR_EQ(pending_scroll_layer
->BaseScrollOffset(),
982 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(),
983 impl_thread_scroll_
);
984 ASSERT_TRUE(active_root
);
985 EXPECT_VECTOR_EQ(active_scroll_layer
->BaseScrollOffset(),
987 EXPECT_VECTOR_EQ(active_scroll_layer
->ScrollDelta(),
988 impl_thread_scroll_
);
991 // On the next commit, this delta should have been sent and applied.
993 pending_scroll_layer
->BaseScrollOffset(),
994 gfx::ScrollOffsetWithDelta(initial_scroll_
, impl_thread_scroll_
));
995 EXPECT_VECTOR_EQ(pending_scroll_layer
->ScrollDelta(), gfx::Vector2d());
1000 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
1001 ImplSidePaintingScrollTest::DrawLayersOnThread(impl
);
1003 LayerImpl
* root
= impl
->active_tree()->root_layer();
1004 LayerImpl
* scroll_layer
= root
->children()[0];
1006 switch (impl
->active_tree()->source_frame_number()) {
1008 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
1009 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), gfx::Vector2d());
1010 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
1011 EXPECT_EQ(1.f
, impl
->active_tree()->current_page_scale_factor());
1012 PostSetNeedsCommitToMainThread();
1015 EXPECT_VECTOR_EQ(scroll_layer
->BaseScrollOffset(), initial_scroll_
);
1016 EXPECT_VECTOR_EQ(scroll_layer
->ScrollDelta(), impl_thread_scroll_
);
1017 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
1018 EXPECT_EQ(impl_scale_
,
1019 impl
->active_tree()->current_page_scale_factor());
1020 PostSetNeedsCommitToMainThread();
1023 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
1024 EXPECT_EQ(impl_scale_
,
1025 impl
->active_tree()->current_page_scale_factor());
1031 void AfterTest() override
{}
1034 gfx::ScrollOffset initial_scroll_
;
1035 gfx::Vector2dF impl_thread_scroll_
;
1039 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll
);
1041 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
1042 : public LayerTreeHostScrollTest
{
1044 LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
1046 void SetupTree() override
{
1047 LayerTreeTest::SetupTree();
1048 scoped_refptr
<Layer
> scroll_layer
= Layer::Create(layer_settings());
1049 layer_tree_host()->root_layer()->AddChild(scroll_layer
);
1052 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1054 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
1055 LayerImpl
* root
= impl
->active_tree()->root_layer();
1056 LayerImpl
* scroll_layer
= root
->children()[0];
1057 scroll_layer
->SetScrollClipLayer(root
->id());
1059 // Set max_scroll_offset = (100, 100).
1060 scroll_layer
->SetBounds(
1061 gfx::Size(root
->bounds().width() + 100, root
->bounds().height() + 100));
1063 InputHandler::SCROLL_STARTED
,
1064 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
), InputHandler::GESTURE
,
1065 SCROLL_BLOCKS_ON_NONE
));
1067 // Set max_scroll_offset = (0, 0).
1068 scroll_layer
->SetBounds(root
->bounds());
1070 InputHandler::SCROLL_IGNORED
,
1071 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
), InputHandler::GESTURE
,
1072 SCROLL_BLOCKS_ON_NONE
));
1074 // Set max_scroll_offset = (-100, -100).
1075 scroll_layer
->SetBounds(gfx::Size());
1077 InputHandler::SCROLL_IGNORED
,
1078 scroll_layer
->TryScroll(gfx::PointF(0.0f
, 1.0f
), InputHandler::GESTURE
,
1079 SCROLL_BLOCKS_ON_NONE
));
1084 void AfterTest() override
{}
1087 SINGLE_AND_MULTI_THREAD_TEST_F(
1088 LayerTreeHostScrollTestScrollZeroMaxScrollOffset
);
1090 class ThreadCheckingInputHandlerClient
: public InputHandlerClient
{
1092 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner
* runner
,
1093 bool* received_stop_flinging
)
1094 : task_runner_(runner
), received_stop_flinging_(received_stop_flinging
) {}
1096 void WillShutdown() override
{
1097 if (!received_stop_flinging_
)
1098 ADD_FAILURE() << "WillShutdown() called before fling stopped";
1101 void Animate(base::TimeTicks time
) override
{
1102 if (!task_runner_
->BelongsToCurrentThread())
1103 ADD_FAILURE() << "Animate called on wrong thread";
1106 void MainThreadHasStoppedFlinging() override
{
1107 if (!task_runner_
->BelongsToCurrentThread())
1108 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
1109 *received_stop_flinging_
= true;
1112 void ReconcileElasticOverscrollAndRootScroll() override
{
1113 if (!task_runner_
->BelongsToCurrentThread()) {
1114 ADD_FAILURE() << "ReconcileElasticOverscrollAndRootScroll called on "
1120 base::SingleThreadTaskRunner
* task_runner_
;
1121 bool* received_stop_flinging_
;
1124 void BindInputHandlerOnCompositorThread(
1125 const base::WeakPtr
<InputHandler
>& input_handler
,
1126 ThreadCheckingInputHandlerClient
* client
) {
1127 input_handler
->BindToClient(client
);
1130 TEST(LayerTreeHostFlingTest
, DidStopFlingingThread
) {
1131 base::Thread
impl_thread("cc");
1132 ASSERT_TRUE(impl_thread
.Start());
1134 bool received_stop_flinging
= false;
1135 LayerTreeSettings settings
;
1137 ThreadCheckingInputHandlerClient
input_handler_client(
1138 impl_thread
.task_runner().get(), &received_stop_flinging
);
1139 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1141 ASSERT_TRUE(impl_thread
.task_runner().get());
1142 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1143 new TestSharedBitmapManager());
1145 LayerTreeHost::InitParams params
;
1146 params
.client
= &client
;
1147 params
.shared_bitmap_manager
= shared_bitmap_manager
.get();
1148 params
.settings
= &settings
;
1149 params
.main_task_runner
= base::ThreadTaskRunnerHandle::Get();
1150 scoped_ptr
<LayerTreeHost
> layer_tree_host
=
1151 LayerTreeHost::CreateThreaded(impl_thread
.task_runner(), ¶ms
);
1153 impl_thread
.task_runner()->PostTask(
1154 FROM_HERE
, base::Bind(&BindInputHandlerOnCompositorThread
,
1155 layer_tree_host
->GetInputHandler(),
1156 base::Unretained(&input_handler_client
)));
1158 layer_tree_host
->DidStopFlinging();
1159 layer_tree_host
= nullptr;
1161 EXPECT_TRUE(received_stop_flinging
);
1164 class LayerTreeHostScrollTestLayerStructureChange
1165 : public LayerTreeHostScrollTest
{
1167 LayerTreeHostScrollTestLayerStructureChange()
1168 : scroll_destroy_whole_tree_(false) {}
1170 void SetupTree() override
{
1171 scoped_refptr
<Layer
> root_layer
= Layer::Create(layer_settings());
1172 root_layer
->SetBounds(gfx::Size(10, 10));
1174 Layer
* root_scroll_layer
=
1175 CreateScrollLayer(root_layer
.get(), &root_scroll_layer_client_
);
1176 CreateScrollLayer(root_layer
.get(), &sibling_scroll_layer_client_
);
1177 CreateScrollLayer(root_scroll_layer
, &child_scroll_layer_client_
);
1179 layer_tree_host()->SetRootLayer(root_layer
);
1180 LayerTreeHostScrollTest::SetupTree();
1183 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1185 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
1186 LayerImpl
* root
= impl
->active_tree()->root_layer();
1187 switch (impl
->active_tree()->source_frame_number()) {
1189 root
->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1190 root
->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1191 root
->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5));
1192 PostSetNeedsCommitToMainThread();
1200 void AfterTest() override
{}
1202 virtual void DidScroll(Layer
* layer
) {
1203 if (scroll_destroy_whole_tree_
) {
1204 layer_tree_host()->SetRootLayer(NULL
);
1208 layer
->RemoveFromParent();
1212 class FakeLayerScrollClient
{
1215 owner_
->DidScroll(layer_
);
1217 LayerTreeHostScrollTestLayerStructureChange
* owner_
;
1221 Layer
* CreateScrollLayer(Layer
* parent
, FakeLayerScrollClient
* client
) {
1222 scoped_refptr
<PictureLayer
> scroll_layer
=
1223 PictureLayer::Create(layer_settings(), &fake_content_layer_client_
);
1224 scroll_layer
->SetBounds(gfx::Size(110, 110));
1225 scroll_layer
->SetPosition(gfx::Point(0, 0));
1226 scroll_layer
->SetIsDrawable(true);
1227 scroll_layer
->SetScrollClipLayerId(parent
->id());
1228 scroll_layer
->SetBounds(gfx::Size(parent
->bounds().width() + 100,
1229 parent
->bounds().height() + 100));
1230 scroll_layer
->set_did_scroll_callback(base::Bind(
1231 &FakeLayerScrollClient::DidScroll
, base::Unretained(client
)));
1232 client
->owner_
= this;
1233 client
->layer_
= scroll_layer
.get();
1234 parent
->AddChild(scroll_layer
);
1235 return scroll_layer
.get();
1238 FakeLayerScrollClient root_scroll_layer_client_
;
1239 FakeLayerScrollClient sibling_scroll_layer_client_
;
1240 FakeLayerScrollClient child_scroll_layer_client_
;
1242 FakeContentLayerClient fake_content_layer_client_
;
1244 bool scroll_destroy_whole_tree_
;
1247 TEST_F(LayerTreeHostScrollTestLayerStructureChange
, ScrollDestroyLayer
) {
1248 RunTest(true, false, true);
1251 TEST_F(LayerTreeHostScrollTestLayerStructureChange
, ScrollDestroyWholeTree
) {
1252 scroll_destroy_whole_tree_
= true;
1253 RunTest(true, false, true);