Remove WebKitTestRunner::setClientWindowRect.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_scroll.cc
blob114262252949965b8d40980054539b791c515399
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"
20 namespace cc {
21 namespace {
23 class LayerTreeHostScrollTest : public LayerTreeTest {};
25 class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest {
26 public:
27 LayerTreeHostScrollTestScrollSimple()
28 : initial_scroll_(10, 20),
29 second_scroll_(40, 5),
30 scroll_amount_(2, -1),
31 num_scrolls_(0) {}
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());
45 } else {
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()) {
62 case 0:
63 EXPECT_VECTOR_EQ(initial_scroll_, root->scroll_offset());
64 EXPECT_VECTOR_EQ(scroll_amount_, root->ScrollDelta());
65 PostSetNeedsCommitToMainThread();
66 break;
67 case 1:
68 EXPECT_VECTOR_EQ(root->scroll_offset(), second_scroll_);
69 EXPECT_VECTOR_EQ(root->ScrollDelta(), scroll_amount_);
70 EndTest();
71 break;
75 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
76 float scale) OVERRIDE {
77 num_scrolls_++;
80 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); }
82 private:
83 gfx::Vector2d initial_scroll_;
84 gfx::Vector2d second_scroll_;
85 gfx::Vector2d scroll_amount_;
86 int num_scrolls_;
89 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple);
91 class LayerTreeHostScrollTestScrollMultipleRedraw
92 : public LayerTreeHostScrollTest {
93 public:
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()) {
109 case 0:
110 EXPECT_VECTOR_EQ(root->scroll_offset(), initial_scroll_);
111 break;
112 case 1:
113 EXPECT_VECTOR_EQ(root->scroll_offset(),
114 initial_scroll_ + scroll_amount_ + scroll_amount_);
115 case 2:
116 EXPECT_VECTOR_EQ(root->scroll_offset(),
117 initial_scroll_ + scroll_amount_ + scroll_amount_);
118 break;
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_);
148 EndTest();
152 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
153 float scale) OVERRIDE {
154 num_scrolls_++;
157 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); }
159 private:
160 gfx::Vector2d initial_scroll_;
161 gfx::Vector2d scroll_amount_;
162 int num_scrolls_;
165 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw);
167 class LayerTreeHostScrollTestScrollAbortedCommit
168 : public LayerTreeHostScrollTest {
169 public:
170 LayerTreeHostScrollTestScrollAbortedCommit()
171 : initial_scroll_(50, 60),
172 impl_scroll_(-3, 2),
173 second_main_scroll_(14, -3),
174 impl_scale_(2.f),
175 num_will_begin_main_frames_(0),
176 num_did_begin_main_frames_(0),
177 num_will_commits_(0),
178 num_did_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_) {
201 case 1:
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());
207 break;
208 case 2:
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();
217 break;
218 case 3:
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_);
228 break;
229 case 4:
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();
238 break;
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 {
249 num_impl_commits_++;
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) {
258 // First draw
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_);
298 EXPECT_VECTOR_EQ(
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_);
308 EndTest();
312 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
313 float scale) OVERRIDE {
314 num_impl_scrolls_++;
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_);
328 private:
329 gfx::Vector2d initial_scroll_;
330 gfx::Vector2d impl_scroll_;
331 gfx::Vector2d second_main_scroll_;
332 float impl_scale_;
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 {
344 public:
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
358 // multiple commits.
359 switch (impl->active_tree()->source_frame_number()) {
360 case 0:
361 EXPECT_VECTOR_EQ(root->scroll_offset(), gfx::Vector2d(0, 0));
362 EXPECT_VECTOR_EQ(root->ScrollDelta(), gfx::Vector2d(0, 0));
363 PostSetNeedsCommitToMainThread();
364 break;
365 case 1:
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();
371 break;
372 case 2:
373 EXPECT_VECTOR_EQ(
374 root->scroll_offset(),
375 gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_));
376 EXPECT_VECTOR_EQ(
377 root->ScrollDelta(),
378 gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f));
379 EndTest();
380 break;
382 root->ScrollBy(scroll_amount_);
385 virtual void AfterTest() OVERRIDE {}
387 private:
388 gfx::Vector2dF scroll_amount_;
391 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll);
393 class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
394 public:
395 LayerTreeHostScrollTestCaseWithChild()
396 : initial_offset_(10, 20),
397 javascript_scroll_(40, 5),
398 scroll_amount_(2, -1),
399 num_scrolls_(0) {}
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));
429 } else {
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_;
443 } else {
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();
464 void DidScroll() {
465 final_scroll_offset_ = expected_scroll_layer_->scroll_offset();
468 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
469 float scale) OVERRIDE {
470 num_scrolls_++;
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()) {
478 case 0:
479 EXPECT_VECTOR_EQ(initial_offset_,
480 expected_scroll_layer_->scroll_offset());
481 break;
482 case 1:
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_);
488 break;
489 case 2:
490 EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_,
491 expected_scroll_layer_->scroll_offset());
492 break;
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;
506 } else {
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()) {
526 case 0: {
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_);
534 impl->ScrollEnd();
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());
541 break;
543 case 1: {
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_);
551 impl->ScrollEnd();
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());
558 break;
560 case 2:
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());
567 EndTest();
568 break;
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_);
577 } else {
578 EXPECT_EQ(2, num_scrolls_);
579 EXPECT_VECTOR_EQ(gfx::Vector2d(), final_scroll_offset_);
583 protected:
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_;
590 int num_scrolls_;
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 {
707 public:
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 {
719 public:
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),
725 num_scrolls_(0) {}
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_);
739 } else {
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()) {
765 case 0:
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.
778 } else {
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_);
789 EXPECT_VECTOR_EQ(
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());
795 break;
796 case 1:
797 EXPECT_FALSE(impl->pending_tree());
798 EXPECT_VECTOR_EQ(
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());
803 EndTest();
804 break;
808 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
809 float scale) OVERRIDE {
810 num_scrolls_++;
813 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); }
815 private:
816 gfx::Vector2d initial_scroll_;
817 gfx::Vector2d main_thread_scroll_;
818 gfx::Vector2d impl_thread_scroll1_;
819 gfx::Vector2d impl_thread_scroll2_;
820 int num_scrolls_;
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
828 // push properties.
829 class ImplSidePaintingScrollTestImplOnlyScroll
830 : public ImplSidePaintingScrollTest {
831 public:
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()) {
846 case 0:
847 EXPECT_TRUE(root->needs_push_properties());
848 break;
849 case 1:
850 // Even if this layer doesn't need push properties, it should
851 // still pick up scrolls that happen on the active layer during
852 // commit.
853 EXPECT_FALSE(root->needs_push_properties());
854 break;
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()) {
875 case 0:
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);
880 break;
881 case 1:
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());
891 break;
892 case 2:
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());
898 EndTest();
899 break;
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()) {
909 case 0:
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();
914 break;
915 case 1:
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();
920 break;
924 virtual void AfterTest() OVERRIDE {}
926 private:
927 gfx::Vector2d initial_scroll_;
928 gfx::Vector2d impl_thread_scroll_;
931 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll);
933 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
934 : public LayerTreeHostScrollTest {
935 public:
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));
956 EndTest();
959 virtual void AfterTest() OVERRIDE {}
962 SINGLE_AND_MULTI_THREAD_TEST_F(
963 LayerTreeHostScrollTestScrollZeroMaxScrollOffset);
965 class ThreadCheckingInputHandlerClient : public InputHandlerClient {
966 public:
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";
992 private:
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();
1026 impl_thread.Stop();
1027 EXPECT_TRUE(received_stop_flinging);
1030 class LayerTreeHostScrollTestLayerStructureChange
1031 : public LayerTreeHostScrollTest {
1032 public:
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()) {
1056 case 0:
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();
1061 break;
1062 case 1:
1063 EndTest();
1064 break;
1068 virtual void AfterTest() OVERRIDE {}
1070 virtual void DidScroll(Layer* layer) {
1071 if (scroll_destroy_whole_tree_) {
1072 layer_tree_host()->SetRootLayer(NULL);
1073 EndTest();
1074 return;
1076 layer->RemoveFromParent();
1079 protected:
1080 class FakeLayerScrollClient {
1081 public:
1082 void DidScroll() {
1083 owner_->DidScroll(layer_);
1085 LayerTreeHostScrollTestLayerStructureChange* owner_;
1086 Layer* layer_;
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);
1124 } // namespace
1125 } // namespace cc