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