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