Lots of random cleanups, mostly for native_theme_win.cc:
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_scroll.cc
blob05a587640183f188ae2152e482d7dacb2c48030d
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/test/test_shared_bitmap_manager.h"
16 #include "cc/trees/layer_tree_impl.h"
17 #include "ui/gfx/point_conversions.h"
18 #include "ui/gfx/size_conversions.h"
19 #include "ui/gfx/vector2d_conversions.h"
21 namespace cc {
22 namespace {
24 class LayerTreeHostScrollTest : public LayerTreeTest {};
26 class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest {
27 public:
28 LayerTreeHostScrollTestScrollSimple()
29 : initial_scroll_(10, 20),
30 second_scroll_(40, 5),
31 scroll_amount_(2, -1),
32 num_scrolls_(0) {}
34 virtual void BeginTest() OVERRIDE {
35 Layer* root_layer = layer_tree_host()->root_layer();
36 scoped_refptr<Layer> scroll_layer = Layer::Create();
37 root_layer->AddChild(scroll_layer);
38 // Create an effective max_scroll_offset of (100, 100).
39 scroll_layer->SetBounds(gfx::Size(root_layer->bounds().width() + 100,
40 root_layer->bounds().height() + 100));
41 scroll_layer->SetIsDrawable(true);
42 scroll_layer->SetIsContainerForFixedPositionLayers(true);
43 scroll_layer->SetScrollClipLayerId(root_layer->id());
44 scroll_layer->SetScrollOffset(initial_scroll_);
45 layer_tree_host()->RegisterViewportLayers(root_layer, scroll_layer, NULL);
46 PostSetNeedsCommitToMainThread();
49 virtual void Layout() OVERRIDE {
50 Layer* root = layer_tree_host()->root_layer();
51 Layer* scroll_layer = root->children()[0];
52 if (!layer_tree_host()->source_frame_number()) {
53 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
54 } else {
55 EXPECT_VECTOR_EQ(initial_scroll_ + scroll_amount_,
56 scroll_layer->scroll_offset());
58 // Pretend like Javascript updated the scroll position itself.
59 scroll_layer->SetScrollOffset(second_scroll_);
63 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
64 LayerImpl* root = impl->active_tree()->root_layer();
65 LayerImpl* scroll_layer = root->children()[0];
66 EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer->ScrollDelta());
68 scroll_layer->SetScrollClipLayer(root->id());
69 scroll_layer->SetBounds(
70 gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
71 scroll_layer->ScrollBy(scroll_amount_);
73 switch (impl->active_tree()->source_frame_number()) {
74 case 0:
75 EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
76 EXPECT_VECTOR_EQ(scroll_amount_, scroll_layer->ScrollDelta());
77 PostSetNeedsCommitToMainThread();
78 break;
79 case 1:
80 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), second_scroll_);
81 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
82 EndTest();
83 break;
87 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
88 float scale) OVERRIDE {
89 num_scrolls_++;
92 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); }
94 private:
95 gfx::Vector2d initial_scroll_;
96 gfx::Vector2d second_scroll_;
97 gfx::Vector2d scroll_amount_;
98 int num_scrolls_;
101 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple);
103 class LayerTreeHostScrollTestScrollMultipleRedraw
104 : public LayerTreeHostScrollTest {
105 public:
106 LayerTreeHostScrollTestScrollMultipleRedraw()
107 : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
109 virtual void BeginTest() OVERRIDE {
110 Layer* root_layer = layer_tree_host()->root_layer();
111 scroll_layer_ = Layer::Create();
112 root_layer->AddChild(scroll_layer_);
113 // Create an effective max_scroll_offset of (100, 100).
114 scroll_layer_->SetBounds(gfx::Size(root_layer->bounds().width() + 100,
115 root_layer->bounds().height() + 100));
116 scroll_layer_->SetIsDrawable(true);
117 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
118 scroll_layer_->SetScrollClipLayerId(root_layer->id());
119 scroll_layer_->SetScrollOffset(initial_scroll_);
120 layer_tree_host()->RegisterViewportLayers(root_layer, scroll_layer_, NULL);
121 PostSetNeedsCommitToMainThread();
124 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
125 switch (layer_tree_host()->source_frame_number()) {
126 case 0:
127 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_);
128 break;
129 case 1:
130 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(),
131 initial_scroll_ + scroll_amount_ + scroll_amount_);
132 case 2:
133 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(),
134 initial_scroll_ + scroll_amount_ + scroll_amount_);
135 break;
139 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
140 LayerImpl* scroll_layer =
141 impl->active_tree()->LayerById(scroll_layer_->id());
142 if (impl->active_tree()->source_frame_number() == 0 &&
143 impl->SourceAnimationFrameNumber() == 1) {
144 // First draw after first commit.
145 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
146 scroll_layer->ScrollBy(scroll_amount_);
147 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
149 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
150 PostSetNeedsRedrawToMainThread();
151 } else if (impl->active_tree()->source_frame_number() == 0 &&
152 impl->SourceAnimationFrameNumber() == 2) {
153 // Second draw after first commit.
154 EXPECT_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
155 scroll_layer->ScrollBy(scroll_amount_);
156 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
157 scroll_amount_ + scroll_amount_);
159 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_);
160 PostSetNeedsCommitToMainThread();
161 } else if (impl->active_tree()->source_frame_number() == 1) {
162 // Third or later draw after second commit.
163 EXPECT_GE(impl->SourceAnimationFrameNumber(), 3);
164 EXPECT_VECTOR_EQ(scroll_layer_->ScrollDelta(), gfx::Vector2d());
165 EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(),
166 initial_scroll_ + scroll_amount_ + scroll_amount_);
167 EndTest();
171 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
172 float scale) OVERRIDE {
173 num_scrolls_++;
176 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); }
178 private:
179 gfx::Vector2d initial_scroll_;
180 gfx::Vector2d scroll_amount_;
181 int num_scrolls_;
182 scoped_refptr<Layer> scroll_layer_;
185 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw);
187 class LayerTreeHostScrollTestScrollAbortedCommit
188 : public LayerTreeHostScrollTest {
189 public:
190 LayerTreeHostScrollTestScrollAbortedCommit()
191 : initial_scroll_(50, 60),
192 impl_scroll_(-3, 2),
193 second_main_scroll_(14, -3),
194 impl_scale_(2.f),
195 num_will_begin_main_frames_(0),
196 num_did_begin_main_frames_(0),
197 num_will_commits_(0),
198 num_did_commits_(0),
199 num_impl_commits_(0),
200 num_impl_scrolls_(0) {}
202 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
204 virtual void SetupTree() OVERRIDE {
205 LayerTreeHostScrollTest::SetupTree();
206 Layer* root_layer = layer_tree_host()->root_layer();
207 scoped_refptr<Layer> root_scroll_layer = Layer::Create();
208 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
209 root_scroll_layer->SetScrollOffset(initial_scroll_);
210 root_scroll_layer->SetBounds(gfx::Size(200, 200));
211 root_scroll_layer->SetIsDrawable(true);
212 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
213 root_layer->AddChild(root_scroll_layer);
215 layer_tree_host()->RegisterViewportLayers(
216 root_layer, root_scroll_layer, NULL);
217 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
220 virtual void WillBeginMainFrame() OVERRIDE {
221 num_will_begin_main_frames_++;
222 Layer* root_scroll_layer = layer_tree_host()->root_layer()->children()[0];
223 switch (num_will_begin_main_frames_) {
224 case 1:
225 // This will not be aborted because of the initial prop changes.
226 EXPECT_EQ(0, num_impl_scrolls_);
227 EXPECT_EQ(0, layer_tree_host()->source_frame_number());
228 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_);
229 EXPECT_EQ(1.f, layer_tree_host()->page_scale_factor());
230 break;
231 case 2:
232 // This commit will be aborted, and another commit will be
233 // initiated from the redraw.
234 EXPECT_EQ(1, num_impl_scrolls_);
235 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
236 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
237 initial_scroll_ + impl_scroll_);
238 EXPECT_EQ(impl_scale_, layer_tree_host()->page_scale_factor());
239 PostSetNeedsRedrawToMainThread();
240 break;
241 case 3:
242 // This commit will not be aborted because of the scroll change.
243 EXPECT_EQ(2, num_impl_scrolls_);
244 // The source frame number still increases even with the abort.
245 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
246 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
247 initial_scroll_ + impl_scroll_ + impl_scroll_);
248 EXPECT_EQ(impl_scale_ * impl_scale_,
249 layer_tree_host()->page_scale_factor());
250 root_scroll_layer->SetScrollOffset(root_scroll_layer->scroll_offset() +
251 second_main_scroll_);
252 break;
253 case 4:
254 // This commit will also be aborted.
255 EXPECT_EQ(3, num_impl_scrolls_);
256 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
257 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
258 initial_scroll_ + impl_scroll_ + impl_scroll_ +
259 impl_scroll_ + second_main_scroll_);
260 // End the test by drawing to verify this commit is also aborted.
261 PostSetNeedsRedrawToMainThread();
262 break;
266 virtual void DidBeginMainFrame() OVERRIDE { num_did_begin_main_frames_++; }
268 virtual void WillCommit() OVERRIDE { num_will_commits_++; }
270 virtual void DidCommit() OVERRIDE { num_did_commits_++; }
272 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
273 num_impl_commits_++;
276 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
277 LayerImpl* root_scroll_layer =
278 impl->active_tree()->root_layer()->children()[0];
280 if (impl->active_tree()->source_frame_number() == 0 &&
281 impl->SourceAnimationFrameNumber() == 1) {
282 // First draw
283 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
284 root_scroll_layer->ScrollBy(impl_scroll_);
285 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
286 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_);
288 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
289 EXPECT_EQ(1.f, impl->active_tree()->total_page_scale_factor());
290 impl->active_tree()->SetPageScaleDelta(impl_scale_);
291 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
292 EXPECT_EQ(impl_scale_, impl->active_tree()->total_page_scale_factor());
294 // To simplify the testing flow, don't redraw here, just commit.
295 impl->SetNeedsCommit();
296 } else if (impl->active_tree()->source_frame_number() == 0 &&
297 impl->SourceAnimationFrameNumber() == 2) {
298 // Test a second draw after an aborted commit.
299 // The scroll/scale values should be baked into the offset/scale factor
300 // since the main thread consumed but aborted the begin frame.
301 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
302 root_scroll_layer->ScrollBy(impl_scroll_);
303 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
304 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
305 initial_scroll_ + impl_scroll_);
307 EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
308 EXPECT_EQ(impl_scale_, impl->active_tree()->total_page_scale_factor());
309 impl->active_tree()->SetPageScaleDelta(impl_scale_);
310 EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
311 EXPECT_EQ(impl_scale_ * impl_scale_,
312 impl->active_tree()->total_page_scale_factor());
314 impl->SetNeedsCommit();
315 } else if (impl->active_tree()->source_frame_number() == 1) {
316 // Commit for source frame 1 is aborted.
317 NOTREACHED();
318 } else if (impl->active_tree()->source_frame_number() == 2 &&
319 impl->SourceAnimationFrameNumber() == 3) {
320 // Third draw after the second full commit.
321 EXPECT_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
322 root_scroll_layer->ScrollBy(impl_scroll_);
323 impl->SetNeedsCommit();
324 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
325 EXPECT_VECTOR_EQ(
326 root_scroll_layer->scroll_offset(),
327 initial_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_);
328 } else if (impl->active_tree()->source_frame_number() == 2 &&
329 impl->SourceAnimationFrameNumber() == 4) {
330 // Final draw after the second aborted commit.
331 EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
332 EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
333 initial_scroll_ + impl_scroll_ + impl_scroll_ +
334 impl_scroll_ + second_main_scroll_);
335 EndTest();
336 } else {
337 // Commit for source frame 3 is aborted.
338 NOTREACHED();
342 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
343 float scale) OVERRIDE {
344 num_impl_scrolls_++;
347 virtual void AfterTest() OVERRIDE {
348 EXPECT_EQ(3, num_impl_scrolls_);
349 // Verify that the embedder sees aborted commits as real commits.
350 EXPECT_EQ(4, num_will_begin_main_frames_);
351 EXPECT_EQ(4, num_did_begin_main_frames_);
352 EXPECT_EQ(4, num_will_commits_);
353 EXPECT_EQ(4, num_did_commits_);
354 // ...but the compositor thread only sees two real ones.
355 EXPECT_EQ(2, num_impl_commits_);
358 private:
359 gfx::Vector2d initial_scroll_;
360 gfx::Vector2d impl_scroll_;
361 gfx::Vector2d second_main_scroll_;
362 float impl_scale_;
363 int num_will_begin_main_frames_;
364 int num_did_begin_main_frames_;
365 int num_will_commits_;
366 int num_did_commits_;
367 int num_impl_commits_;
368 int num_impl_scrolls_;
371 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit);
373 class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest {
374 public:
375 LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
377 virtual void SetupTree() OVERRIDE {
378 LayerTreeHostScrollTest::SetupTree();
379 Layer* root_layer = layer_tree_host()->root_layer();
380 scoped_refptr<Layer> root_scroll_layer = Layer::Create();
381 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
382 root_scroll_layer->SetBounds(
383 gfx::Size(root_layer->bounds().width() + 100,
384 root_layer->bounds().height() + 100));
385 root_scroll_layer->SetIsDrawable(true);
386 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
387 root_layer->AddChild(root_scroll_layer);
389 layer_tree_host()->RegisterViewportLayers(
390 root_layer, root_scroll_layer, NULL);
391 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
394 virtual void BeginTest() OVERRIDE {
395 PostSetNeedsCommitToMainThread();
398 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
399 LayerImpl* root = impl->active_tree()->root_layer();
400 LayerImpl* scroll_layer = root->children()[0];
402 // Check that a fractional scroll delta is correctly accumulated over
403 // multiple commits.
404 switch (impl->active_tree()->source_frame_number()) {
405 case 0:
406 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), gfx::Vector2d(0, 0));
407 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d(0, 0));
408 PostSetNeedsCommitToMainThread();
409 break;
410 case 1:
411 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(),
412 gfx::ToFlooredVector2d(scroll_amount_));
413 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
414 gfx::Vector2dF(fmod(scroll_amount_.x(), 1.0f), 0.0f));
415 PostSetNeedsCommitToMainThread();
416 break;
417 case 2:
418 EXPECT_VECTOR_EQ(
419 scroll_layer->scroll_offset(),
420 gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_));
421 EXPECT_VECTOR_EQ(
422 scroll_layer->ScrollDelta(),
423 gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f));
424 EndTest();
425 break;
427 scroll_layer->ScrollBy(scroll_amount_);
430 virtual void AfterTest() OVERRIDE {}
432 private:
433 gfx::Vector2dF scroll_amount_;
436 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll);
438 class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
439 public:
440 LayerTreeHostScrollTestCaseWithChild()
441 : initial_offset_(10, 20),
442 javascript_scroll_(40, 5),
443 scroll_amount_(2, -1),
444 num_scrolls_(0) {}
446 virtual void SetupTree() OVERRIDE {
447 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
449 scoped_refptr<Layer> root_layer = Layer::Create();
450 root_layer->SetBounds(gfx::Size(10, 10));
452 root_scroll_layer_ = ContentLayer::Create(&fake_content_layer_client_);
453 root_scroll_layer_->SetBounds(gfx::Size(110, 110));
455 root_scroll_layer_->SetPosition(gfx::Point());
457 root_scroll_layer_->SetIsDrawable(true);
458 root_scroll_layer_->SetScrollClipLayerId(root_layer->id());
459 root_scroll_layer_->SetIsContainerForFixedPositionLayers(true);
460 root_layer->AddChild(root_scroll_layer_);
462 child_layer_ = ContentLayer::Create(&fake_content_layer_client_);
463 child_layer_->set_did_scroll_callback(
464 base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
465 base::Unretained(this)));
466 child_layer_->SetBounds(gfx::Size(110, 110));
468 if (scroll_child_layer_) {
469 // Scrolls on the child layer will happen at 5, 5. If they are treated
470 // like device pixels, and device scale factor is 2, then they will
471 // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
472 child_layer_->SetPosition(gfx::Point(5, 5));
473 } else {
474 // Adjust the child layer horizontally so that scrolls will never hit it.
475 child_layer_->SetPosition(gfx::Point(60, 5));
478 child_layer_->SetIsDrawable(true);
479 child_layer_->SetScrollClipLayerId(root_layer->id());
480 child_layer_->SetBounds(root_scroll_layer_->bounds());
481 root_scroll_layer_->AddChild(child_layer_);
483 if (scroll_child_layer_) {
484 expected_scroll_layer_ = child_layer_;
485 expected_no_scroll_layer_ = root_scroll_layer_;
486 } else {
487 expected_scroll_layer_ = root_scroll_layer_;
488 expected_no_scroll_layer_ = child_layer_;
491 expected_scroll_layer_->SetScrollOffset(initial_offset_);
493 layer_tree_host()->SetRootLayer(root_layer);
494 layer_tree_host()->RegisterViewportLayers(
495 root_layer, root_scroll_layer_, NULL);
496 LayerTreeHostScrollTest::SetupTree();
499 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
501 virtual void WillCommit() OVERRIDE {
502 // Keep the test committing (otherwise the early out for no update
503 // will stall the test).
504 if (layer_tree_host()->source_frame_number() < 2) {
505 layer_tree_host()->SetNeedsCommit();
509 void DidScroll() {
510 final_scroll_offset_ = expected_scroll_layer_->scroll_offset();
513 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
514 float scale) OVERRIDE {
515 num_scrolls_++;
518 virtual void Layout() OVERRIDE {
519 EXPECT_VECTOR_EQ(gfx::Vector2d(),
520 expected_no_scroll_layer_->scroll_offset());
522 switch (layer_tree_host()->source_frame_number()) {
523 case 0:
524 EXPECT_VECTOR_EQ(initial_offset_,
525 expected_scroll_layer_->scroll_offset());
526 break;
527 case 1:
528 EXPECT_VECTOR_EQ(initial_offset_ + scroll_amount_,
529 expected_scroll_layer_->scroll_offset());
531 // Pretend like Javascript updated the scroll position itself.
532 expected_scroll_layer_->SetScrollOffset(javascript_scroll_);
533 break;
534 case 2:
535 EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_,
536 expected_scroll_layer_->scroll_offset());
537 break;
541 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
542 LayerImpl* root_impl = impl->active_tree()->root_layer();
543 LayerImpl* root_scroll_layer_impl = root_impl->children()[0];
544 LayerImpl* child_layer_impl = root_scroll_layer_impl->children()[0];
546 LayerImpl* expected_scroll_layer_impl = NULL;
547 LayerImpl* expected_no_scroll_layer_impl = NULL;
548 if (scroll_child_layer_) {
549 expected_scroll_layer_impl = child_layer_impl;
550 expected_no_scroll_layer_impl = root_scroll_layer_impl;
551 } else {
552 expected_scroll_layer_impl = root_scroll_layer_impl;
553 expected_no_scroll_layer_impl = child_layer_impl;
556 EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl->ScrollDelta());
557 EXPECT_VECTOR_EQ(gfx::Vector2d(),
558 expected_no_scroll_layer_impl->ScrollDelta());
560 // Ensure device scale factor is affecting the layers.
561 gfx::Size expected_content_bounds = gfx::ToCeiledSize(
562 gfx::ScaleSize(root_scroll_layer_impl->bounds(), device_scale_factor_));
563 EXPECT_SIZE_EQ(expected_content_bounds,
564 root_scroll_layer_->content_bounds());
566 expected_content_bounds = gfx::ToCeiledSize(
567 gfx::ScaleSize(child_layer_impl->bounds(), device_scale_factor_));
568 EXPECT_SIZE_EQ(expected_content_bounds, child_layer_->content_bounds());
570 switch (impl->active_tree()->source_frame_number()) {
571 case 0: {
572 // Gesture scroll on impl thread.
573 InputHandler::ScrollStatus status = impl->ScrollBegin(
574 gfx::ToCeiledPoint(expected_scroll_layer_impl->position() -
575 gfx::Vector2dF(0.5f, 0.5f)),
576 InputHandler::Gesture);
577 EXPECT_EQ(InputHandler::ScrollStarted, status);
578 impl->ScrollBy(gfx::Point(), scroll_amount_);
579 impl->ScrollEnd();
581 // Check the scroll is applied as a delta.
582 EXPECT_VECTOR_EQ(initial_offset_,
583 expected_scroll_layer_impl->scroll_offset());
584 EXPECT_VECTOR_EQ(scroll_amount_,
585 expected_scroll_layer_impl->ScrollDelta());
586 break;
588 case 1: {
589 // Wheel scroll on impl thread.
590 InputHandler::ScrollStatus status = impl->ScrollBegin(
591 gfx::ToCeiledPoint(expected_scroll_layer_impl->position() +
592 gfx::Vector2dF(0.5f, 0.5f)),
593 InputHandler::Wheel);
594 EXPECT_EQ(InputHandler::ScrollStarted, status);
595 impl->ScrollBy(gfx::Point(), scroll_amount_);
596 impl->ScrollEnd();
598 // Check the scroll is applied as a delta.
599 EXPECT_VECTOR_EQ(javascript_scroll_,
600 expected_scroll_layer_impl->scroll_offset());
601 EXPECT_VECTOR_EQ(scroll_amount_,
602 expected_scroll_layer_impl->ScrollDelta());
603 break;
605 case 2:
607 EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_,
608 expected_scroll_layer_impl->scroll_offset());
609 EXPECT_VECTOR_EQ(gfx::Vector2d(),
610 expected_scroll_layer_impl->ScrollDelta());
612 EndTest();
613 break;
617 virtual void AfterTest() OVERRIDE {
618 if (scroll_child_layer_) {
619 EXPECT_EQ(0, num_scrolls_);
620 EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_,
621 final_scroll_offset_);
622 } else {
623 EXPECT_EQ(2, num_scrolls_);
624 EXPECT_VECTOR_EQ(gfx::Vector2d(), final_scroll_offset_);
628 protected:
629 float device_scale_factor_;
630 bool scroll_child_layer_;
632 gfx::Vector2d initial_offset_;
633 gfx::Vector2d javascript_scroll_;
634 gfx::Vector2d scroll_amount_;
635 int num_scrolls_;
636 gfx::Vector2d final_scroll_offset_;
638 FakeContentLayerClient fake_content_layer_client_;
640 scoped_refptr<Layer> root_scroll_layer_;
641 scoped_refptr<Layer> child_layer_;
642 scoped_refptr<Layer> expected_scroll_layer_;
643 scoped_refptr<Layer> expected_no_scroll_layer_;
646 TEST_F(LayerTreeHostScrollTestCaseWithChild,
647 DeviceScaleFactor1_ScrollChild_DirectRenderer_MainThreadPaint) {
648 device_scale_factor_ = 1.f;
649 scroll_child_layer_ = true;
650 RunTest(true, false, false);
653 TEST_F(LayerTreeHostScrollTestCaseWithChild,
654 DeviceScaleFactor1_ScrollChild_DirectRenderer_ImplSidePaint) {
655 device_scale_factor_ = 1.f;
656 scroll_child_layer_ = true;
657 RunTest(true, false, true);
660 TEST_F(LayerTreeHostScrollTestCaseWithChild,
661 DeviceScaleFactor1_ScrollChild_DelegatingRenderer_MainThreadPaint) {
662 device_scale_factor_ = 1.f;
663 scroll_child_layer_ = true;
664 RunTest(true, true, false);
667 TEST_F(LayerTreeHostScrollTestCaseWithChild,
668 DeviceScaleFactor1_ScrollChild_DelegatingRenderer_ImplSidePaint) {
669 device_scale_factor_ = 1.f;
670 scroll_child_layer_ = true;
671 RunTest(true, true, true);
674 TEST_F(LayerTreeHostScrollTestCaseWithChild,
675 DeviceScaleFactor15_ScrollChild_DirectRenderer) {
676 device_scale_factor_ = 1.5f;
677 scroll_child_layer_ = true;
678 RunTest(true, false, true);
681 TEST_F(LayerTreeHostScrollTestCaseWithChild,
682 DeviceScaleFactor15_ScrollChild_DelegatingRenderer) {
683 device_scale_factor_ = 1.5f;
684 scroll_child_layer_ = true;
685 RunTest(true, true, true);
688 TEST_F(LayerTreeHostScrollTestCaseWithChild,
689 DeviceScaleFactor2_ScrollChild_DirectRenderer) {
690 device_scale_factor_ = 2.f;
691 scroll_child_layer_ = true;
692 RunTest(true, false, true);
695 TEST_F(LayerTreeHostScrollTestCaseWithChild,
696 DeviceScaleFactor2_ScrollChild_DelegatingRenderer) {
697 device_scale_factor_ = 2.f;
698 scroll_child_layer_ = true;
699 RunTest(true, true, true);
702 TEST_F(LayerTreeHostScrollTestCaseWithChild,
703 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer) {
704 device_scale_factor_ = 1.f;
705 scroll_child_layer_ = false;
706 RunTest(true, false, true);
709 TEST_F(LayerTreeHostScrollTestCaseWithChild,
710 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer) {
711 device_scale_factor_ = 1.f;
712 scroll_child_layer_ = false;
713 RunTest(true, true, true);
716 TEST_F(LayerTreeHostScrollTestCaseWithChild,
717 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer) {
718 device_scale_factor_ = 1.5f;
719 scroll_child_layer_ = false;
720 RunTest(true, false, true);
723 TEST_F(LayerTreeHostScrollTestCaseWithChild,
724 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer) {
725 device_scale_factor_ = 1.5f;
726 scroll_child_layer_ = false;
727 RunTest(true, true, true);
730 TEST_F(LayerTreeHostScrollTestCaseWithChild,
731 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer_MainSidePaint) {
732 device_scale_factor_ = 2.f;
733 scroll_child_layer_ = false;
734 RunTest(true, false, false);
737 TEST_F(LayerTreeHostScrollTestCaseWithChild,
738 DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer_ImplSidePaint) {
739 device_scale_factor_ = 2.f;
740 scroll_child_layer_ = false;
741 RunTest(true, false, true);
744 TEST_F(LayerTreeHostScrollTestCaseWithChild,
745 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer) {
746 device_scale_factor_ = 2.f;
747 scroll_child_layer_ = false;
748 RunTest(true, true, true);
751 class ImplSidePaintingScrollTest : public LayerTreeHostScrollTest {
752 public:
753 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
754 settings->impl_side_painting = true;
757 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
758 if (impl->pending_tree())
759 impl->SetNeedsRedraw();
763 class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest {
764 public:
765 ImplSidePaintingScrollTestSimple()
766 : initial_scroll_(10, 20),
767 main_thread_scroll_(40, 5),
768 impl_thread_scroll1_(2, -1),
769 impl_thread_scroll2_(-3, 10),
770 num_scrolls_(0) {}
772 virtual void SetupTree() OVERRIDE {
773 LayerTreeHostScrollTest::SetupTree();
774 Layer* root_layer = layer_tree_host()->root_layer();
775 scoped_refptr<Layer> root_scroll_layer = Layer::Create();
776 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
777 root_scroll_layer->SetScrollOffset(initial_scroll_);
778 root_scroll_layer->SetBounds(
779 gfx::Size(root_layer->bounds().width() + 100,
780 root_layer->bounds().height() + 100));
781 root_scroll_layer->SetIsDrawable(true);
782 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
783 root_layer->AddChild(root_scroll_layer);
785 layer_tree_host()->RegisterViewportLayers(
786 root_layer, root_scroll_layer, NULL);
787 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
790 virtual void BeginTest() OVERRIDE {
791 PostSetNeedsCommitToMainThread();
794 virtual void Layout() OVERRIDE {
795 Layer* root = layer_tree_host()->root_layer();
796 Layer* scroll_layer = root->children()[0];
797 if (!layer_tree_host()->source_frame_number()) {
798 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
799 } else {
800 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(),
801 initial_scroll_ + impl_thread_scroll1_);
803 // Pretend like Javascript updated the scroll position itself with a
804 // change of main_thread_scroll.
805 scroll_layer->SetScrollOffset(initial_scroll_ + main_thread_scroll_ +
806 impl_thread_scroll1_);
810 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
811 // We force a second draw here of the first commit before activating
812 // the second commit.
813 if (impl->active_tree()->source_frame_number() == 0)
814 impl->SetNeedsRedraw();
817 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
818 ImplSidePaintingScrollTest::DrawLayersOnThread(impl);
820 LayerImpl* root = impl->active_tree()->root_layer();
821 LayerImpl* scroll_layer = root->children()[0];
822 LayerImpl* pending_root =
823 impl->active_tree()->FindPendingTreeLayerById(root->id());
825 switch (impl->active_tree()->source_frame_number()) {
826 case 0:
827 if (!impl->pending_tree()) {
828 impl->BlockNotifyReadyToActivateForTesting(true);
829 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
830 scroll_layer->ScrollBy(impl_thread_scroll1_);
832 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
833 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll1_);
834 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
835 PostSetNeedsCommitToMainThread();
837 // CommitCompleteOnThread will trigger this function again
838 // and cause us to take the else clause.
839 } else {
840 impl->BlockNotifyReadyToActivateForTesting(false);
841 ASSERT_TRUE(pending_root);
842 EXPECT_EQ(impl->pending_tree()->source_frame_number(), 1);
844 scroll_layer->ScrollBy(impl_thread_scroll2_);
845 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
846 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
847 impl_thread_scroll1_ + impl_thread_scroll2_);
848 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(),
849 impl_thread_scroll1_);
851 LayerImpl* pending_scroll_layer = pending_root->children()[0];
852 EXPECT_VECTOR_EQ(
853 pending_scroll_layer->scroll_offset(),
854 initial_scroll_ + main_thread_scroll_ + impl_thread_scroll1_);
855 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(),
856 impl_thread_scroll2_);
857 EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
858 gfx::Vector2d());
860 break;
861 case 1:
862 EXPECT_FALSE(impl->pending_tree());
863 EXPECT_VECTOR_EQ(
864 scroll_layer->scroll_offset(),
865 initial_scroll_ + main_thread_scroll_ + impl_thread_scroll1_);
866 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll2_);
867 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
868 EndTest();
869 break;
873 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
874 float scale) OVERRIDE {
875 num_scrolls_++;
878 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); }
880 private:
881 gfx::Vector2d initial_scroll_;
882 gfx::Vector2d main_thread_scroll_;
883 gfx::Vector2d impl_thread_scroll1_;
884 gfx::Vector2d impl_thread_scroll2_;
885 int num_scrolls_;
888 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple);
890 // This test makes sure that layers pick up scrolls that occur between
891 // beginning a commit and finishing a commit (aka scroll deltas not
892 // included in sent scroll delta) still apply to layers that don't
893 // push properties.
894 class ImplSidePaintingScrollTestImplOnlyScroll
895 : public ImplSidePaintingScrollTest {
896 public:
897 ImplSidePaintingScrollTestImplOnlyScroll()
898 : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3) {}
900 virtual void SetupTree() OVERRIDE {
901 LayerTreeHostScrollTest::SetupTree();
902 Layer* root_layer = layer_tree_host()->root_layer();
903 scoped_refptr<Layer> root_scroll_layer = Layer::Create();
904 root_scroll_layer->SetScrollClipLayerId(root_layer->id());
905 root_scroll_layer->SetScrollOffset(initial_scroll_);
906 root_scroll_layer->SetBounds(
907 gfx::Size(root_layer->bounds().width() + 100,
908 root_layer->bounds().height() + 100));
909 root_scroll_layer->SetIsDrawable(true);
910 root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
911 root_layer->AddChild(root_scroll_layer);
913 layer_tree_host()->RegisterViewportLayers(
914 root_layer, root_scroll_layer, NULL);
915 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
918 virtual void BeginTest() OVERRIDE {
919 PostSetNeedsCommitToMainThread();
922 virtual void WillCommit() OVERRIDE {
923 Layer* root = layer_tree_host()->root_layer();
924 Layer* scroll_layer = root->children()[0];
925 switch (layer_tree_host()->source_frame_number()) {
926 case 0:
927 EXPECT_TRUE(scroll_layer->needs_push_properties());
928 break;
929 case 1:
930 // Even if this layer doesn't need push properties, it should
931 // still pick up scrolls that happen on the active layer during
932 // commit.
933 EXPECT_FALSE(scroll_layer->needs_push_properties());
934 break;
938 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
939 // Scroll after the 2nd commit has started.
940 if (impl->active_tree()->source_frame_number() == 0) {
941 LayerImpl* active_root = impl->active_tree()->root_layer();
942 LayerImpl* active_scroll_layer = active_root->children()[0];
943 ASSERT_TRUE(active_root);
944 ASSERT_TRUE(active_scroll_layer);
945 active_scroll_layer->ScrollBy(impl_thread_scroll_);
949 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
950 // We force a second draw here of the first commit before activating
951 // the second commit.
952 LayerImpl* active_root = impl->active_tree()->root_layer();
953 LayerImpl* active_scroll_layer =
954 active_root ? active_root->children()[0] : NULL;
955 LayerImpl* pending_root = impl->pending_tree()->root_layer();
956 LayerImpl* pending_scroll_layer = pending_root->children()[0];
958 ASSERT_TRUE(pending_root);
959 ASSERT_TRUE(pending_scroll_layer);
960 switch (impl->pending_tree()->source_frame_number()) {
961 case 0:
962 EXPECT_VECTOR_EQ(pending_scroll_layer->scroll_offset(),
963 initial_scroll_);
964 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d());
965 EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
966 gfx::Vector2d());
967 EXPECT_FALSE(active_root);
968 break;
969 case 1:
970 // Even though the scroll happened during the commit, both layers
971 // should have the appropriate scroll delta.
972 EXPECT_VECTOR_EQ(pending_scroll_layer->scroll_offset(),
973 initial_scroll_);
974 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(),
975 impl_thread_scroll_);
976 EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
977 gfx::Vector2d());
978 ASSERT_TRUE(active_root);
979 EXPECT_VECTOR_EQ(active_scroll_layer->scroll_offset(), initial_scroll_);
980 EXPECT_VECTOR_EQ(active_scroll_layer->ScrollDelta(),
981 impl_thread_scroll_);
982 EXPECT_VECTOR_EQ(active_scroll_layer->sent_scroll_delta(),
983 gfx::Vector2d());
984 break;
985 case 2:
986 // On the next commit, this delta should have been sent and applied.
987 EXPECT_VECTOR_EQ(pending_scroll_layer->scroll_offset(),
988 initial_scroll_ + impl_thread_scroll_);
989 EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d());
990 EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
991 gfx::Vector2d());
992 EndTest();
993 break;
997 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
998 ImplSidePaintingScrollTest::DrawLayersOnThread(impl);
1000 LayerImpl* root = impl->active_tree()->root_layer();
1001 LayerImpl* scroll_layer = root->children()[0];
1003 switch (impl->active_tree()->source_frame_number()) {
1004 case 0:
1005 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
1006 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
1007 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
1008 PostSetNeedsCommitToMainThread();
1009 break;
1010 case 1:
1011 EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
1012 EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll_);
1013 EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
1014 PostSetNeedsCommitToMainThread();
1015 break;
1019 virtual void AfterTest() OVERRIDE {}
1021 private:
1022 gfx::Vector2d initial_scroll_;
1023 gfx::Vector2d impl_thread_scroll_;
1026 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll);
1028 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
1029 : public LayerTreeHostScrollTest {
1030 public:
1031 LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
1033 virtual void SetupTree() OVERRIDE {
1034 LayerTreeTest::SetupTree();
1035 scoped_refptr<Layer> scroll_layer = Layer::Create();
1036 layer_tree_host()->root_layer()->AddChild(scroll_layer);
1039 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1041 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1042 LayerImpl* root = impl->active_tree()->root_layer();
1043 LayerImpl* scroll_layer = root->children()[0];
1044 scroll_layer->SetScrollClipLayer(root->id());
1046 // Set max_scroll_offset = (100, 100).
1047 scroll_layer->SetBounds(
1048 gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
1049 EXPECT_EQ(InputHandler::ScrollStarted,
1050 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f),
1051 InputHandler::Gesture));
1053 // Set max_scroll_offset = (0, 0).
1054 scroll_layer->SetBounds(root->bounds());
1055 EXPECT_EQ(InputHandler::ScrollIgnored,
1056 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f),
1057 InputHandler::Gesture));
1059 // Set max_scroll_offset = (-100, -100).
1060 scroll_layer->SetBounds(gfx::Size());
1061 EXPECT_EQ(InputHandler::ScrollIgnored,
1062 scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f),
1063 InputHandler::Gesture));
1065 EndTest();
1068 virtual void AfterTest() OVERRIDE {}
1071 SINGLE_AND_MULTI_THREAD_TEST_F(
1072 LayerTreeHostScrollTestScrollZeroMaxScrollOffset);
1074 class ThreadCheckingInputHandlerClient : public InputHandlerClient {
1075 public:
1076 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner* runner,
1077 bool* received_stop_flinging)
1078 : task_runner_(runner), received_stop_flinging_(received_stop_flinging) {}
1080 virtual void WillShutdown() OVERRIDE {
1081 if (!received_stop_flinging_)
1082 ADD_FAILURE() << "WillShutdown() called before fling stopped";
1085 virtual void Animate(base::TimeTicks time) OVERRIDE {
1086 if (!task_runner_->BelongsToCurrentThread())
1087 ADD_FAILURE() << "Animate called on wrong thread";
1090 virtual void MainThreadHasStoppedFlinging() OVERRIDE {
1091 if (!task_runner_->BelongsToCurrentThread())
1092 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
1093 *received_stop_flinging_ = true;
1096 virtual void DidOverscroll(const gfx::Vector2dF& accumulated_overscroll,
1097 const gfx::Vector2dF& latest_overscroll_delta)
1098 OVERRIDE {
1099 if (!task_runner_->BelongsToCurrentThread())
1100 ADD_FAILURE() << "DidOverscroll called on wrong thread";
1103 private:
1104 base::SingleThreadTaskRunner* task_runner_;
1105 bool* received_stop_flinging_;
1108 void BindInputHandlerOnCompositorThread(
1109 const base::WeakPtr<InputHandler>& input_handler,
1110 ThreadCheckingInputHandlerClient* client) {
1111 input_handler->BindToClient(client);
1114 TEST(LayerTreeHostFlingTest, DidStopFlingingThread) {
1115 base::Thread impl_thread("cc");
1116 ASSERT_TRUE(impl_thread.Start());
1118 bool received_stop_flinging = false;
1119 LayerTreeSettings settings;
1121 ThreadCheckingInputHandlerClient input_handler_client(
1122 impl_thread.message_loop_proxy().get(), &received_stop_flinging);
1123 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1125 ASSERT_TRUE(impl_thread.message_loop_proxy().get());
1126 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1127 new TestSharedBitmapManager());
1128 scoped_ptr<LayerTreeHost> layer_tree_host =
1129 LayerTreeHost::CreateThreaded(&client,
1130 shared_bitmap_manager.get(),
1131 settings,
1132 impl_thread.message_loop_proxy());
1134 impl_thread.message_loop_proxy()
1135 ->PostTask(FROM_HERE,
1136 base::Bind(&BindInputHandlerOnCompositorThread,
1137 layer_tree_host->GetInputHandler(),
1138 base::Unretained(&input_handler_client)));
1140 layer_tree_host->DidStopFlinging();
1141 layer_tree_host.reset();
1142 impl_thread.Stop();
1143 EXPECT_TRUE(received_stop_flinging);
1146 class LayerTreeHostScrollTestLayerStructureChange
1147 : public LayerTreeHostScrollTest {
1148 public:
1149 LayerTreeHostScrollTestLayerStructureChange()
1150 : scroll_destroy_whole_tree_(false) {}
1152 virtual void SetupTree() OVERRIDE {
1153 scoped_refptr<Layer> root_layer = Layer::Create();
1154 root_layer->SetBounds(gfx::Size(10, 10));
1156 Layer* root_scroll_layer =
1157 CreateScrollLayer(root_layer.get(), &root_scroll_layer_client_);
1158 CreateScrollLayer(root_layer.get(), &sibling_scroll_layer_client_);
1159 CreateScrollLayer(root_scroll_layer, &child_scroll_layer_client_);
1161 layer_tree_host()->SetRootLayer(root_layer);
1162 LayerTreeHostScrollTest::SetupTree();
1165 virtual void BeginTest() OVERRIDE {
1166 PostSetNeedsCommitToMainThread();
1169 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1170 LayerImpl* root = impl->active_tree()->root_layer();
1171 switch (impl->active_tree()->source_frame_number()) {
1172 case 0:
1173 root->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1174 root->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
1175 root->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5));
1176 PostSetNeedsCommitToMainThread();
1177 break;
1178 case 1:
1179 EndTest();
1180 break;
1184 virtual void AfterTest() OVERRIDE {}
1186 virtual void DidScroll(Layer* layer) {
1187 if (scroll_destroy_whole_tree_) {
1188 layer_tree_host()->SetRootLayer(NULL);
1189 EndTest();
1190 return;
1192 layer->RemoveFromParent();
1195 protected:
1196 class FakeLayerScrollClient {
1197 public:
1198 void DidScroll() {
1199 owner_->DidScroll(layer_);
1201 LayerTreeHostScrollTestLayerStructureChange* owner_;
1202 Layer* layer_;
1205 Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) {
1206 scoped_refptr<Layer> scroll_layer =
1207 ContentLayer::Create(&fake_content_layer_client_);
1208 scroll_layer->SetBounds(gfx::Size(110, 110));
1209 scroll_layer->SetPosition(gfx::Point(0, 0));
1210 scroll_layer->SetIsDrawable(true);
1211 scroll_layer->SetScrollClipLayerId(parent->id());
1212 scroll_layer->SetBounds(gfx::Size(parent->bounds().width() + 100,
1213 parent->bounds().height() + 100));
1214 scroll_layer->set_did_scroll_callback(base::Bind(
1215 &FakeLayerScrollClient::DidScroll, base::Unretained(client)));
1216 client->owner_ = this;
1217 client->layer_ = scroll_layer.get();
1218 parent->AddChild(scroll_layer);
1219 return scroll_layer.get();
1222 FakeLayerScrollClient root_scroll_layer_client_;
1223 FakeLayerScrollClient sibling_scroll_layer_client_;
1224 FakeLayerScrollClient child_scroll_layer_client_;
1226 FakeContentLayerClient fake_content_layer_client_;
1228 bool scroll_destroy_whole_tree_;
1231 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyLayer) {
1232 RunTest(true, false, false);
1235 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) {
1236 scroll_destroy_whole_tree_ = true;
1237 RunTest(true, false, false);
1240 } // namespace
1241 } // namespace cc