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