• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
LayerTreeHostScrollTestScrollSimple()30   LayerTreeHostScrollTestScrollSimple()
31       : initial_scroll_(10, 20),
32         second_scroll_(40, 5),
33         scroll_amount_(2, -1),
34         num_scrolls_(0) {}
35 
BeginTest()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 
Layout()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 
DrawLayersOnThread(LayerTreeHostImpl * impl)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 
ApplyViewportDeltas(const gfx::Vector2d & scroll_delta,float scale,float top_controls_delta)89   virtual void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
90                                    float scale,
91                                    float top_controls_delta) OVERRIDE {
92     num_scrolls_++;
93   }
94 
AfterTest()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 
104 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple);
105 
106 class LayerTreeHostScrollTestScrollMultipleRedraw
107     : public LayerTreeHostScrollTest {
108  public:
LayerTreeHostScrollTestScrollMultipleRedraw()109   LayerTreeHostScrollTestScrollMultipleRedraw()
110       : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
111 
BeginTest()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 
BeginCommitOnThread(LayerTreeHostImpl * impl)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 
DrawLayersOnThread(LayerTreeHostImpl * impl)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 
ApplyViewportDeltas(const gfx::Vector2d & scroll_delta,float scale,float top_controls_delta)174   virtual void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
175                                    float scale,
176                                    float top_controls_delta) OVERRIDE {
177     num_scrolls_++;
178   }
179 
AfterTest()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 
189 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw);
190 
191 class LayerTreeHostScrollTestScrollAbortedCommit
192     : public LayerTreeHostScrollTest {
193  public:
LayerTreeHostScrollTestScrollAbortedCommit()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 
BeginTest()206   virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
207 
SetupTree()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 
WillBeginMainFrame()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 
DidBeginMainFrame()271   virtual void DidBeginMainFrame() OVERRIDE { num_did_begin_main_frames_++; }
272 
WillCommit()273   virtual void WillCommit() OVERRIDE { num_will_commits_++; }
274 
DidCommit()275   virtual void DidCommit() OVERRIDE { num_did_commits_++; }
276 
BeginCommitOnThread(LayerTreeHostImpl * impl)277   virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
278     num_impl_commits_++;
279   }
280 
DrawLayersOnThread(LayerTreeHostImpl * impl)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 
ApplyViewportDeltas(const gfx::Vector2d & scroll_delta,float scale,float top_controls_delta)347   virtual void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
348                                    float scale,
349                                    float top_controls_delta) OVERRIDE {
350     num_impl_scrolls_++;
351   }
352 
AfterTest()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 
377 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit);
378 
379 class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest {
380  public:
LayerTreeHostScrollTestFractionalScroll()381   LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
382 
SetupTree()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 
BeginTest()400   virtual void BeginTest() OVERRIDE {
401     PostSetNeedsCommitToMainThread();
402   }
403 
DrawLayersOnThread(LayerTreeHostImpl * impl)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 
AfterTest()436   virtual void AfterTest() OVERRIDE {}
437 
438  private:
439   gfx::Vector2dF scroll_amount_;
440 };
441 
442 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll);
443 
444 class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
445  public:
LayerTreeHostScrollTestCaseWithChild()446   LayerTreeHostScrollTestCaseWithChild()
447       : initial_offset_(10, 20),
448         javascript_scroll_(40, 5),
449         scroll_amount_(2, -1),
450         num_scrolls_(0) {}
451 
SetupTree()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 
BeginTest()505   virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
506 
WillCommit()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 
DidScroll()515   void DidScroll() {
516     final_scroll_offset_ = expected_scroll_layer_->scroll_offset();
517   }
518 
ApplyViewportDeltas(const gfx::Vector2d & scroll_delta,float scale,float top_controls_delta)519   virtual void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
520                                    float scale,
521                                    float top_controls_delta) OVERRIDE {
522     num_scrolls_++;
523   }
524 
Layout()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 
DidActivateTreeOnThread(LayerTreeHostImpl * impl)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 
AfterTest()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 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor1_ScrollChild_DirectRenderer)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 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor1_ScrollChild_DelegatingRenderer)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 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor15_ScrollChild_DirectRenderer)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 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor15_ScrollChild_DelegatingRenderer)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 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor2_ScrollChild_DirectRenderer)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 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor2_ScrollChild_DelegatingRenderer)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 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer)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 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer)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 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer)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 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer)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 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer)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 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer)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:
InitializeSettings(LayerTreeSettings * settings)733   virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
734     settings->impl_side_painting = true;
735   }
736 
DrawLayersOnThread(LayerTreeHostImpl * impl)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:
ImplSidePaintingScrollTestSimple()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 
SetupTree()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 
BeginTest()770   virtual void BeginTest() OVERRIDE {
771     PostSetNeedsCommitToMainThread();
772   }
773 
Layout()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 
CommitCompleteOnThread(LayerTreeHostImpl * impl)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 
DrawLayersOnThread(LayerTreeHostImpl * impl)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 
ApplyViewportDeltas(const gfx::Vector2d & scroll_delta,float scale,float top_controls_delta)853   virtual void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
854                                    float scale,
855                                    float top_controls_delta) OVERRIDE {
856     num_scrolls_++;
857   }
858 
AfterTest()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 
869 MULTI_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.
875 class ImplSidePaintingScrollTestImplOnlyScroll
876     : public ImplSidePaintingScrollTest {
877  public:
ImplSidePaintingScrollTestImplOnlyScroll()878   ImplSidePaintingScrollTestImplOnlyScroll()
879       : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3) {}
880 
SetupTree()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 
BeginTest()899   virtual void BeginTest() OVERRIDE {
900     PostSetNeedsCommitToMainThread();
901   }
902 
WillCommit()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 
BeginCommitOnThread(LayerTreeHostImpl * impl)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 
CommitCompleteOnThread(LayerTreeHostImpl * impl)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 
DrawLayersOnThread(LayerTreeHostImpl * impl)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 
AfterTest()1000   virtual void AfterTest() OVERRIDE {}
1001 
1002  private:
1003   gfx::Vector2d initial_scroll_;
1004   gfx::Vector2d impl_thread_scroll_;
1005 };
1006 
1007 MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll);
1008 
1009 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
1010     : public LayerTreeHostScrollTest {
1011  public:
LayerTreeHostScrollTestScrollZeroMaxScrollOffset()1012   LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
1013 
SetupTree()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 
BeginTest()1020   virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1021 
DrawLayersOnThread(LayerTreeHostImpl * impl)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 
AfterTest()1049   virtual void AfterTest() OVERRIDE {}
1050 };
1051 
1052 SINGLE_AND_MULTI_THREAD_TEST_F(
1053     LayerTreeHostScrollTestScrollZeroMaxScrollOffset);
1054 
1055 class ThreadCheckingInputHandlerClient : public InputHandlerClient {
1056  public:
ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner * runner,bool * received_stop_flinging)1057   ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner* runner,
1058                                    bool* received_stop_flinging)
1059       : task_runner_(runner), received_stop_flinging_(received_stop_flinging) {}
1060 
WillShutdown()1061   virtual void WillShutdown() OVERRIDE {
1062     if (!received_stop_flinging_)
1063       ADD_FAILURE() << "WillShutdown() called before fling stopped";
1064   }
1065 
Animate(base::TimeTicks time)1066   virtual void Animate(base::TimeTicks time) OVERRIDE {
1067     if (!task_runner_->BelongsToCurrentThread())
1068       ADD_FAILURE() << "Animate called on wrong thread";
1069   }
1070 
MainThreadHasStoppedFlinging()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 
DidOverscroll(const gfx::PointF & causal_event_viewport_point,const gfx::Vector2dF & accumulated_overscroll,const gfx::Vector2dF & latest_overscroll_delta)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 
BindInputHandlerOnCompositorThread(const base::WeakPtr<InputHandler> & input_handler,ThreadCheckingInputHandlerClient * client)1090 void BindInputHandlerOnCompositorThread(
1091     const base::WeakPtr<InputHandler>& input_handler,
1092     ThreadCheckingInputHandlerClient* client) {
1093   input_handler->BindToClient(client);
1094 }
1095 
TEST(LayerTreeHostFlingTest,DidStopFlingingThread)1096 TEST(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 
1129 class LayerTreeHostScrollTestLayerStructureChange
1130     : public LayerTreeHostScrollTest {
1131  public:
LayerTreeHostScrollTestLayerStructureChange()1132   LayerTreeHostScrollTestLayerStructureChange()
1133       : scroll_destroy_whole_tree_(false) {}
1134 
SetupTree()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 
BeginTest()1148   virtual void BeginTest() OVERRIDE {
1149     PostSetNeedsCommitToMainThread();
1150   }
1151 
DrawLayersOnThread(LayerTreeHostImpl * impl)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 
AfterTest()1167   virtual void AfterTest() OVERRIDE {}
1168 
DidScroll(Layer * layer)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:
DidScroll()1181     void DidScroll() {
1182       owner_->DidScroll(layer_);
1183     }
1184     LayerTreeHostScrollTestLayerStructureChange* owner_;
1185     Layer* layer_;
1186   };
1187 
CreateScrollLayer(Layer * parent,FakeLayerScrollClient * client)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 
TEST_F(LayerTreeHostScrollTestLayerStructureChange,ScrollDestroyLayer)1214 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyLayer) {
1215   RunTest(true, false, true);
1216 }
1217 
TEST_F(LayerTreeHostScrollTestLayerStructureChange,ScrollDestroyWholeTree)1218 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) {
1219   scroll_destroy_whole_tree_ = true;
1220   RunTest(true, false, true);
1221 }
1222 
1223 }  // namespace
1224 }  // namespace cc
1225