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/content_layer.h"
9 #include "cc/layers/layer.h"
10 #include "cc/layers/layer_impl.h"
11 #include "cc/test/fake_content_layer_client.h"
12 #include "cc/test/fake_layer_tree_host_client.h"
13 #include "cc/test/geometry_test_utils.h"
14 #include "cc/test/layer_tree_test.h"
15 #include "cc/trees/layer_tree_impl.h"
16 #include "ui/gfx/point_conversions.h"
17 #include "ui/gfx/size_conversions.h"
18 #include "ui/gfx/vector2d_conversions.h"
23 class LayerTreeHostScrollTest
: public LayerTreeTest
{};
25 class LayerTreeHostScrollTestScrollSimple
: public LayerTreeHostScrollTest
{
27 LayerTreeHostScrollTestScrollSimple()
28 : initial_scroll_(10, 20),
29 second_scroll_(40, 5),
30 scroll_amount_(2, -1),
33 virtual void BeginTest() OVERRIDE
{
34 layer_tree_host()->root_layer()->SetScrollable(true);
35 layer_tree_host()->root_layer()
36 ->SetMaxScrollOffset(gfx::Vector2d(100, 100));
37 layer_tree_host()->root_layer()->SetScrollOffset(initial_scroll_
);
38 PostSetNeedsCommitToMainThread();
41 virtual void Layout() OVERRIDE
{
42 Layer
* root
= layer_tree_host()->root_layer();
43 if (!layer_tree_host()->source_frame_number()) {
44 EXPECT_VECTOR_EQ(initial_scroll_
, root
->scroll_offset());
46 EXPECT_VECTOR_EQ(initial_scroll_
+ scroll_amount_
, root
->scroll_offset());
48 // Pretend like Javascript updated the scroll position itself.
49 root
->SetScrollOffset(second_scroll_
);
53 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
54 LayerImpl
* root
= impl
->active_tree()->root_layer();
55 EXPECT_VECTOR_EQ(gfx::Vector2d(), root
->ScrollDelta());
57 root
->SetScrollable(true);
58 root
->SetMaxScrollOffset(gfx::Vector2d(100, 100));
59 root
->ScrollBy(scroll_amount_
);
61 switch (impl
->active_tree()->source_frame_number()) {
63 EXPECT_VECTOR_EQ(initial_scroll_
, root
->scroll_offset());
64 EXPECT_VECTOR_EQ(scroll_amount_
, root
->ScrollDelta());
65 PostSetNeedsCommitToMainThread();
68 EXPECT_VECTOR_EQ(root
->scroll_offset(), second_scroll_
);
69 EXPECT_VECTOR_EQ(root
->ScrollDelta(), scroll_amount_
);
75 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta
,
76 float scale
) OVERRIDE
{
80 virtual void AfterTest() OVERRIDE
{ EXPECT_EQ(1, num_scrolls_
); }
83 gfx::Vector2d initial_scroll_
;
84 gfx::Vector2d second_scroll_
;
85 gfx::Vector2d scroll_amount_
;
89 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple
);
91 class LayerTreeHostScrollTestScrollMultipleRedraw
92 : public LayerTreeHostScrollTest
{
94 LayerTreeHostScrollTestScrollMultipleRedraw()
95 : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
97 virtual void BeginTest() OVERRIDE
{
98 layer_tree_host()->root_layer()->SetScrollable(true);
99 layer_tree_host()->root_layer()->SetScrollOffset(initial_scroll_
);
100 layer_tree_host()->root_layer()->SetBounds(gfx::Size(200, 200));
101 layer_tree_host()->root_layer()
102 ->SetMaxScrollOffset(gfx::Vector2d(100, 100));
103 PostSetNeedsCommitToMainThread();
106 virtual void BeginCommitOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
107 Layer
* root
= layer_tree_host()->root_layer();
108 switch (layer_tree_host()->source_frame_number()) {
110 EXPECT_VECTOR_EQ(root
->scroll_offset(), initial_scroll_
);
113 EXPECT_VECTOR_EQ(root
->scroll_offset(),
114 initial_scroll_
+ scroll_amount_
+ scroll_amount_
);
116 EXPECT_VECTOR_EQ(root
->scroll_offset(),
117 initial_scroll_
+ scroll_amount_
+ scroll_amount_
);
122 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
123 LayerImpl
* root
= impl
->active_tree()->root_layer();
124 if (impl
->active_tree()->source_frame_number() == 0 &&
125 impl
->SourceAnimationFrameNumber() == 1) {
126 // First draw after first commit.
127 EXPECT_VECTOR_EQ(root
->ScrollDelta(), gfx::Vector2d());
128 root
->ScrollBy(scroll_amount_
);
129 EXPECT_VECTOR_EQ(root
->ScrollDelta(), scroll_amount_
);
131 EXPECT_VECTOR_EQ(root
->scroll_offset(), initial_scroll_
);
132 PostSetNeedsRedrawToMainThread();
133 } else if (impl
->active_tree()->source_frame_number() == 0 &&
134 impl
->SourceAnimationFrameNumber() == 2) {
135 // Second draw after first commit.
136 EXPECT_EQ(root
->ScrollDelta(), scroll_amount_
);
137 root
->ScrollBy(scroll_amount_
);
138 EXPECT_VECTOR_EQ(root
->ScrollDelta(), scroll_amount_
+ scroll_amount_
);
140 EXPECT_VECTOR_EQ(root
->scroll_offset(), initial_scroll_
);
141 PostSetNeedsCommitToMainThread();
142 } else if (impl
->active_tree()->source_frame_number() == 1) {
143 // Third or later draw after second commit.
144 EXPECT_GE(impl
->SourceAnimationFrameNumber(), 3);
145 EXPECT_VECTOR_EQ(root
->ScrollDelta(), gfx::Vector2d());
146 EXPECT_VECTOR_EQ(root
->scroll_offset(),
147 initial_scroll_
+ scroll_amount_
+ scroll_amount_
);
152 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta
,
153 float scale
) OVERRIDE
{
157 virtual void AfterTest() OVERRIDE
{ EXPECT_EQ(1, num_scrolls_
); }
160 gfx::Vector2d initial_scroll_
;
161 gfx::Vector2d scroll_amount_
;
165 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw
);
167 class LayerTreeHostScrollTestScrollAbortedCommit
168 : public LayerTreeHostScrollTest
{
170 LayerTreeHostScrollTestScrollAbortedCommit()
171 : initial_scroll_(50, 60),
173 second_main_scroll_(14, -3),
175 num_will_begin_main_frames_(0),
176 num_did_begin_main_frames_(0),
177 num_will_commits_(0),
179 num_impl_commits_(0),
180 num_impl_scrolls_(0) {}
182 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
184 virtual void SetupTree() OVERRIDE
{
185 LayerTreeHostScrollTest::SetupTree();
186 scoped_refptr
<Layer
> root_scroll_layer
= Layer::Create();
187 root_scroll_layer
->SetScrollable(true);
188 root_scroll_layer
->SetScrollOffset(initial_scroll_
);
189 root_scroll_layer
->SetBounds(gfx::Size(200, 200));
190 root_scroll_layer
->SetMaxScrollOffset(gfx::Vector2d(100, 100));
191 root_scroll_layer
->SetIsDrawable(true);
192 layer_tree_host()->root_layer()->AddChild(root_scroll_layer
);
194 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.01f
, 100.f
);
197 virtual void WillBeginMainFrame() OVERRIDE
{
198 num_will_begin_main_frames_
++;
199 Layer
* root_scroll_layer
= layer_tree_host()->root_layer()->children()[0];
200 switch (num_will_begin_main_frames_
) {
202 // This will not be aborted because of the initial prop changes.
203 EXPECT_EQ(0, num_impl_scrolls_
);
204 EXPECT_EQ(0, layer_tree_host()->source_frame_number());
205 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(), initial_scroll_
);
206 EXPECT_EQ(1.f
, layer_tree_host()->page_scale_factor());
209 // This commit will be aborted, and another commit will be
210 // initiated from the redraw.
211 EXPECT_EQ(1, num_impl_scrolls_
);
212 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
213 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
214 initial_scroll_
+ impl_scroll_
);
215 EXPECT_EQ(impl_scale_
, layer_tree_host()->page_scale_factor());
216 PostSetNeedsRedrawToMainThread();
219 // This commit will not be aborted because of the scroll change.
220 EXPECT_EQ(2, num_impl_scrolls_
);
221 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
222 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
223 initial_scroll_
+ impl_scroll_
+ impl_scroll_
);
224 EXPECT_EQ(impl_scale_
* impl_scale_
,
225 layer_tree_host()->page_scale_factor());
226 root_scroll_layer
->SetScrollOffset(root_scroll_layer
->scroll_offset() +
227 second_main_scroll_
);
230 // This commit will also be aborted.
231 EXPECT_EQ(3, num_impl_scrolls_
);
232 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
233 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
234 initial_scroll_
+ impl_scroll_
+ impl_scroll_
+
235 impl_scroll_
+ second_main_scroll_
);
236 // End the test by drawing to verify this commit is also aborted.
237 PostSetNeedsRedrawToMainThread();
242 virtual void DidBeginMainFrame() OVERRIDE
{ num_did_begin_main_frames_
++; }
244 virtual void WillCommit() OVERRIDE
{ num_will_commits_
++; }
246 virtual void DidCommit() OVERRIDE
{ num_did_commits_
++; }
248 virtual void BeginCommitOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
252 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
253 LayerImpl
* root_scroll_layer
=
254 impl
->active_tree()->root_layer()->children()[0];
256 if (impl
->active_tree()->source_frame_number() == 0 &&
257 impl
->SourceAnimationFrameNumber() == 1) {
259 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
260 root_scroll_layer
->ScrollBy(impl_scroll_
);
261 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
262 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(), initial_scroll_
);
264 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
265 EXPECT_EQ(1.f
, impl
->active_tree()->total_page_scale_factor());
266 impl
->active_tree()->SetPageScaleDelta(impl_scale_
);
267 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
268 EXPECT_EQ(impl_scale_
, impl
->active_tree()->total_page_scale_factor());
270 // To simplify the testing flow, don't redraw here, just commit.
271 impl
->SetNeedsCommit();
272 } else if (impl
->active_tree()->source_frame_number() == 0 &&
273 impl
->SourceAnimationFrameNumber() == 2) {
274 // Test a second draw after an aborted commit.
275 // The scroll/scale values should be baked into the offset/scale factor
276 // since the main thread consumed but aborted the begin frame.
277 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
278 root_scroll_layer
->ScrollBy(impl_scroll_
);
279 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
280 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
281 initial_scroll_
+ impl_scroll_
);
283 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_delta());
284 EXPECT_EQ(impl_scale_
, impl
->active_tree()->total_page_scale_factor());
285 impl
->active_tree()->SetPageScaleDelta(impl_scale_
);
286 EXPECT_EQ(impl_scale_
, impl
->active_tree()->page_scale_delta());
287 EXPECT_EQ(impl_scale_
* impl_scale_
,
288 impl
->active_tree()->total_page_scale_factor());
290 impl
->SetNeedsCommit();
291 } else if (impl
->active_tree()->source_frame_number() == 1 &&
292 impl
->SourceAnimationFrameNumber() == 3) {
293 // Third draw after the second full commit.
294 EXPECT_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
295 root_scroll_layer
->ScrollBy(impl_scroll_
);
296 impl
->SetNeedsCommit();
297 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), impl_scroll_
);
299 root_scroll_layer
->scroll_offset(),
300 initial_scroll_
+ impl_scroll_
+ impl_scroll_
+ second_main_scroll_
);
301 } else if (impl
->active_tree()->source_frame_number() == 1 &&
302 impl
->SourceAnimationFrameNumber() == 4) {
303 // Final draw after the second aborted commit.
304 EXPECT_VECTOR_EQ(root_scroll_layer
->ScrollDelta(), gfx::Vector2d());
305 EXPECT_VECTOR_EQ(root_scroll_layer
->scroll_offset(),
306 initial_scroll_
+ impl_scroll_
+ impl_scroll_
+
307 impl_scroll_
+ second_main_scroll_
);
312 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta
,
313 float scale
) OVERRIDE
{
317 virtual void AfterTest() OVERRIDE
{
318 EXPECT_EQ(3, num_impl_scrolls_
);
319 // Verify that the embedder sees aborted commits as real commits.
320 EXPECT_EQ(4, num_will_begin_main_frames_
);
321 EXPECT_EQ(4, num_did_begin_main_frames_
);
322 EXPECT_EQ(4, num_will_commits_
);
323 EXPECT_EQ(4, num_did_commits_
);
324 // ...but the compositor thread only sees two real ones.
325 EXPECT_EQ(2, num_impl_commits_
);
329 gfx::Vector2d initial_scroll_
;
330 gfx::Vector2d impl_scroll_
;
331 gfx::Vector2d second_main_scroll_
;
333 int num_will_begin_main_frames_
;
334 int num_did_begin_main_frames_
;
335 int num_will_commits_
;
336 int num_did_commits_
;
337 int num_impl_commits_
;
338 int num_impl_scrolls_
;
341 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit
);
343 class LayerTreeHostScrollTestFractionalScroll
: public LayerTreeHostScrollTest
{
345 LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
347 virtual void BeginTest() OVERRIDE
{
348 layer_tree_host()->root_layer()->SetScrollable(true);
349 layer_tree_host()->root_layer()
350 ->SetMaxScrollOffset(gfx::Vector2d(100, 100));
351 PostSetNeedsCommitToMainThread();
354 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
355 LayerImpl
* root
= impl
->active_tree()->root_layer();
357 // Check that a fractional scroll delta is correctly accumulated over
359 switch (impl
->active_tree()->source_frame_number()) {
361 EXPECT_VECTOR_EQ(root
->scroll_offset(), gfx::Vector2d(0, 0));
362 EXPECT_VECTOR_EQ(root
->ScrollDelta(), gfx::Vector2d(0, 0));
363 PostSetNeedsCommitToMainThread();
366 EXPECT_VECTOR_EQ(root
->scroll_offset(),
367 gfx::ToFlooredVector2d(scroll_amount_
));
368 EXPECT_VECTOR_EQ(root
->ScrollDelta(),
369 gfx::Vector2dF(fmod(scroll_amount_
.x(), 1.0f
), 0.0f
));
370 PostSetNeedsCommitToMainThread();
374 root
->scroll_offset(),
375 gfx::ToFlooredVector2d(scroll_amount_
+ scroll_amount_
));
378 gfx::Vector2dF(fmod(2.0f
* scroll_amount_
.x(), 1.0f
), 0.0f
));
382 root
->ScrollBy(scroll_amount_
);
385 virtual void AfterTest() OVERRIDE
{}
388 gfx::Vector2dF scroll_amount_
;
391 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll
);
393 class LayerTreeHostScrollTestCaseWithChild
: public LayerTreeHostScrollTest
{
395 LayerTreeHostScrollTestCaseWithChild()
396 : initial_offset_(10, 20),
397 javascript_scroll_(40, 5),
398 scroll_amount_(2, -1),
401 virtual void SetupTree() OVERRIDE
{
402 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_
);
404 scoped_refptr
<Layer
> root_layer
= Layer::Create();
405 root_layer
->SetBounds(gfx::Size(10, 10));
407 root_scroll_layer_
= ContentLayer::Create(&fake_content_layer_client_
);
408 root_scroll_layer_
->SetBounds(gfx::Size(110, 110));
410 root_scroll_layer_
->SetPosition(gfx::Point());
411 root_scroll_layer_
->SetAnchorPoint(gfx::PointF());
413 root_scroll_layer_
->SetIsDrawable(true);
414 root_scroll_layer_
->SetScrollable(true);
415 root_scroll_layer_
->SetMaxScrollOffset(gfx::Vector2d(100, 100));
416 root_layer
->AddChild(root_scroll_layer_
);
418 child_layer_
= ContentLayer::Create(&fake_content_layer_client_
);
419 child_layer_
->set_did_scroll_callback(
420 base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll
,
421 base::Unretained(this)));
422 child_layer_
->SetBounds(gfx::Size(110, 110));
424 if (scroll_child_layer_
) {
425 // Scrolls on the child layer will happen at 5, 5. If they are treated
426 // like device pixels, and device scale factor is 2, then they will
427 // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
428 child_layer_
->SetPosition(gfx::Point(5, 5));
430 // Adjust the child layer horizontally so that scrolls will never hit it.
431 child_layer_
->SetPosition(gfx::Point(60, 5));
433 child_layer_
->SetAnchorPoint(gfx::PointF());
435 child_layer_
->SetIsDrawable(true);
436 child_layer_
->SetScrollable(true);
437 child_layer_
->SetMaxScrollOffset(gfx::Vector2d(100, 100));
438 root_scroll_layer_
->AddChild(child_layer_
);
440 if (scroll_child_layer_
) {
441 expected_scroll_layer_
= child_layer_
;
442 expected_no_scroll_layer_
= root_scroll_layer_
;
444 expected_scroll_layer_
= root_scroll_layer_
;
445 expected_no_scroll_layer_
= child_layer_
;
448 expected_scroll_layer_
->SetScrollOffset(initial_offset_
);
450 layer_tree_host()->SetRootLayer(root_layer
);
451 LayerTreeHostScrollTest::SetupTree();
454 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
456 virtual void WillCommit() OVERRIDE
{
457 // Keep the test committing (otherwise the early out for no update
458 // will stall the test).
459 if (layer_tree_host()->source_frame_number() < 2) {
460 layer_tree_host()->SetNeedsCommit();
465 final_scroll_offset_
= expected_scroll_layer_
->scroll_offset();
468 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta
,
469 float scale
) OVERRIDE
{
473 virtual void Layout() OVERRIDE
{
474 EXPECT_VECTOR_EQ(gfx::Vector2d(),
475 expected_no_scroll_layer_
->scroll_offset());
477 switch (layer_tree_host()->source_frame_number()) {
479 EXPECT_VECTOR_EQ(initial_offset_
,
480 expected_scroll_layer_
->scroll_offset());
483 EXPECT_VECTOR_EQ(initial_offset_
+ scroll_amount_
,
484 expected_scroll_layer_
->scroll_offset());
486 // Pretend like Javascript updated the scroll position itself.
487 expected_scroll_layer_
->SetScrollOffset(javascript_scroll_
);
490 EXPECT_VECTOR_EQ(javascript_scroll_
+ scroll_amount_
,
491 expected_scroll_layer_
->scroll_offset());
496 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
497 LayerImpl
* root_impl
= impl
->active_tree()->root_layer();
498 LayerImpl
* root_scroll_layer_impl
= root_impl
->children()[0];
499 LayerImpl
* child_layer_impl
= root_scroll_layer_impl
->children()[0];
501 LayerImpl
* expected_scroll_layer_impl
= NULL
;
502 LayerImpl
* expected_no_scroll_layer_impl
= NULL
;
503 if (scroll_child_layer_
) {
504 expected_scroll_layer_impl
= child_layer_impl
;
505 expected_no_scroll_layer_impl
= root_scroll_layer_impl
;
507 expected_scroll_layer_impl
= root_scroll_layer_impl
;
508 expected_no_scroll_layer_impl
= child_layer_impl
;
511 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl
->ScrollDelta());
512 EXPECT_VECTOR_EQ(gfx::Vector2d(),
513 expected_no_scroll_layer_impl
->ScrollDelta());
515 // Ensure device scale factor is affecting the layers.
516 gfx::Size expected_content_bounds
= gfx::ToCeiledSize(
517 gfx::ScaleSize(root_scroll_layer_impl
->bounds(), device_scale_factor_
));
518 EXPECT_SIZE_EQ(expected_content_bounds
,
519 root_scroll_layer_
->content_bounds());
521 expected_content_bounds
= gfx::ToCeiledSize(
522 gfx::ScaleSize(child_layer_impl
->bounds(), device_scale_factor_
));
523 EXPECT_SIZE_EQ(expected_content_bounds
, child_layer_
->content_bounds());
525 switch (impl
->active_tree()->source_frame_number()) {
527 // Gesture scroll on impl thread.
528 InputHandler::ScrollStatus status
= impl
->ScrollBegin(
529 gfx::ToCeiledPoint(expected_scroll_layer_impl
->position() -
530 gfx::Vector2dF(0.5f
, 0.5f
)),
531 InputHandler::Gesture
);
532 EXPECT_EQ(InputHandler::ScrollStarted
, status
);
533 impl
->ScrollBy(gfx::Point(), scroll_amount_
);
536 // Check the scroll is applied as a delta.
537 EXPECT_VECTOR_EQ(initial_offset_
,
538 expected_scroll_layer_impl
->scroll_offset());
539 EXPECT_VECTOR_EQ(scroll_amount_
,
540 expected_scroll_layer_impl
->ScrollDelta());
544 // Wheel scroll on impl thread.
545 InputHandler::ScrollStatus status
= impl
->ScrollBegin(
546 gfx::ToCeiledPoint(expected_scroll_layer_impl
->position() +
547 gfx::Vector2dF(0.5f
, 0.5f
)),
548 InputHandler::Wheel
);
549 EXPECT_EQ(InputHandler::ScrollStarted
, status
);
550 impl
->ScrollBy(gfx::Point(), scroll_amount_
);
553 // Check the scroll is applied as a delta.
554 EXPECT_VECTOR_EQ(javascript_scroll_
,
555 expected_scroll_layer_impl
->scroll_offset());
556 EXPECT_VECTOR_EQ(scroll_amount_
,
557 expected_scroll_layer_impl
->ScrollDelta());
562 EXPECT_VECTOR_EQ(javascript_scroll_
+ scroll_amount_
,
563 expected_scroll_layer_impl
->scroll_offset());
564 EXPECT_VECTOR_EQ(gfx::Vector2d(),
565 expected_scroll_layer_impl
->ScrollDelta());
572 virtual void AfterTest() OVERRIDE
{
573 if (scroll_child_layer_
) {
574 EXPECT_EQ(0, num_scrolls_
);
575 EXPECT_VECTOR_EQ(javascript_scroll_
+ scroll_amount_
,
576 final_scroll_offset_
);
578 EXPECT_EQ(2, num_scrolls_
);
579 EXPECT_VECTOR_EQ(gfx::Vector2d(), final_scroll_offset_
);
584 float device_scale_factor_
;
585 bool scroll_child_layer_
;
587 gfx::Vector2d initial_offset_
;
588 gfx::Vector2d javascript_scroll_
;
589 gfx::Vector2d scroll_amount_
;
591 gfx::Vector2d final_scroll_offset_
;
593 FakeContentLayerClient fake_content_layer_client_
;
595 scoped_refptr
<Layer
> root_scroll_layer_
;
596 scoped_refptr
<Layer
> child_layer_
;
597 scoped_refptr
<Layer
> expected_scroll_layer_
;
598 scoped_refptr
<Layer
> expected_no_scroll_layer_
;
601 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
602 DeviceScaleFactor1_ScrollChild_DirectRenderer_MainThreadPaint
) {
603 device_scale_factor_
= 1.f
;
604 scroll_child_layer_
= true;
605 RunTest(true, false, false);
608 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
609 DeviceScaleFactor1_ScrollChild_DirectRenderer_ImplSidePaint
) {
610 device_scale_factor_
= 1.f
;
611 scroll_child_layer_
= true;
612 RunTest(true, false, true);
615 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
616 DeviceScaleFactor1_ScrollChild_DelegatingRenderer_MainThreadPaint
) {
617 device_scale_factor_
= 1.f
;
618 scroll_child_layer_
= true;
619 RunTest(true, true, false);
622 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
623 DeviceScaleFactor1_ScrollChild_DelegatingRenderer_ImplSidePaint
) {
624 device_scale_factor_
= 1.f
;
625 scroll_child_layer_
= true;
626 RunTest(true, true, true);
629 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
630 DeviceScaleFactor15_ScrollChild_DirectRenderer
) {
631 device_scale_factor_
= 1.5f
;
632 scroll_child_layer_
= true;
633 RunTest(true, false, true);
636 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
637 DeviceScaleFactor15_ScrollChild_DelegatingRenderer
) {
638 device_scale_factor_
= 1.5f
;
639 scroll_child_layer_
= true;
640 RunTest(true, true, true);
643 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
644 DeviceScaleFactor2_ScrollChild_DirectRenderer
) {
645 device_scale_factor_
= 2.f
;
646 scroll_child_layer_
= true;
647 RunTest(true, false, true);
650 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
651 DeviceScaleFactor2_ScrollChild_DelegatingRenderer
) {
652 device_scale_factor_
= 2.f
;
653 scroll_child_layer_
= true;
654 RunTest(true, true, true);
657 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
658 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer
) {
659 device_scale_factor_
= 1.f
;
660 scroll_child_layer_
= false;
661 RunTest(true, false, true);
664 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
665 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer
) {
666 device_scale_factor_
= 1.f
;
667 scroll_child_layer_
= false;
668 RunTest(true, true, true);
671 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
672 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer
) {
673 device_scale_factor_
= 1.5f
;
674 scroll_child_layer_
= false;
675 RunTest(true, false, true);
678 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
679 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer
) {
680 device_scale_factor_
= 1.5f
;
681 scroll_child_layer_
= false;
682 RunTest(true, true, true);
685 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
686 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer_MainSidePaint
) {
687 device_scale_factor_
= 2.f
;
688 scroll_child_layer_
= false;
689 RunTest(true, false, false);
692 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
693 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer_ImplSidePaint
) {
694 device_scale_factor_
= 2.f
;
695 scroll_child_layer_
= false;
696 RunTest(true, false, true);
699 TEST_F(LayerTreeHostScrollTestCaseWithChild
,
700 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer
) {
701 device_scale_factor_
= 2.f
;
702 scroll_child_layer_
= false;
703 RunTest(true, true, true);
706 class ImplSidePaintingScrollTest
: public LayerTreeHostScrollTest
{
708 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
709 settings
->impl_side_painting
= true;
712 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
713 if (impl
->pending_tree())
714 impl
->SetNeedsRedraw();
718 class ImplSidePaintingScrollTestSimple
: public ImplSidePaintingScrollTest
{
720 ImplSidePaintingScrollTestSimple()
721 : initial_scroll_(10, 20),
722 main_thread_scroll_(40, 5),
723 impl_thread_scroll1_(2, -1),
724 impl_thread_scroll2_(-3, 10),
727 virtual void BeginTest() OVERRIDE
{
728 layer_tree_host()->root_layer()->SetScrollable(true);
729 layer_tree_host()->root_layer()
730 ->SetMaxScrollOffset(gfx::Vector2d(100, 100));
731 layer_tree_host()->root_layer()->SetScrollOffset(initial_scroll_
);
732 PostSetNeedsCommitToMainThread();
735 virtual void Layout() OVERRIDE
{
736 Layer
* root
= layer_tree_host()->root_layer();
737 if (!layer_tree_host()->source_frame_number()) {
738 EXPECT_VECTOR_EQ(root
->scroll_offset(), initial_scroll_
);
740 EXPECT_VECTOR_EQ(root
->scroll_offset(),
741 initial_scroll_
+ impl_thread_scroll1_
);
743 // Pretend like Javascript updated the scroll position itself with a
744 // change of main_thread_scroll.
745 root
->SetScrollOffset(initial_scroll_
+ main_thread_scroll_
+
746 impl_thread_scroll1_
);
750 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
751 // We force a second draw here of the first commit before activating
752 // the second commit.
753 if (impl
->active_tree()->source_frame_number() == 0)
754 impl
->SetNeedsRedraw();
757 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
758 ImplSidePaintingScrollTest::DrawLayersOnThread(impl
);
760 LayerImpl
* root
= impl
->active_tree()->root_layer();
761 LayerImpl
* pending_root
=
762 impl
->active_tree()->FindPendingTreeLayerById(root
->id());
764 switch (impl
->active_tree()->source_frame_number()) {
766 if (!impl
->pending_tree()) {
767 impl
->BlockNotifyReadyToActivateForTesting(true);
768 EXPECT_VECTOR_EQ(root
->ScrollDelta(), gfx::Vector2d());
769 root
->ScrollBy(impl_thread_scroll1_
);
771 EXPECT_VECTOR_EQ(root
->scroll_offset(), initial_scroll_
);
772 EXPECT_VECTOR_EQ(root
->ScrollDelta(), impl_thread_scroll1_
);
773 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), gfx::Vector2d());
774 PostSetNeedsCommitToMainThread();
776 // CommitCompleteOnThread will trigger this function again
777 // and cause us to take the else clause.
779 impl
->BlockNotifyReadyToActivateForTesting(false);
780 ASSERT_TRUE(pending_root
);
781 EXPECT_EQ(impl
->pending_tree()->source_frame_number(), 1);
783 root
->ScrollBy(impl_thread_scroll2_
);
784 EXPECT_VECTOR_EQ(root
->scroll_offset(), initial_scroll_
);
785 EXPECT_VECTOR_EQ(root
->ScrollDelta(),
786 impl_thread_scroll1_
+ impl_thread_scroll2_
);
787 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), impl_thread_scroll1_
);
790 pending_root
->scroll_offset(),
791 initial_scroll_
+ main_thread_scroll_
+ impl_thread_scroll1_
);
792 EXPECT_VECTOR_EQ(pending_root
->ScrollDelta(), impl_thread_scroll2_
);
793 EXPECT_VECTOR_EQ(pending_root
->sent_scroll_delta(), gfx::Vector2d());
797 EXPECT_FALSE(impl
->pending_tree());
799 root
->scroll_offset(),
800 initial_scroll_
+ main_thread_scroll_
+ impl_thread_scroll1_
);
801 EXPECT_VECTOR_EQ(root
->ScrollDelta(), impl_thread_scroll2_
);
802 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), gfx::Vector2d());
808 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta
,
809 float scale
) OVERRIDE
{
813 virtual void AfterTest() OVERRIDE
{ EXPECT_EQ(1, num_scrolls_
); }
816 gfx::Vector2d initial_scroll_
;
817 gfx::Vector2d main_thread_scroll_
;
818 gfx::Vector2d impl_thread_scroll1_
;
819 gfx::Vector2d impl_thread_scroll2_
;
823 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple
);
825 // This test makes sure that layers pick up scrolls that occur between
826 // beginning a commit and finishing a commit (aka scroll deltas not
827 // included in sent scroll delta) still apply to layers that don't
829 class ImplSidePaintingScrollTestImplOnlyScroll
830 : public ImplSidePaintingScrollTest
{
832 ImplSidePaintingScrollTestImplOnlyScroll()
833 : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3) {}
835 virtual void BeginTest() OVERRIDE
{
836 layer_tree_host()->root_layer()->SetScrollable(true);
837 layer_tree_host()->root_layer()->SetMaxScrollOffset(
838 gfx::Vector2d(100, 100));
839 layer_tree_host()->root_layer()->SetScrollOffset(initial_scroll_
);
840 PostSetNeedsCommitToMainThread();
843 virtual void WillCommit() OVERRIDE
{
844 Layer
* root
= layer_tree_host()->root_layer();
845 switch (layer_tree_host()->source_frame_number()) {
847 EXPECT_TRUE(root
->needs_push_properties());
850 // Even if this layer doesn't need push properties, it should
851 // still pick up scrolls that happen on the active layer during
853 EXPECT_FALSE(root
->needs_push_properties());
858 virtual void BeginCommitOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
859 // Scroll after the 2nd commit has started.
860 if (impl
->active_tree()->source_frame_number() == 0) {
861 LayerImpl
* active_root
= impl
->active_tree()->root_layer();
862 ASSERT_TRUE(active_root
);
863 active_root
->ScrollBy(impl_thread_scroll_
);
867 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
868 // We force a second draw here of the first commit before activating
869 // the second commit.
870 LayerImpl
* active_root
= impl
->active_tree()->root_layer();
871 LayerImpl
* pending_root
= impl
->pending_tree()->root_layer();
873 ASSERT_TRUE(pending_root
);
874 switch (impl
->pending_tree()->source_frame_number()) {
876 EXPECT_VECTOR_EQ(pending_root
->scroll_offset(), initial_scroll_
);
877 EXPECT_VECTOR_EQ(pending_root
->ScrollDelta(), gfx::Vector2d());
878 EXPECT_VECTOR_EQ(pending_root
->sent_scroll_delta(), gfx::Vector2d());
879 EXPECT_FALSE(active_root
);
882 // Even though the scroll happened during the commit, both layers
883 // should have the appropriate scroll delta.
884 EXPECT_VECTOR_EQ(pending_root
->scroll_offset(), initial_scroll_
);
885 EXPECT_VECTOR_EQ(pending_root
->ScrollDelta(), impl_thread_scroll_
);
886 EXPECT_VECTOR_EQ(pending_root
->sent_scroll_delta(), gfx::Vector2d());
887 ASSERT_TRUE(active_root
);
888 EXPECT_VECTOR_EQ(active_root
->scroll_offset(), initial_scroll_
);
889 EXPECT_VECTOR_EQ(active_root
->ScrollDelta(), impl_thread_scroll_
);
890 EXPECT_VECTOR_EQ(active_root
->sent_scroll_delta(), gfx::Vector2d());
893 // On the next commit, this delta should have been sent and applied.
894 EXPECT_VECTOR_EQ(pending_root
->scroll_offset(),
895 initial_scroll_
+ impl_thread_scroll_
);
896 EXPECT_VECTOR_EQ(pending_root
->ScrollDelta(), gfx::Vector2d());
897 EXPECT_VECTOR_EQ(pending_root
->sent_scroll_delta(), gfx::Vector2d());
903 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
904 ImplSidePaintingScrollTest::DrawLayersOnThread(impl
);
906 LayerImpl
* root
= impl
->active_tree()->root_layer();
908 switch (impl
->active_tree()->source_frame_number()) {
910 EXPECT_VECTOR_EQ(root
->scroll_offset(), initial_scroll_
);
911 EXPECT_VECTOR_EQ(root
->ScrollDelta(), gfx::Vector2d());
912 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), gfx::Vector2d());
913 PostSetNeedsCommitToMainThread();
916 EXPECT_VECTOR_EQ(root
->scroll_offset(), initial_scroll_
);
917 EXPECT_VECTOR_EQ(root
->ScrollDelta(), impl_thread_scroll_
);
918 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), gfx::Vector2d());
919 PostSetNeedsCommitToMainThread();
924 virtual void AfterTest() OVERRIDE
{}
927 gfx::Vector2d initial_scroll_
;
928 gfx::Vector2d impl_thread_scroll_
;
931 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll
);
933 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
934 : public LayerTreeHostScrollTest
{
936 LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
938 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
940 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
941 LayerImpl
* root
= impl
->active_tree()->root_layer();
942 root
->SetScrollable(true);
944 root
->SetMaxScrollOffset(gfx::Vector2d(100, 100));
945 EXPECT_EQ(InputHandler::ScrollStarted
,
946 root
->TryScroll(gfx::PointF(0.0f
, 1.0f
), InputHandler::Gesture
));
948 root
->SetMaxScrollOffset(gfx::Vector2d(0, 0));
949 EXPECT_EQ(InputHandler::ScrollIgnored
,
950 root
->TryScroll(gfx::PointF(0.0f
, 1.0f
), InputHandler::Gesture
));
952 root
->SetMaxScrollOffset(gfx::Vector2d(-100, -100));
953 EXPECT_EQ(InputHandler::ScrollIgnored
,
954 root
->TryScroll(gfx::PointF(0.0f
, 1.0f
), InputHandler::Gesture
));
959 virtual void AfterTest() OVERRIDE
{}
962 SINGLE_AND_MULTI_THREAD_TEST_F(
963 LayerTreeHostScrollTestScrollZeroMaxScrollOffset
);
965 class ThreadCheckingInputHandlerClient
: public InputHandlerClient
{
967 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner
* runner
,
968 bool* received_stop_flinging
)
969 : task_runner_(runner
), received_stop_flinging_(received_stop_flinging
) {}
971 virtual void WillShutdown() OVERRIDE
{
972 if (!received_stop_flinging_
)
973 ADD_FAILURE() << "WillShutdown() called before fling stopped";
976 virtual void Animate(base::TimeTicks time
) OVERRIDE
{
977 if (!task_runner_
->BelongsToCurrentThread())
978 ADD_FAILURE() << "Animate called on wrong thread";
981 virtual void MainThreadHasStoppedFlinging() OVERRIDE
{
982 if (!task_runner_
->BelongsToCurrentThread())
983 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
984 *received_stop_flinging_
= true;
987 virtual void DidOverscroll(const DidOverscrollParams
& params
) OVERRIDE
{
988 if (!task_runner_
->BelongsToCurrentThread())
989 ADD_FAILURE() << "DidOverscroll called on wrong thread";
993 base::SingleThreadTaskRunner
* task_runner_
;
994 bool* received_stop_flinging_
;
997 void BindInputHandlerOnCompositorThread(
998 const base::WeakPtr
<InputHandler
>& input_handler
,
999 ThreadCheckingInputHandlerClient
* client
) {
1000 input_handler
->BindToClient(client
);
1003 TEST(LayerTreeHostFlingTest
, DidStopFlingingThread
) {
1004 base::Thread
impl_thread("cc");
1005 ASSERT_TRUE(impl_thread
.Start());
1007 bool received_stop_flinging
= false;
1008 LayerTreeSettings settings
;
1010 ThreadCheckingInputHandlerClient
input_handler_client(
1011 impl_thread
.message_loop_proxy().get(), &received_stop_flinging
);
1012 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1014 ASSERT_TRUE(impl_thread
.message_loop_proxy().get());
1015 scoped_ptr
<LayerTreeHost
> layer_tree_host
= LayerTreeHost::Create(
1016 &client
, NULL
, settings
, impl_thread
.message_loop_proxy());
1018 impl_thread
.message_loop_proxy()
1019 ->PostTask(FROM_HERE
,
1020 base::Bind(&BindInputHandlerOnCompositorThread
,
1021 layer_tree_host
->GetInputHandler(),
1022 base::Unretained(&input_handler_client
)));
1024 layer_tree_host
->DidStopFlinging();
1025 layer_tree_host
.reset();
1027 EXPECT_TRUE(received_stop_flinging
);
1030 class LayerTreeHostScrollTestLayerStructureChange
1031 : public LayerTreeHostScrollTest
{
1033 LayerTreeHostScrollTestLayerStructureChange()
1034 : scroll_destroy_whole_tree_(false) {}
1036 virtual void SetupTree() OVERRIDE
{
1037 scoped_refptr
<Layer
> root_layer
= Layer::Create();
1038 root_layer
->SetBounds(gfx::Size(10, 10));
1040 Layer
* root_scroll_layer
=
1041 CreateScrollLayer(root_layer
.get(), &root_scroll_layer_client_
);
1042 CreateScrollLayer(root_layer
.get(), &sibling_scroll_layer_client_
);
1043 CreateScrollLayer(root_scroll_layer
, &child_scroll_layer_client_
);
1045 layer_tree_host()->SetRootLayer(root_layer
);
1046 LayerTreeHostScrollTest::SetupTree();
1049 virtual void BeginTest() OVERRIDE
{
1050 PostSetNeedsCommitToMainThread();
1053 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1054 LayerImpl
* root
= impl
->active_tree()->root_layer();
1055 switch (impl
->active_tree()->source_frame_number()) {
1057 root
->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1058 root
->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1059 root
->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5));
1060 PostSetNeedsCommitToMainThread();
1068 virtual void AfterTest() OVERRIDE
{}
1070 virtual void DidScroll(Layer
* layer
) {
1071 if (scroll_destroy_whole_tree_
) {
1072 layer_tree_host()->SetRootLayer(NULL
);
1076 layer
->RemoveFromParent();
1080 class FakeLayerScrollClient
{
1083 owner_
->DidScroll(layer_
);
1085 LayerTreeHostScrollTestLayerStructureChange
* owner_
;
1089 Layer
* CreateScrollLayer(Layer
* parent
, FakeLayerScrollClient
* client
) {
1090 scoped_refptr
<Layer
> scroll_layer
=
1091 ContentLayer::Create(&fake_content_layer_client_
);
1092 scroll_layer
->SetBounds(gfx::Size(110, 110));
1093 scroll_layer
->SetPosition(gfx::Point(0, 0));
1094 scroll_layer
->SetAnchorPoint(gfx::PointF());
1095 scroll_layer
->SetIsDrawable(true);
1096 scroll_layer
->SetScrollable(true);
1097 scroll_layer
->SetMaxScrollOffset(gfx::Vector2d(100, 100));
1098 scroll_layer
->set_did_scroll_callback(base::Bind(
1099 &FakeLayerScrollClient::DidScroll
, base::Unretained(client
)));
1100 client
->owner_
= this;
1101 client
->layer_
= scroll_layer
.get();
1102 parent
->AddChild(scroll_layer
);
1103 return scroll_layer
.get();
1106 FakeLayerScrollClient root_scroll_layer_client_
;
1107 FakeLayerScrollClient sibling_scroll_layer_client_
;
1108 FakeLayerScrollClient child_scroll_layer_client_
;
1110 FakeContentLayerClient fake_content_layer_client_
;
1112 bool scroll_destroy_whole_tree_
;
1115 TEST_F(LayerTreeHostScrollTestLayerStructureChange
, ScrollDestroyLayer
) {
1116 RunTest(true, false, false);
1119 TEST_F(LayerTreeHostScrollTestLayerStructureChange
, ScrollDestroyWholeTree
) {
1120 scroll_destroy_whole_tree_
= true;
1121 RunTest(true, false, false);