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/bind.h"
8 #include "base/location.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/stl_util.h"
12 #include "base/threading/thread_task_runner_handle.h"
13 #include "cc/animation/animation_host.h"
14 #include "cc/base/completion_event.h"
15 #include "cc/input/main_thread_scrolling_reason.h"
16 #include "cc/input/scroll_elasticity_helper.h"
17 #include "cc/input/scroll_input_type.h"
18 #include "cc/layers/layer.h"
19 #include "cc/layers/layer_impl.h"
20 #include "cc/layers/picture_layer.h"
21 #include "cc/test/fake_content_layer_client.h"
22 #include "cc/test/fake_layer_tree_host_client.h"
23 #include "cc/test/fake_picture_layer.h"
24 #include "cc/test/fake_picture_layer_impl.h"
25 #include "cc/test/geometry_test_utils.h"
26 #include "cc/test/layer_tree_test.h"
27 #include "cc/test/test_task_graph_runner.h"
28 #include "cc/test/test_ukm_recorder_factory.h"
29 #include "cc/trees/clip_node.h"
30 #include "cc/trees/effect_node.h"
31 #include "cc/trees/layer_tree_impl.h"
32 #include "cc/trees/scroll_node.h"
33 #include "cc/trees/transform_node.h"
34 #include "components/viz/common/frame_sinks/begin_frame_source.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "ui/gfx/geometry/point_conversions.h"
37 #include "ui/gfx/geometry/size_conversions.h"
38 #include "ui/gfx/geometry/vector2d_conversions.h"
39 
40 using ::testing::Mock;
41 
42 namespace cc {
43 namespace {
44 
BeginState(const gfx::Point & point)45 std::unique_ptr<ScrollState> BeginState(const gfx::Point& point) {
46   ScrollStateData scroll_state_data;
47   scroll_state_data.is_beginning = true;
48   scroll_state_data.position_x = point.x();
49   scroll_state_data.position_y = point.y();
50   std::unique_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data));
51   return scroll_state;
52 }
53 
UpdateState(const gfx::Point & point,const gfx::Vector2dF & delta)54 std::unique_ptr<ScrollState> UpdateState(const gfx::Point& point,
55                                          const gfx::Vector2dF& delta) {
56   ScrollStateData scroll_state_data;
57   scroll_state_data.delta_x = delta.x();
58   scroll_state_data.delta_y = delta.y();
59   scroll_state_data.position_x = point.x();
60   scroll_state_data.position_y = point.y();
61   std::unique_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data));
62   return scroll_state;
63 }
64 
65 class LayerTreeHostScrollTest : public LayerTreeTest, public ScrollCallbacks {
66  protected:
LayerTreeHostScrollTest()67   LayerTreeHostScrollTest() { SetUseLayerLists(); }
68 
SetupTree()69   void SetupTree() override {
70     LayerTreeTest::SetupTree();
71     Layer* root_layer = layer_tree_host()->root_layer();
72 
73     // Create an effective max_scroll_offset of (100, 100).
74     gfx::Size scroll_layer_bounds(root_layer->bounds().width() + 100,
75                                   root_layer->bounds().height() + 100);
76 
77     SetupViewport(root_layer, root_layer->bounds(), scroll_layer_bounds);
78     layer_tree_host()->property_trees()->scroll_tree.SetScrollCallbacks(
79         weak_ptr_factory_.GetWeakPtr());
80   }
81 
82   // ScrollCallbacks
DidScroll(ElementId element_id,const gfx::ScrollOffset & scroll_offset,const base::Optional<TargetSnapAreaElementIds> & snap_target_ids)83   void DidScroll(ElementId element_id,
84                  const gfx::ScrollOffset& scroll_offset,
85                  const base::Optional<TargetSnapAreaElementIds>&
86                      snap_target_ids) override {
87     // Simulates cc client (e.g Blink) behavior when handling impl-side scrolls.
88     SetScrollOffsetFromImplSide(layer_tree_host()->LayerByElementId(element_id),
89                                 scroll_offset);
90 
91     if (element_id ==
92         layer_tree_host()->OuterViewportScrollLayerForTesting()->element_id()) {
93       DidScrollOuterViewport(scroll_offset);
94     }
95     if (snap_target_ids.has_value()) {
96       ScrollNode* scroller_node =
97           layer_tree_host()
98               ->property_trees()
99               ->scroll_tree.FindNodeFromElementId(element_id);
100       scroller_node->snap_container_data.value().SetTargetSnapAreaElementIds(
101           snap_target_ids.value());
102     }
103   }
DidChangeScrollbarsHidden(ElementId,bool)104   void DidChangeScrollbarsHidden(ElementId, bool) override {}
105 
DidScrollOuterViewport(const gfx::ScrollOffset & scroll_offset)106   virtual void DidScrollOuterViewport(const gfx::ScrollOffset& scroll_offset) {
107     num_outer_viewport_scrolls_++;
108   }
109 
110   int num_outer_viewport_scrolls_ = 0;
111 
112  private:
113   base::WeakPtrFactory<LayerTreeHostScrollTest> weak_ptr_factory_{this};
114 };
115 
116 class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest {
117  public:
LayerTreeHostScrollTestScrollSimple()118   LayerTreeHostScrollTestScrollSimple()
119       : initial_scroll_(10, 20), second_scroll_(40, 5), scroll_amount_(2, -1) {}
120 
BeginTest()121   void BeginTest() override {
122     SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(),
123                     initial_scroll_);
124     PostSetNeedsCommitToMainThread();
125   }
126 
UpdateLayerTreeHost()127   void UpdateLayerTreeHost() override {
128     Layer* scroll_layer =
129         layer_tree_host()->OuterViewportScrollLayerForTesting();
130     if (!layer_tree_host()->SourceFrameNumber()) {
131       EXPECT_VECTOR_EQ(initial_scroll_,
132                        GetTransformNode(scroll_layer)->scroll_offset);
133     } else {
134       EXPECT_VECTOR_EQ(
135           gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_),
136           GetTransformNode(scroll_layer)->scroll_offset);
137 
138       // Pretend like Javascript updated the scroll position itself.
139       SetScrollOffset(scroll_layer, second_scroll_);
140     }
141   }
142 
DrawLayersOnThread(LayerTreeHostImpl * impl)143   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
144     LayerImpl* root = impl->active_tree()->root_layer();
145     LayerImpl* scroll_layer =
146         impl->active_tree()->OuterViewportScrollLayerForTesting();
147     EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer));
148 
149     scroll_layer->SetBounds(
150         gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
151     scroll_layer->ScrollBy(scroll_amount_);
152 
153     switch (impl->active_tree()->source_frame_number()) {
154       case 0:
155         EXPECT_VECTOR_EQ(initial_scroll_, ScrollOffsetBase(scroll_layer));
156         EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer));
157         PostSetNeedsCommitToMainThread();
158         break;
159       case 1:
160         EXPECT_VECTOR_EQ(second_scroll_, ScrollOffsetBase(scroll_layer));
161         EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer));
162         EndTest();
163         break;
164     }
165   }
166 
AfterTest()167   void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); }
168 
169  private:
170   gfx::ScrollOffset initial_scroll_;
171   gfx::ScrollOffset second_scroll_;
172   gfx::Vector2dF scroll_amount_;
173 };
174 
175 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple);
176 
177 class LayerTreeHostScrollTestScrollMultipleRedraw
178     : public LayerTreeHostScrollTest {
179  public:
LayerTreeHostScrollTestScrollMultipleRedraw()180   LayerTreeHostScrollTestScrollMultipleRedraw()
181       : initial_scroll_(40, 10), scroll_amount_(-3, 17) {}
182 
BeginTest()183   void BeginTest() override {
184     scroll_layer_ = layer_tree_host()->OuterViewportScrollLayerForTesting();
185     SetScrollOffset(scroll_layer_.get(), initial_scroll_);
186     PostSetNeedsCommitToMainThread();
187   }
188 
BeginCommitOnThread(LayerTreeHostImpl * impl)189   void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
190     switch (layer_tree_host()->SourceFrameNumber()) {
191       case 0:
192         EXPECT_VECTOR_EQ(initial_scroll_,
193                          CurrentScrollOffset(scroll_layer_.get()));
194         break;
195       case 1:
196       case 2:
197         EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(
198                              initial_scroll_, scroll_amount_ + scroll_amount_),
199                          CurrentScrollOffset(scroll_layer_.get()));
200         break;
201     }
202   }
203 
DrawLayersOnThread(LayerTreeHostImpl * impl)204   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
205     LayerImpl* scroll_layer =
206         impl->active_tree()->LayerById(scroll_layer_->id());
207     if (impl->active_tree()->source_frame_number() == 0 &&
208         impl->SourceAnimationFrameNumberForTesting() == 1) {
209       // First draw after first commit.
210       EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer));
211       scroll_layer->ScrollBy(scroll_amount_);
212       EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer));
213 
214       EXPECT_VECTOR_EQ(initial_scroll_, ScrollOffsetBase(scroll_layer));
215       PostSetNeedsRedrawToMainThread();
216     } else if (impl->active_tree()->source_frame_number() == 0 &&
217                impl->SourceAnimationFrameNumberForTesting() == 2) {
218       // Second draw after first commit.
219       EXPECT_VECTOR_EQ(ScrollDelta(scroll_layer), scroll_amount_);
220       scroll_layer->ScrollBy(scroll_amount_);
221       EXPECT_VECTOR_EQ(scroll_amount_ + scroll_amount_,
222                        ScrollDelta(scroll_layer));
223 
224       EXPECT_VECTOR_EQ(initial_scroll_,
225                        CurrentScrollOffset(scroll_layer_.get()));
226       PostSetNeedsCommitToMainThread();
227     } else if (impl->active_tree()->source_frame_number() == 1) {
228       // Third or later draw after second commit.
229       EXPECT_GE(impl->SourceAnimationFrameNumberForTesting(), 3u);
230       EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(
231                            initial_scroll_, scroll_amount_ + scroll_amount_),
232                        CurrentScrollOffset(scroll_layer_.get()));
233       EndTest();
234     }
235   }
236 
AfterTest()237   void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); }
238 
239  private:
240   gfx::ScrollOffset initial_scroll_;
241   gfx::Vector2dF scroll_amount_;
242   scoped_refptr<Layer> scroll_layer_;
243 };
244 
245 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw);
246 
247 class LayerTreeHostScrollTestScrollAbortedCommit
248     : public LayerTreeHostScrollTest {
249  public:
LayerTreeHostScrollTestScrollAbortedCommit()250   LayerTreeHostScrollTestScrollAbortedCommit()
251       : initial_scroll_(50, 60),
252         impl_scroll_(-3, 2),
253         second_main_scroll_(14, -3),
254         impl_scale_(2.f),
255         num_will_begin_main_frames_(0),
256         num_did_begin_main_frames_(0),
257         num_will_commits_(0),
258         num_did_commits_(0),
259         num_impl_commits_(0) {}
260 
BeginTest()261   void BeginTest() override {
262     SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(),
263                     initial_scroll_);
264     PostSetNeedsCommitToMainThread();
265   }
266 
SetupTree()267   void SetupTree() override {
268     LayerTreeHostScrollTest::SetupTree();
269 
270     gfx::Size scroll_layer_bounds(200, 200);
271     layer_tree_host()->OuterViewportScrollLayerForTesting()->SetBounds(
272         scroll_layer_bounds);
273     layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
274   }
275 
WillBeginMainFrame()276   void WillBeginMainFrame() override {
277     num_will_begin_main_frames_++;
278     Layer* root_scroll_layer =
279         layer_tree_host()->OuterViewportScrollLayerForTesting();
280     switch (num_will_begin_main_frames_) {
281       case 1:
282         // This will not be aborted because of the initial prop changes.
283         EXPECT_EQ(0, num_outer_viewport_scrolls_);
284         EXPECT_EQ(0, layer_tree_host()->SourceFrameNumber());
285         EXPECT_VECTOR_EQ(initial_scroll_,
286                          CurrentScrollOffset(root_scroll_layer));
287         EXPECT_EQ(1.f, layer_tree_host()->page_scale_factor());
288         break;
289       case 2:
290         // This commit will be aborted, and another commit will be
291         // initiated from the redraw.
292         EXPECT_EQ(1, num_outer_viewport_scrolls_);
293         EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber());
294         EXPECT_VECTOR_EQ(
295             gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_),
296             CurrentScrollOffset(root_scroll_layer));
297         EXPECT_EQ(impl_scale_, layer_tree_host()->page_scale_factor());
298         PostSetNeedsRedrawToMainThread();
299         break;
300       case 3:
301         // This commit will not be aborted because of the scroll change.
302         EXPECT_EQ(2, num_outer_viewport_scrolls_);
303         // The source frame number still increases even with the abort.
304         EXPECT_EQ(2, layer_tree_host()->SourceFrameNumber());
305         EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(
306                              initial_scroll_, impl_scroll_ + impl_scroll_),
307                          CurrentScrollOffset(root_scroll_layer));
308         EXPECT_EQ(impl_scale_ * impl_scale_,
309                   layer_tree_host()->page_scale_factor());
310         SetScrollOffset(
311             root_scroll_layer,
312             gfx::ScrollOffsetWithDelta(CurrentScrollOffset(root_scroll_layer),
313                                        second_main_scroll_));
314         break;
315       case 4:
316         // This commit will also be aborted.
317         EXPECT_EQ(3, num_outer_viewport_scrolls_);
318         EXPECT_EQ(3, layer_tree_host()->SourceFrameNumber());
319         gfx::Vector2dF delta =
320             impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
321         EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
322                          CurrentScrollOffset(root_scroll_layer));
323 
324         // End the test by drawing to verify this commit is also aborted.
325         PostSetNeedsRedrawToMainThread();
326         break;
327     }
328   }
329 
DidBeginMainFrame()330   void DidBeginMainFrame() override { num_did_begin_main_frames_++; }
331 
WillCommit()332   void WillCommit() override { num_will_commits_++; }
333 
DidCommit()334   void DidCommit() override { num_did_commits_++; }
335 
BeginCommitOnThread(LayerTreeHostImpl * impl)336   void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
337     num_impl_commits_++;
338   }
339 
DrawLayersOnThread(LayerTreeHostImpl * impl)340   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
341     LayerImpl* root_scroll_layer =
342         impl->active_tree()->OuterViewportScrollLayerForTesting();
343 
344     if (impl->active_tree()->source_frame_number() == 0 &&
345         impl->SourceAnimationFrameNumberForTesting() == 1) {
346       // First draw
347       EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(root_scroll_layer));
348       root_scroll_layer->ScrollBy(impl_scroll_);
349       EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer));
350       EXPECT_VECTOR_EQ(initial_scroll_, ScrollOffsetBase(root_scroll_layer));
351 
352       EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
353       EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
354       impl->active_tree()->SetPageScaleOnActiveTree(impl_scale_);
355       EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
356       EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor());
357 
358       // To simplify the testing flow, don't redraw here, just commit.
359       impl->SetNeedsCommit();
360     } else if (impl->active_tree()->source_frame_number() == 0 &&
361                impl->SourceAnimationFrameNumberForTesting() == 2) {
362       // Test a second draw after an aborted commit.
363       // The scroll/scale values should be baked into the offset/scale factor
364       // since the main thread consumed but aborted the begin frame.
365       EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(root_scroll_layer));
366       root_scroll_layer->ScrollBy(impl_scroll_);
367       EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer));
368       EXPECT_VECTOR_EQ(
369           gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_),
370           ScrollOffsetBase(root_scroll_layer));
371 
372       EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
373       EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor());
374       impl->active_tree()->SetPageScaleOnActiveTree(impl_scale_ * impl_scale_);
375       EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
376       EXPECT_EQ(impl_scale_ * impl_scale_,
377                 impl->active_tree()->current_page_scale_factor());
378 
379       impl->SetNeedsCommit();
380     } else if (impl->active_tree()->source_frame_number() == 1) {
381       // Commit for source frame 1 is aborted.
382       NOTREACHED();
383     } else if (impl->active_tree()->source_frame_number() == 2 &&
384                impl->SourceAnimationFrameNumberForTesting() == 3) {
385       // Third draw after the second full commit.
386       EXPECT_EQ(ScrollDelta(root_scroll_layer), gfx::ScrollOffset());
387       root_scroll_layer->ScrollBy(impl_scroll_);
388       impl->SetNeedsCommit();
389       EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer));
390       gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + second_main_scroll_;
391       EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
392                        ScrollOffsetBase(root_scroll_layer));
393     } else if (impl->active_tree()->source_frame_number() == 2 &&
394                impl->SourceAnimationFrameNumberForTesting() == 4) {
395       // Final draw after the second aborted commit.
396       EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(root_scroll_layer));
397       gfx::Vector2dF delta =
398           impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
399       EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
400                        ScrollOffsetBase(root_scroll_layer));
401       EndTest();
402     } else {
403       // Commit for source frame 3 is aborted.
404       NOTREACHED();
405     }
406   }
407 
AfterTest()408   void AfterTest() override {
409     EXPECT_EQ(3, num_outer_viewport_scrolls_);
410     // Verify that the embedder sees aborted commits as real commits.
411     EXPECT_EQ(4, num_will_begin_main_frames_);
412     EXPECT_EQ(4, num_did_begin_main_frames_);
413     EXPECT_EQ(4, num_will_commits_);
414     EXPECT_EQ(4, num_did_commits_);
415     // ...but the compositor thread only sees two real ones.
416     EXPECT_EQ(2, num_impl_commits_);
417   }
418 
419  private:
420   gfx::ScrollOffset initial_scroll_;
421   gfx::Vector2dF impl_scroll_;
422   gfx::Vector2dF second_main_scroll_;
423   float impl_scale_;
424   int num_will_begin_main_frames_;
425   int num_did_begin_main_frames_;
426   int num_will_commits_;
427   int num_did_commits_;
428   int num_impl_commits_;
429 };
430 
431 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit);
432 
433 class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest {
434  public:
LayerTreeHostScrollTestFractionalScroll()435   LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}
436 
SetupTree()437   void SetupTree() override {
438     LayerTreeHostScrollTest::SetupTree();
439     layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
440   }
441 
BeginTest()442   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
443 
DrawLayersOnThread(LayerTreeHostImpl * impl)444   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
445     LayerImpl* scroll_layer =
446         impl->active_tree()->OuterViewportScrollLayerForTesting();
447 
448     // Check that a fractional scroll delta is correctly accumulated over
449     // multiple commits.
450     switch (impl->active_tree()->source_frame_number()) {
451       case 0:
452         EXPECT_VECTOR_EQ(gfx::Vector2d(0, 0), ScrollOffsetBase(scroll_layer));
453         EXPECT_VECTOR_EQ(gfx::Vector2d(0, 0), ScrollDelta(scroll_layer));
454         PostSetNeedsCommitToMainThread();
455         break;
456       case 1:
457         EXPECT_VECTOR_EQ(gfx::ToRoundedVector2d(scroll_amount_),
458                          ScrollOffsetBase(scroll_layer));
459         EXPECT_VECTOR_EQ(
460             scroll_amount_ - gfx::ToRoundedVector2d(scroll_amount_),
461             ScrollDelta(scroll_layer));
462         PostSetNeedsCommitToMainThread();
463         break;
464       case 2:
465         EXPECT_VECTOR_EQ(
466             gfx::ToRoundedVector2d(scroll_amount_ + scroll_amount_),
467             ScrollOffsetBase(scroll_layer));
468         EXPECT_VECTOR_EQ(
469             scroll_amount_ + scroll_amount_ -
470                 gfx::ToRoundedVector2d(scroll_amount_ + scroll_amount_),
471             ScrollDelta(scroll_layer));
472         EndTest();
473         break;
474     }
475     scroll_layer->ScrollBy(scroll_amount_);
476   }
477 
478  private:
479   gfx::Vector2dF scroll_amount_;
480 };
481 
482 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll);
483 
484 class LayerTreeHostScrollTestScrollSnapping : public LayerTreeHostScrollTest {
485  public:
LayerTreeHostScrollTestScrollSnapping()486   LayerTreeHostScrollTestScrollSnapping() : scroll_amount_(1.75, 0) {}
487 
SetupTree()488   void SetupTree() override {
489     LayerTreeHostScrollTest::SetupTree();
490 
491     scoped_refptr<Layer> container = Layer::Create();
492     container->SetBounds(gfx::Size(100, 100));
493     CopyProperties(layer_tree_host()->OuterViewportScrollLayerForTesting(),
494                    container.get());
495     CreateTransformNode(container.get()).post_translation =
496         gfx::Vector2dF(0.25, 0);
497     CreateEffectNode(container.get()).render_surface_reason =
498         RenderSurfaceReason::kTest;
499     layer_tree_host()->root_layer()->AddChild(container);
500 
501     scroll_layer_ = Layer::Create();
502     scroll_layer_->SetBounds(gfx::Size(200, 200));
503     scroll_layer_->SetIsDrawable(true);
504     scroll_layer_->SetElementId(
505         LayerIdToElementIdForTesting(scroll_layer_->id()));
506     CopyProperties(container.get(), scroll_layer_.get());
507     CreateTransformNode(scroll_layer_.get());
508     CreateScrollNode(scroll_layer_.get(), gfx::Size(100, 100));
509     layer_tree_host()->root_layer()->AddChild(scroll_layer_);
510 
511     layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.1f, 100.f);
512   }
513 
BeginTest()514   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
515 
DrawLayersOnThread(LayerTreeHostImpl * impl)516   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
517     LayerImpl* scroll_layer =
518         impl->active_tree()->LayerById(scroll_layer_->id());
519 
520     gfx::Transform translate;
521 
522     // Check that screen space transform of the scrollable layer is correctly
523     // snapped to integers.
524     switch (impl->active_tree()->source_frame_number()) {
525       case 0:
526         EXPECT_EQ(gfx::Transform(),
527                   scroll_layer->draw_properties().screen_space_transform);
528         PostSetNeedsCommitToMainThread();
529         break;
530       case 1:
531         translate.Translate(-2, 0);
532         EXPECT_EQ(translate,
533                   scroll_layer->draw_properties().screen_space_transform);
534         PostSetNeedsCommitToMainThread();
535         break;
536       case 2:
537         translate.Translate(-3, 0);
538         EXPECT_EQ(translate,
539                   scroll_layer->draw_properties().screen_space_transform);
540         EndTest();
541         break;
542     }
543     scroll_layer->ScrollBy(scroll_amount_);
544   }
545 
546  private:
547   scoped_refptr<Layer> scroll_layer_;
548   gfx::Vector2dF scroll_amount_;
549 };
550 
551 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSnapping);
552 
553 class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
554  public:
LayerTreeHostScrollTestCaseWithChild()555   LayerTreeHostScrollTestCaseWithChild()
556       : initial_offset_(10, 20),
557         javascript_scroll_(40, 5),
558         scroll_amount_(2, -1) {}
559 
SetupTree()560   void SetupTree() override {
561     SetInitialDeviceScaleFactor(device_scale_factor_);
562     SetInitialRootBounds(gfx::Size(10, 10));
563     LayerTreeHostScrollTest::SetupTree();
564     Layer* root_layer = layer_tree_host()->root_layer();
565     Layer* root_scroll_layer =
566         layer_tree_host()->OuterViewportScrollLayerForTesting();
567 
568     child_layer_ = Layer::Create();
569     child_layer_->SetElementId(
570         LayerIdToElementIdForTesting(child_layer_->id()));
571     child_layer_->SetBounds(gfx::Size(110, 110));
572 
573     gfx::Vector2dF child_layer_offset;
574     // Adjust the child layer horizontally so that scrolls will never hit it.
575     if (scroll_child_layer_) {
576       // Scrolls on the child layer will happen at 5, 5. If they are treated
577       // like device pixels, and device scale factor is 2, then they will
578       // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
579       child_layer_offset = gfx::Vector2dF(5.f, 5.f);
580     } else {
581       child_layer_offset = gfx::Vector2dF(60.f, 5.f);
582     }
583 
584     child_layer_->SetIsDrawable(true);
585     child_layer_->SetHitTestable(true);
586     child_layer_->SetElementId(
587         LayerIdToElementIdForTesting(child_layer_->id()));
588     child_layer_->SetBounds(root_scroll_layer->bounds());
589     root_layer->AddChild(child_layer_);
590 
591     CopyProperties(root_scroll_layer, child_layer_.get());
592     CreateTransformNode(child_layer_.get()).post_translation =
593         child_layer_offset;
594     CreateScrollNode(child_layer_.get(), root_layer->bounds());
595 
596     if (scroll_child_layer_) {
597       expected_scroll_layer_ = child_layer_.get();
598       expected_no_scroll_layer_ = root_scroll_layer;
599     } else {
600       expected_scroll_layer_ = root_scroll_layer;
601       expected_no_scroll_layer_ = child_layer_.get();
602     }
603 
604     SetScrollOffset(expected_scroll_layer_, initial_offset_);
605   }
606 
BeginTest()607   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
608 
WillCommit()609   void WillCommit() override {
610     // Keep the test committing (otherwise the early out for no update
611     // will stall the test).
612     if (layer_tree_host()->SourceFrameNumber() < 2) {
613       layer_tree_host()->SetNeedsCommit();
614     }
615   }
616 
DidScroll(ElementId element_id,const gfx::ScrollOffset & offset,const base::Optional<TargetSnapAreaElementIds> & snap_target_ids)617   void DidScroll(ElementId element_id,
618                  const gfx::ScrollOffset& offset,
619                  const base::Optional<TargetSnapAreaElementIds>&
620                      snap_target_ids) override {
621     LayerTreeHostScrollTest::DidScroll(element_id, offset, snap_target_ids);
622     if (element_id == expected_scroll_layer_->element_id()) {
623       final_scroll_offset_ = CurrentScrollOffset(expected_scroll_layer_);
624       EXPECT_EQ(offset, final_scroll_offset_);
625       EXPECT_EQ(element_id, expected_scroll_layer_->element_id());
626     } else {
627       EXPECT_TRUE(offset.IsZero());
628     }
629   }
630 
UpdateLayerTreeHost()631   void UpdateLayerTreeHost() override {
632     EXPECT_VECTOR_EQ(gfx::Vector2d(),
633                      CurrentScrollOffset(expected_no_scroll_layer_));
634 
635     switch (layer_tree_host()->SourceFrameNumber()) {
636       case 0:
637         EXPECT_VECTOR_EQ(initial_offset_,
638                          CurrentScrollOffset(expected_scroll_layer_));
639         break;
640       case 1:
641         EXPECT_VECTOR_EQ(
642             gfx::ScrollOffsetWithDelta(initial_offset_, scroll_amount_),
643             CurrentScrollOffset(expected_scroll_layer_));
644 
645         // Pretend like Javascript updated the scroll position itself.
646         SetScrollOffset(expected_scroll_layer_, javascript_scroll_);
647         break;
648       case 2:
649         EXPECT_VECTOR_EQ(
650             gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_),
651             CurrentScrollOffset(expected_scroll_layer_));
652         break;
653     }
654   }
655 
DidActivateTreeOnThread(LayerTreeHostImpl * impl)656   void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
657     LayerImpl* inner_scroll =
658         impl->active_tree()->InnerViewportScrollLayerForTesting();
659     LayerImpl* root_scroll_layer_impl =
660         impl->active_tree()->OuterViewportScrollLayerForTesting();
661     LayerImpl* child_layer_impl =
662         root_scroll_layer_impl->layer_tree_impl()->LayerById(
663             child_layer_->id());
664 
665     LayerImpl* expected_scroll_layer_impl = nullptr;
666     LayerImpl* expected_no_scroll_layer_impl = nullptr;
667     if (scroll_child_layer_) {
668       expected_scroll_layer_impl = child_layer_impl;
669       expected_no_scroll_layer_impl = root_scroll_layer_impl;
670     } else {
671       expected_scroll_layer_impl = root_scroll_layer_impl;
672       expected_no_scroll_layer_impl = child_layer_impl;
673     }
674 
675     EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(inner_scroll));
676     EXPECT_VECTOR_EQ(gfx::Vector2d(),
677                      ScrollDelta(expected_no_scroll_layer_impl));
678 
679     // Ensure device scale factor matches the active tree.
680     EXPECT_EQ(device_scale_factor_, impl->active_tree()->device_scale_factor());
681     switch (impl->active_tree()->source_frame_number()) {
682       case 0: {
683         // GESTURE scroll on impl thread. Also tests that the last scrolled
684         // layer id is stored even after the scrolling ends.
685         gfx::Point scroll_point = gfx::ToCeiledPoint(
686             gfx::PointF(-0.5f, -0.5f) +
687             GetTransformNode(expected_scroll_layer_impl)->post_translation);
688         InputHandler::ScrollStatus status = impl->ScrollBegin(
689             BeginState(scroll_point).get(), ScrollInputType::kTouchscreen);
690         EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
691         impl->ScrollUpdate(UpdateState(gfx::Point(), scroll_amount_).get());
692         auto* scrolling_node = impl->CurrentlyScrollingNode();
693         CHECK(scrolling_node);
694         impl->ScrollEnd();
695         CHECK(!impl->CurrentlyScrollingNode());
696         EXPECT_EQ(scrolling_node->id,
697                   impl->active_tree()->LastScrolledScrollNodeIndex());
698 
699         // Check the scroll is applied as a delta.
700         EXPECT_VECTOR_EQ(initial_offset_,
701                          ScrollOffsetBase(expected_scroll_layer_impl));
702         EXPECT_VECTOR_EQ(scroll_amount_,
703                          ScrollDelta(expected_scroll_layer_impl));
704         break;
705       }
706       case 1: {
707         // WHEEL scroll on impl thread.
708         gfx::Point scroll_point = gfx::ToCeiledPoint(
709             gfx::PointF(0.5f, 0.5f) +
710             GetTransformNode(expected_scroll_layer_impl)->post_translation);
711         InputHandler::ScrollStatus status = impl->ScrollBegin(
712             BeginState(scroll_point).get(), ScrollInputType::kWheel);
713         EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
714         impl->ScrollUpdate(UpdateState(gfx::Point(), scroll_amount_).get());
715         impl->ScrollEnd();
716 
717         // Check the scroll is applied as a delta.
718         EXPECT_VECTOR_EQ(javascript_scroll_,
719                          ScrollOffsetBase(expected_scroll_layer_impl));
720         EXPECT_VECTOR_EQ(scroll_amount_,
721                          ScrollDelta(expected_scroll_layer_impl));
722         break;
723       }
724       case 2:
725 
726         EXPECT_VECTOR_EQ(
727             gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_),
728             ScrollOffsetBase(expected_scroll_layer_impl));
729         EXPECT_VECTOR_EQ(gfx::Vector2d(),
730                          ScrollDelta(expected_scroll_layer_impl));
731 
732         EndTest();
733         break;
734     }
735   }
736 
AfterTest()737   void AfterTest() override {
738     EXPECT_EQ(scroll_child_layer_ ? 0 : 2, num_outer_viewport_scrolls_);
739     EXPECT_VECTOR_EQ(
740         gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_),
741         final_scroll_offset_);
742   }
743 
744  protected:
745   float device_scale_factor_;
746   bool scroll_child_layer_;
747 
748   gfx::ScrollOffset initial_offset_;
749   gfx::ScrollOffset javascript_scroll_;
750   gfx::Vector2d scroll_amount_;
751   gfx::ScrollOffset final_scroll_offset_;
752 
753   scoped_refptr<Layer> child_layer_;
754   Layer* expected_scroll_layer_;
755   Layer* expected_no_scroll_layer_;
756 };
757 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor1_ScrollChild)758 TEST_F(LayerTreeHostScrollTestCaseWithChild, DeviceScaleFactor1_ScrollChild) {
759   device_scale_factor_ = 1.f;
760   scroll_child_layer_ = true;
761   RunTest(CompositorMode::THREADED);
762 }
763 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor15_ScrollChild)764 TEST_F(LayerTreeHostScrollTestCaseWithChild, DeviceScaleFactor15_ScrollChild) {
765   device_scale_factor_ = 1.5f;
766   scroll_child_layer_ = true;
767   RunTest(CompositorMode::THREADED);
768 }
769 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor2_ScrollChild)770 TEST_F(LayerTreeHostScrollTestCaseWithChild, DeviceScaleFactor2_ScrollChild) {
771   device_scale_factor_ = 2.f;
772   scroll_child_layer_ = true;
773   RunTest(CompositorMode::THREADED);
774 }
775 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor1_ScrollRootScrollLayer)776 TEST_F(LayerTreeHostScrollTestCaseWithChild,
777        DeviceScaleFactor1_ScrollRootScrollLayer) {
778   device_scale_factor_ = 1.f;
779   scroll_child_layer_ = false;
780   RunTest(CompositorMode::THREADED);
781 }
782 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor15_ScrollRootScrollLayer)783 TEST_F(LayerTreeHostScrollTestCaseWithChild,
784        DeviceScaleFactor15_ScrollRootScrollLayer) {
785   device_scale_factor_ = 1.5f;
786   scroll_child_layer_ = false;
787   RunTest(CompositorMode::THREADED);
788 }
789 
TEST_F(LayerTreeHostScrollTestCaseWithChild,DeviceScaleFactor2_ScrollRootScrollLayer)790 TEST_F(LayerTreeHostScrollTestCaseWithChild,
791        DeviceScaleFactor2_ScrollRootScrollLayer) {
792   device_scale_factor_ = 2.f;
793   scroll_child_layer_ = false;
794   RunTest(CompositorMode::THREADED);
795 }
796 
797 class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest {
798  public:
LayerTreeHostScrollTestSimple()799   LayerTreeHostScrollTestSimple()
800       : initial_scroll_(10, 20),
801         main_thread_scroll_(40, 5),
802         impl_thread_scroll1_(2, -1),
803         impl_thread_scroll2_(-3, 10) {}
804 
SetupTree()805   void SetupTree() override {
806     LayerTreeHostScrollTest::SetupTree();
807     layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
808   }
809 
BeginTest()810   void BeginTest() override {
811     SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(),
812                     initial_scroll_);
813     PostSetNeedsCommitToMainThread();
814   }
815 
UpdateLayerTreeHost()816   void UpdateLayerTreeHost() override {
817     Layer* scroll_layer =
818         layer_tree_host()->OuterViewportScrollLayerForTesting();
819     if (!layer_tree_host()->SourceFrameNumber()) {
820       EXPECT_VECTOR_EQ(initial_scroll_, CurrentScrollOffset(scroll_layer));
821     } else {
822       EXPECT_VECTOR_EQ(
823           CurrentScrollOffset(scroll_layer),
824           gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll1_));
825 
826       // Pretend like Javascript updated the scroll position itself with a
827       // change of main_thread_scroll.
828       SetScrollOffset(
829           scroll_layer,
830           gfx::ScrollOffsetWithDelta(
831               initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
832     }
833   }
834 
CommitCompleteOnThread(LayerTreeHostImpl * impl)835   void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
836     // We force a second draw here of the first commit before activating
837     // the second commit.
838     if (impl->active_tree()->source_frame_number() == 0)
839       impl->SetNeedsRedraw();
840   }
841 
DrawLayersOnThread(LayerTreeHostImpl * impl)842   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
843     if (impl->pending_tree())
844       impl->SetNeedsRedraw();
845 
846     LayerImpl* root = impl->active_tree()->root_layer();
847     LayerImpl* scroll_layer =
848         impl->active_tree()->OuterViewportScrollLayerForTesting();
849     LayerImpl* pending_root =
850         impl->active_tree()->FindPendingTreeLayerById(root->id());
851 
852     switch (impl->active_tree()->source_frame_number()) {
853       case 0:
854         if (!impl->pending_tree()) {
855           impl->BlockNotifyReadyToActivateForTesting(true);
856           EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer));
857           scroll_layer->ScrollBy(impl_thread_scroll1_);
858 
859           EXPECT_VECTOR_EQ(initial_scroll_, ScrollOffsetBase(scroll_layer));
860           EXPECT_VECTOR_EQ(impl_thread_scroll1_, ScrollDelta(scroll_layer));
861           PostSetNeedsCommitToMainThread();
862 
863           // CommitCompleteOnThread will trigger this function again
864           // and cause us to take the else clause.
865         } else {
866           impl->BlockNotifyReadyToActivateForTesting(false);
867           ASSERT_TRUE(pending_root);
868           EXPECT_EQ(impl->pending_tree()->source_frame_number(), 1);
869 
870           scroll_layer->ScrollBy(impl_thread_scroll2_);
871           EXPECT_VECTOR_EQ(initial_scroll_, ScrollOffsetBase(scroll_layer));
872           EXPECT_VECTOR_EQ(impl_thread_scroll1_ + impl_thread_scroll2_,
873                            ScrollDelta(scroll_layer));
874 
875           LayerImpl* pending_scroll_layer =
876               impl->pending_tree()->OuterViewportScrollLayerForTesting();
877           EXPECT_VECTOR_EQ(
878               gfx::ScrollOffsetWithDelta(
879                   initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_),
880               ScrollOffsetBase(pending_scroll_layer));
881           EXPECT_VECTOR_EQ(impl_thread_scroll2_,
882                            ScrollDelta(pending_scroll_layer));
883         }
884         break;
885       case 1:
886         EXPECT_FALSE(impl->pending_tree());
887         EXPECT_VECTOR_EQ(
888             gfx::ScrollOffsetWithDelta(
889                 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_),
890             ScrollOffsetBase(scroll_layer));
891         EXPECT_VECTOR_EQ(impl_thread_scroll2_, ScrollDelta(scroll_layer));
892         EndTest();
893         break;
894     }
895   }
896 
AfterTest()897   void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); }
898 
899  private:
900   gfx::ScrollOffset initial_scroll_;
901   gfx::Vector2dF main_thread_scroll_;
902   gfx::Vector2dF impl_thread_scroll1_;
903   gfx::Vector2dF impl_thread_scroll2_;
904 };
905 
906 // This tests scrolling on the impl side which is only possible with a thread.
907 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestSimple);
908 
909 // This test makes sure that layers pick up scrolls that occur between
910 // beginning a commit and finishing a commit (aka scroll deltas not
911 // included in sent scroll delta) still apply to layers that don't
912 // push properties.
913 class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest {
914  public:
LayerTreeHostScrollTestImplOnlyScroll()915   LayerTreeHostScrollTestImplOnlyScroll()
916       : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3), impl_scale_(2.f) {}
917 
SetupTree()918   void SetupTree() override {
919     LayerTreeHostScrollTest::SetupTree();
920     layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
921   }
922 
BeginTest()923   void BeginTest() override {
924     SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(),
925                     initial_scroll_);
926     PostSetNeedsCommitToMainThread();
927   }
928 
WillCommit()929   void WillCommit() override {
930     Layer* scroll_layer =
931         layer_tree_host()->OuterViewportScrollLayerForTesting();
932     switch (layer_tree_host()->SourceFrameNumber()) {
933       case 0:
934         EXPECT_TRUE(base::Contains(
935             scroll_layer->layer_tree_host()->LayersThatShouldPushProperties(),
936             scroll_layer));
937         break;
938       case 1:
939         // Even if this layer doesn't need push properties, it should
940         // still pick up scrolls that happen on the active layer during
941         // commit.
942         EXPECT_FALSE(base::Contains(
943             scroll_layer->layer_tree_host()->LayersThatShouldPushProperties(),
944             scroll_layer));
945         break;
946     }
947   }
948 
BeginCommitOnThread(LayerTreeHostImpl * impl)949   void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
950     // Scroll after the 2nd commit has started.
951     if (impl->active_tree()->source_frame_number() == 0) {
952       LayerImpl* active_root = impl->active_tree()->root_layer();
953       LayerImpl* active_scroll_layer =
954           impl->active_tree()->OuterViewportScrollLayerForTesting();
955       ASSERT_TRUE(active_root);
956       ASSERT_TRUE(active_scroll_layer);
957       active_scroll_layer->ScrollBy(impl_thread_scroll_);
958       impl->active_tree()->SetPageScaleOnActiveTree(impl_scale_);
959     }
960   }
961 
CommitCompleteOnThread(LayerTreeHostImpl * impl)962   void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
963     // We force a second draw here of the first commit before activating
964     // the second commit.
965     LayerImpl* active_root = impl->active_tree()->root_layer();
966     LayerImpl* active_scroll_layer =
967         active_root ? impl->active_tree()->OuterViewportScrollLayerForTesting()
968                     : nullptr;
969     LayerImpl* pending_root = impl->pending_tree()->root_layer();
970     LayerImpl* pending_scroll_layer =
971         impl->pending_tree()->OuterViewportScrollLayerForTesting();
972 
973     ASSERT_TRUE(pending_root);
974     ASSERT_TRUE(pending_scroll_layer);
975     switch (impl->pending_tree()->source_frame_number()) {
976       case 0:
977         EXPECT_VECTOR_EQ(initial_scroll_,
978                          ScrollOffsetBase(pending_scroll_layer));
979         EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(pending_scroll_layer));
980         EXPECT_FALSE(active_root);
981         break;
982       case 1:
983         // Even though the scroll happened during the commit, both layers
984         // should have the appropriate scroll delta.
985         EXPECT_VECTOR_EQ(initial_scroll_,
986                          ScrollOffsetBase(pending_scroll_layer));
987         EXPECT_VECTOR_EQ(impl_thread_scroll_,
988                          ScrollDelta(pending_scroll_layer));
989         ASSERT_TRUE(active_root);
990         EXPECT_VECTOR_EQ(initial_scroll_,
991                          ScrollOffsetBase(active_scroll_layer));
992         EXPECT_VECTOR_EQ(impl_thread_scroll_, ScrollDelta(active_scroll_layer));
993         break;
994       case 2:
995         // On the next commit, this delta should have been sent and applied.
996         EXPECT_VECTOR_EQ(
997             gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll_),
998             ScrollOffsetBase(pending_scroll_layer));
999         EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(pending_scroll_layer));
1000         break;
1001     }
1002 
1003     // Ensure that the scroll-offsets on the TransformTree are consistent with
1004     // the synced scroll offsets, for the pending tree.
1005     if (!impl->pending_tree())
1006       return;
1007 
1008     LayerImpl* scroll_layer =
1009         impl->pending_tree()->OuterViewportScrollLayerForTesting();
1010     gfx::ScrollOffset scroll_offset = CurrentScrollOffset(scroll_layer);
1011     int transform_index = scroll_layer->transform_tree_index();
1012     gfx::ScrollOffset transform_tree_scroll_offset =
1013         impl->pending_tree()
1014             ->property_trees()
1015             ->transform_tree.Node(transform_index)
1016             ->scroll_offset;
1017     EXPECT_EQ(scroll_offset, transform_tree_scroll_offset);
1018   }
1019 
DrawLayersOnThread(LayerTreeHostImpl * impl)1020   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1021     if (impl->pending_tree())
1022       impl->SetNeedsRedraw();
1023 
1024     LayerImpl* scroll_layer =
1025         impl->active_tree()->OuterViewportScrollLayerForTesting();
1026 
1027     switch (impl->active_tree()->source_frame_number()) {
1028       case 0:
1029         EXPECT_VECTOR_EQ(initial_scroll_, ScrollOffsetBase(scroll_layer));
1030         EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer));
1031         EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
1032         EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1033         PostSetNeedsCommitToMainThread();
1034         break;
1035       case 1:
1036         EXPECT_VECTOR_EQ(initial_scroll_, ScrollOffsetBase(scroll_layer));
1037         EXPECT_VECTOR_EQ(impl_thread_scroll_, ScrollDelta(scroll_layer));
1038         EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
1039         EXPECT_EQ(impl_scale_,
1040                   impl->active_tree()->current_page_scale_factor());
1041         PostSetNeedsCommitToMainThread();
1042         break;
1043       case 2:
1044         EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
1045         EXPECT_EQ(impl_scale_,
1046                   impl->active_tree()->current_page_scale_factor());
1047         EndTest();
1048         break;
1049     }
1050   }
1051 
1052  private:
1053   gfx::ScrollOffset initial_scroll_;
1054   gfx::Vector2dF impl_thread_scroll_;
1055   float impl_scale_;
1056 };
1057 
1058 // This tests scrolling on the impl side which is only possible with a thread.
1059 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplOnlyScroll);
1060 
DoGestureScroll(LayerTreeHostImpl * host_impl,const scoped_refptr<Layer> & scroller,gfx::Vector2dF offset)1061 void DoGestureScroll(LayerTreeHostImpl* host_impl,
1062                      const scoped_refptr<Layer>& scroller,
1063                      gfx::Vector2dF offset) {
1064   ScrollStateData begin_scroll_state_data;
1065   begin_scroll_state_data.set_current_native_scrolling_element(
1066       scroller->element_id());
1067   begin_scroll_state_data.delta_x_hint = offset.x();
1068   begin_scroll_state_data.delta_y_hint = offset.y();
1069   std::unique_ptr<ScrollState> begin_scroll_state(
1070       new ScrollState(begin_scroll_state_data));
1071   auto scroll_status = host_impl->ScrollBegin(begin_scroll_state.get(),
1072                                               ScrollInputType::kTouchscreen);
1073   EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, scroll_status.thread);
1074   auto* scrolling_node = host_impl->CurrentlyScrollingNode();
1075   EXPECT_TRUE(scrolling_node);
1076   EXPECT_EQ(scrolling_node->element_id, scroller->element_id());
1077 
1078   ScrollStateData update_scroll_state_data;
1079   update_scroll_state_data.delta_x = offset.x();
1080   update_scroll_state_data.delta_y = offset.y();
1081   std::unique_ptr<ScrollState> update_scroll_state(
1082       new ScrollState(update_scroll_state_data));
1083   host_impl->ScrollUpdate(update_scroll_state.get());
1084 
1085   host_impl->ScrollEnd(true /* should_snap */);
1086 }
1087 
1088 // This test simulates scrolling on the impl thread such that snapping occurs
1089 // and ensures that the target snap area element ids are sent back to the main
1090 // thread.
1091 class LayerTreeHostScrollTestImplOnlyScrollSnap
1092     : public LayerTreeHostScrollTest {
1093  public:
LayerTreeHostScrollTestImplOnlyScrollSnap()1094   LayerTreeHostScrollTestImplOnlyScrollSnap()
1095       : initial_scroll_(100, 100),
1096         impl_thread_scroll_(350, 350),
1097         snap_area_id_(ElementId(10)) {}
1098 
SetupTree()1099   void SetupTree() override {
1100     LayerTreeHostScrollTest::SetupTree();
1101 
1102     Layer* root = layer_tree_host()->root_layer();
1103     container_ = Layer::Create();
1104     scroller_ = Layer::Create();
1105     scroller_->SetElementId(LayerIdToElementIdForTesting(scroller_->id()));
1106 
1107     container_->SetBounds(gfx::Size(100, 100));
1108     CopyProperties(root, container_.get());
1109     root->AddChild(container_);
1110 
1111     scroller_->SetBounds(gfx::Size(1000, 1000));
1112     CopyProperties(container_.get(), scroller_.get());
1113     CreateTransformNode(scroller_.get());
1114 
1115     // Set up a snap area.
1116     snap_area_ = Layer::Create();
1117     snap_area_->SetBounds(gfx::Size(50, 50));
1118     snap_area_->SetPosition(gfx::PointF(500, 500));
1119     CopyProperties(scroller_.get(), snap_area_.get());
1120     scroller_->AddChild(snap_area_);
1121     SnapAreaData snap_area_data(ScrollSnapAlign(SnapAlignment::kStart),
1122                                 gfx::RectF(500, 500, 100, 100), false,
1123                                 snap_area_id_);
1124 
1125     // Set up snap container data.
1126     SnapContainerData snap_container_data(
1127         ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
1128         gfx::RectF(0, 0, 100, 100), gfx::ScrollOffset(900, 900));
1129     snap_container_data.AddSnapAreaData(snap_area_data);
1130     CreateScrollNode(scroller_.get(), container_->bounds())
1131         .snap_container_data = snap_container_data;
1132 
1133     root->AddChild(scroller_);
1134   }
1135 
BeginTest()1136   void BeginTest() override {
1137     SetScrollOffset(scroller_.get(), initial_scroll_);
1138     PostSetNeedsCommitToMainThread();
1139   }
1140 
1141   // The animations states are updated before this call.
WillSendBeginMainFrameOnThread(LayerTreeHostImpl * host_impl)1142   void WillSendBeginMainFrameOnThread(LayerTreeHostImpl* host_impl) override {
1143     if (host_impl->active_tree()->source_frame_number() < 0)
1144       return;
1145 
1146     // Perform a scroll such that a snap target is found. This will get pushed
1147     // to the main thread on the next BeginMainFrame.
1148     if (host_impl->active_tree()->source_frame_number() == 0) {
1149       LayerImpl* scroller_impl =
1150           host_impl->active_tree()->LayerById(scroller_->id());
1151 
1152       DoGestureScroll(host_impl, scroller_, impl_thread_scroll_);
1153 
1154       EXPECT_TRUE(host_impl->IsAnimatingForSnap());
1155       EXPECT_VECTOR_EQ(impl_thread_scroll_, ScrollDelta(scroller_impl));
1156     } else {
1157       snap_animation_finished_ = !host_impl->IsAnimatingForSnap();
1158     }
1159   }
1160 
UpdateLayerTreeHost()1161   void UpdateLayerTreeHost() override {
1162     ScrollNode* scroller_node =
1163         layer_tree_host()->property_trees()->scroll_tree.Node(
1164             scroller_->scroll_tree_index());
1165     auto snap_target_ids = scroller_node->snap_container_data.value()
1166                                .GetTargetSnapAreaElementIds();
1167     if (layer_tree_host()->SourceFrameNumber() == 0) {
1168       // On the first BeginMainFrame scrolling has not happened yet.
1169       // Check that the scroll offset and scroll snap targets are at the initial
1170       // values on the main thread.
1171       EXPECT_VECTOR_EQ(initial_scroll_, CurrentScrollOffset(scroller_.get()));
1172     }
1173     if (snap_animation_finished_) {
1174       // After a snap target is set on the impl thread, the snap targets should
1175       // be pushed to the main thread.
1176       EXPECT_EQ(snap_target_ids,
1177                 TargetSnapAreaElementIds(snap_area_id_, snap_area_id_));
1178       EndTest();
1179     } else {
1180       EXPECT_EQ(snap_target_ids, TargetSnapAreaElementIds());
1181     }
1182   }
1183 
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)1184   void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1185     PostSetNeedsCommitToMainThread();
1186   }
1187 
1188  private:
1189   scoped_refptr<Layer> container_;
1190   scoped_refptr<Layer> scroller_;
1191   scoped_refptr<Layer> snap_area_;
1192 
1193   gfx::ScrollOffset initial_scroll_;
1194   gfx::Vector2dF impl_thread_scroll_;
1195 
1196   ElementId snap_area_id_;
1197 
1198   bool snap_animation_finished_ = false;
1199 };
1200 
1201 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplOnlyScrollSnap);
1202 
1203 // This test simulates scrolling on the impl thread such that 2 impl-only
1204 // scrolls occur between main frames. It ensures that the snap target ids will
1205 // be synced from impl to main for both snapped scrolling nodes.
1206 class LayerTreeHostScrollTestImplOnlyMultipleScrollSnap
1207     : public LayerTreeHostScrollTest {
1208  public:
LayerTreeHostScrollTestImplOnlyMultipleScrollSnap()1209   LayerTreeHostScrollTestImplOnlyMultipleScrollSnap()
1210       : initial_scroll_(100, 100),
1211         // Scroll to the boundary so that an animation is not created when
1212         // snapping to allow 2 scrolls between main frames.
1213         impl_thread_scroll_a_(400, 400),
1214         impl_thread_scroll_b_(400, 400),
1215         snap_area_a_id_(ElementId(10)),
1216         snap_area_b_id_(ElementId(20)) {}
1217 
SetupTree()1218   void SetupTree() override {
1219     LayerTreeHostScrollTest::SetupTree();
1220 
1221     Layer* root = layer_tree_host()->root_layer();
1222     container_ = Layer::Create();
1223     scroller_a_ = Layer::Create();
1224     scroller_b_ = Layer::Create();
1225     scroller_a_->SetElementId(LayerIdToElementIdForTesting(scroller_a_->id()));
1226     scroller_b_->SetElementId(LayerIdToElementIdForTesting(scroller_b_->id()));
1227 
1228     container_->SetBounds(gfx::Size(100, 100));
1229     CopyProperties(root, container_.get());
1230     root->AddChild(container_);
1231 
1232     scroller_a_->SetBounds(gfx::Size(1000, 1000));
1233     CopyProperties(container_.get(), scroller_a_.get());
1234     CreateTransformNode(scroller_a_.get());
1235     scroller_b_->SetBounds(gfx::Size(1000, 1000));
1236     CopyProperties(container_.get(), scroller_b_.get());
1237     CreateTransformNode(scroller_b_.get());
1238 
1239     // Set up snap areas.
1240     snap_area_a_ = Layer::Create();
1241     snap_area_a_->SetBounds(gfx::Size(50, 50));
1242     snap_area_a_->SetPosition(gfx::PointF(500, 500));
1243     CopyProperties(scroller_a_.get(), snap_area_a_.get());
1244     scroller_a_->AddChild(snap_area_a_);
1245     SnapAreaData snap_area_data_a(ScrollSnapAlign(SnapAlignment::kStart),
1246                                   gfx::RectF(500, 500, 100, 100), false,
1247                                   snap_area_a_id_);
1248 
1249     snap_area_b_ = Layer::Create();
1250     snap_area_b_->SetBounds(gfx::Size(50, 50));
1251     snap_area_b_->SetPosition(gfx::PointF(500, 500));
1252     CopyProperties(scroller_b_.get(), snap_area_b_.get());
1253     scroller_b_->AddChild(snap_area_b_);
1254     SnapAreaData snap_area_data_b(ScrollSnapAlign(SnapAlignment::kStart),
1255                                   gfx::RectF(500, 500, 100, 100), false,
1256                                   snap_area_b_id_);
1257 
1258     // Set up snap container data.
1259     SnapContainerData snap_container_data_a(
1260         ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
1261         gfx::RectF(0, 0, 100, 100), gfx::ScrollOffset(900, 900));
1262     snap_container_data_a.AddSnapAreaData(snap_area_data_a);
1263     CreateScrollNode(scroller_a_.get(), container_->bounds())
1264         .snap_container_data = snap_container_data_a;
1265 
1266     // Set up snap container data.
1267     SnapContainerData snap_container_data_b(
1268         ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
1269         gfx::RectF(0, 0, 100, 100), gfx::ScrollOffset(900, 900));
1270     snap_container_data_b.AddSnapAreaData(snap_area_data_b);
1271     CreateScrollNode(scroller_b_.get(), container_->bounds())
1272         .snap_container_data = snap_container_data_b;
1273 
1274     root->AddChild(scroller_a_);
1275     root->AddChild(scroller_b_);
1276   }
1277 
BeginTest()1278   void BeginTest() override {
1279     SetScrollOffset(scroller_a_.get(), initial_scroll_);
1280     SetScrollOffset(scroller_b_.get(), initial_scroll_);
1281     PostSetNeedsCommitToMainThread();
1282   }
1283 
UpdateLayerTreeHost()1284   void UpdateLayerTreeHost() override {
1285     ScrollNode* scroller_node_a =
1286         layer_tree_host()->property_trees()->scroll_tree.Node(
1287             scroller_a_->scroll_tree_index());
1288     ScrollNode* scroller_node_b =
1289         layer_tree_host()->property_trees()->scroll_tree.Node(
1290             scroller_b_->scroll_tree_index());
1291     auto snap_target_ids_a = scroller_node_a->snap_container_data.value()
1292                                  .GetTargetSnapAreaElementIds();
1293     auto snap_target_ids_b = scroller_node_b->snap_container_data.value()
1294                                  .GetTargetSnapAreaElementIds();
1295     if (layer_tree_host()->SourceFrameNumber() == 0) {
1296       // On the first BeginMainFrame scrolling has not happened yet.
1297       // Check that the scroll offset and scroll snap targets are at the initial
1298       // values on the main thread.
1299       EXPECT_EQ(snap_target_ids_a, TargetSnapAreaElementIds());
1300       EXPECT_EQ(snap_target_ids_b, TargetSnapAreaElementIds());
1301       EXPECT_VECTOR_EQ(initial_scroll_, CurrentScrollOffset(scroller_a_.get()));
1302       EXPECT_VECTOR_EQ(initial_scroll_, CurrentScrollOffset(scroller_b_.get()));
1303     } else {
1304       // When scrolling happens on the impl thread, the snap targets of the
1305       // scrolled layers should be pushed to the main thread.
1306       EXPECT_EQ(snap_target_ids_a,
1307                 TargetSnapAreaElementIds(snap_area_a_id_, snap_area_a_id_));
1308       EXPECT_EQ(snap_target_ids_b,
1309                 TargetSnapAreaElementIds(snap_area_b_id_, snap_area_b_id_));
1310       EndTest();
1311     }
1312   }
1313 
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)1314   void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1315     // Perform scrolls such that a snap target is found. These will get pushed
1316     // to the main thread on the next BeginMainFrame.
1317     if (host_impl->active_tree()->source_frame_number() == 0) {
1318       LayerImpl* scroller_impl_a =
1319           host_impl->active_tree()->LayerById(scroller_a_->id());
1320       LayerImpl* scroller_impl_b =
1321           host_impl->active_tree()->LayerById(scroller_b_->id());
1322 
1323       DoGestureScroll(host_impl, scroller_a_, impl_thread_scroll_a_);
1324       DoGestureScroll(host_impl, scroller_b_, impl_thread_scroll_b_);
1325 
1326       EXPECT_VECTOR_EQ(impl_thread_scroll_a_, ScrollDelta(scroller_impl_a));
1327       EXPECT_VECTOR_EQ(impl_thread_scroll_b_, ScrollDelta(scroller_impl_b));
1328     }
1329     PostSetNeedsCommitToMainThread();
1330   }
1331 
1332  private:
1333   scoped_refptr<Layer> container_;
1334   scoped_refptr<Layer> scroller_a_;
1335   scoped_refptr<Layer> scroller_b_;
1336   scoped_refptr<Layer> snap_area_a_;
1337   scoped_refptr<Layer> snap_area_b_;
1338 
1339   gfx::ScrollOffset initial_scroll_;
1340   gfx::Vector2dF impl_thread_scroll_a_;
1341   gfx::Vector2dF impl_thread_scroll_b_;
1342 
1343   ElementId snap_area_a_id_;
1344   ElementId snap_area_b_id_;
1345 };
1346 
1347 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplOnlyMultipleScrollSnap);
1348 
1349 class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
1350     : public LayerTreeHostScrollTest {
1351  public:
1352   LayerTreeHostScrollTestScrollZeroMaxScrollOffset() = default;
1353 
SetupTree()1354   void SetupTree() override {
1355     LayerTreeHostScrollTest::SetupTree();
1356 
1357     // Add a sub-scroller to test TryScroll against. The outer viewport scroll
1358     // will be latched to for scrolling even if it doesn't have any scroll
1359     // extent in the given direction to support overscroll actions.
1360     scroller_ = Layer::Create();
1361     scroller_->SetIsDrawable(true);
1362     scroller_->SetHitTestable(true);
1363     scroller_->SetElementId(LayerIdToElementIdForTesting(scroller_->id()));
1364     CopyProperties(layer_tree_host()->OuterViewportScrollLayerForTesting(),
1365                    scroller_.get());
1366     CreateTransformNode(scroller_.get());
1367     CreateScrollNode(scroller_.get(),
1368                      layer_tree_host()->root_layer()->bounds());
1369     layer_tree_host()->root_layer()->AddChild(scroller_.get());
1370   }
1371 
BeginTest()1372   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1373 
UpdateLayerTreeHost()1374   void UpdateLayerTreeHost() override {
1375     ScrollTree& scroll_tree = layer_tree_host()->property_trees()->scroll_tree;
1376     ScrollNode* scroll_node = scroll_tree.Node(scroller_->scroll_tree_index());
1377     switch (layer_tree_host()->SourceFrameNumber()) {
1378       case 0:
1379         // Set max_scroll_offset = (100, 100).
1380         scroll_node->bounds = scroll_node->container_bounds;
1381         scroll_node->bounds.Enlarge(100, 100);
1382         break;
1383       case 1:
1384         // Set max_scroll_offset = (0, 0).
1385         scroll_node->bounds = scroll_node->container_bounds;
1386         break;
1387       case 2:
1388         // Set max_scroll_offset = (-1, -1).
1389         scroll_node->bounds = gfx::Size();
1390         break;
1391     }
1392   }
1393 
DrawLayersOnThread(LayerTreeHostImpl * impl)1394   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1395     ScrollTree& scroll_tree =
1396         impl->active_tree()->property_trees()->scroll_tree;
1397     ScrollNode* scroll_node = scroll_tree.Node(scroller_->scroll_tree_index());
1398     InputHandler::ScrollStatus status =
1399         impl->TryScroll(scroll_tree, scroll_node);
1400     switch (impl->active_tree()->source_frame_number()) {
1401       case 0:
1402         EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread)
1403             << "In Frame 0";
1404         EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
1405                   status.main_thread_scrolling_reasons)
1406             << "In Frame 0";
1407         PostSetNeedsCommitToMainThread();
1408         break;
1409       case 1:
1410         EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread) << "In Frame 1";
1411         EXPECT_EQ(MainThreadScrollingReason::kNotScrollable,
1412                   status.main_thread_scrolling_reasons)
1413             << "In Frame 1";
1414         PostSetNeedsCommitToMainThread();
1415         break;
1416       case 2:
1417         EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread) << "In Frame 2";
1418         EXPECT_EQ(MainThreadScrollingReason::kNotScrollable,
1419                   status.main_thread_scrolling_reasons)
1420             << "In Frame 2";
1421         EndTest();
1422         break;
1423     }
1424   }
1425 
1426  private:
1427   scoped_refptr<Layer> scroller_;
1428 };
1429 
1430 SINGLE_AND_MULTI_THREAD_TEST_F(
1431     LayerTreeHostScrollTestScrollZeroMaxScrollOffset);
1432 
1433 class LayerTreeHostScrollTestScrollNonDrawnLayer
1434     : public LayerTreeHostScrollTest {
1435  public:
1436   LayerTreeHostScrollTestScrollNonDrawnLayer() = default;
1437 
BeginTest()1438   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1439 
SetupTree()1440   void SetupTree() override {
1441     LayerTreeHostScrollTest::SetupTree();
1442     layer_tree_host()->OuterViewportScrollLayerForTesting()->SetIsDrawable(
1443         false);
1444     SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(),
1445                     gfx::ScrollOffset(20.f, 20.f));
1446     layer_tree_host()
1447         ->OuterViewportScrollLayerForTesting()
1448         ->SetNonFastScrollableRegion(gfx::Rect(20, 20, 20, 20));
1449   }
1450 
DrawLayersOnThread(LayerTreeHostImpl * impl)1451   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1452     // Verify that the scroll layer's scroll offset is taken into account when
1453     // checking whether the screen space point is inside the non-fast
1454     // scrollable region.
1455     InputHandler::ScrollStatus status = impl->ScrollBegin(
1456         BeginState(gfx::Point(0, 0)).get(), ScrollInputType::kTouchscreen);
1457     EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
1458     EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
1459               status.main_thread_scrolling_reasons);
1460 
1461     status = impl->ScrollBegin(BeginState(gfx::Point(21, 21)).get(),
1462                                ScrollInputType::kTouchscreen);
1463     EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
1464     EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
1465               status.main_thread_scrolling_reasons);
1466 
1467     EndTest();
1468   }
1469 };
1470 
1471 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollNonDrawnLayer);
1472 
1473 class LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent
1474     : public LayerTreeHostScrollTest {
1475  public:
LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent()1476   LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent() {
1477     SetUseLayerLists();
1478   }
1479 
BeginTest()1480   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1481 
SetupTree()1482   void SetupTree() override {
1483     LayerTreeHostScrollTest::SetupTree();
1484     GetScrollNode(layer_tree_host()->InnerViewportScrollLayerForTesting())
1485         ->main_thread_scrolling_reasons =
1486         MainThreadScrollingReason::kScrollbarScrolling;
1487   }
1488 
DrawLayersOnThread(LayerTreeHostImpl * impl)1489   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1490     LayerImpl* inner_scroll_layer =
1491         impl->active_tree()->InnerViewportScrollLayerForTesting();
1492     LayerImpl* outer_scroll_layer =
1493         impl->active_tree()->OuterViewportScrollLayerForTesting();
1494 
1495     ScrollTree& scroll_tree =
1496         impl->active_tree()->property_trees()->scroll_tree;
1497     ScrollNode* inner_scroll_node =
1498         scroll_tree.Node(inner_scroll_layer->scroll_tree_index());
1499     ScrollNode* outer_scroll_node =
1500         scroll_tree.Node(outer_scroll_layer->scroll_tree_index());
1501 
1502     InputHandler::ScrollStatus status =
1503         impl->TryScroll(scroll_tree, inner_scroll_node);
1504     EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
1505     EXPECT_EQ(MainThreadScrollingReason::kScrollbarScrolling,
1506               status.main_thread_scrolling_reasons);
1507 
1508     status = impl->TryScroll(scroll_tree, outer_scroll_node);
1509     EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
1510     EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
1511               status.main_thread_scrolling_reasons);
1512     EndTest();
1513   }
1514 };
1515 
1516 SINGLE_AND_MULTI_THREAD_TEST_F(
1517     LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent);
1518 
1519 class ThreadCheckingInputHandlerClient : public InputHandlerClient {
1520  public:
ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner * runner,bool * received_stop_flinging)1521   ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner* runner,
1522                                    bool* received_stop_flinging)
1523       : task_runner_(runner), received_stop_flinging_(received_stop_flinging) {}
1524 
WillShutdown()1525   void WillShutdown() override {
1526     if (!received_stop_flinging_)
1527       ADD_FAILURE() << "WillShutdown() called before fling stopped";
1528   }
1529 
Animate(base::TimeTicks time)1530   void Animate(base::TimeTicks time) override {
1531     if (!task_runner_->BelongsToCurrentThread())
1532       ADD_FAILURE() << "Animate called on wrong thread";
1533   }
1534 
ReconcileElasticOverscrollAndRootScroll()1535   void ReconcileElasticOverscrollAndRootScroll() override {
1536     if (!task_runner_->BelongsToCurrentThread()) {
1537       ADD_FAILURE() << "ReconcileElasticOverscrollAndRootScroll called on "
1538                     << "wrong thread";
1539     }
1540   }
1541 
UpdateRootLayerStateForSynchronousInputHandler(const gfx::ScrollOffset & total_scroll_offset,const gfx::ScrollOffset & max_scroll_offset,const gfx::SizeF & scrollable_size,float page_scale_factor,float min_page_scale_factor,float max_page_scale_factor)1542   void UpdateRootLayerStateForSynchronousInputHandler(
1543       const gfx::ScrollOffset& total_scroll_offset,
1544       const gfx::ScrollOffset& max_scroll_offset,
1545       const gfx::SizeF& scrollable_size,
1546       float page_scale_factor,
1547       float min_page_scale_factor,
1548       float max_page_scale_factor) override {
1549     if (!task_runner_->BelongsToCurrentThread()) {
1550       ADD_FAILURE() << "UpdateRootLayerStateForSynchronousInputHandler called "
1551                     << " on wrong thread";
1552     }
1553   }
1554 
DeliverInputForBeginFrame(const viz::BeginFrameArgs & args)1555   void DeliverInputForBeginFrame(const viz::BeginFrameArgs& args) override {
1556     if (!task_runner_->BelongsToCurrentThread()) {
1557       ADD_FAILURE() << "DeliverInputForBeginFrame called on wrong thread";
1558     }
1559   }
1560 
DeliverInputForHighLatencyMode()1561   void DeliverInputForHighLatencyMode() override {
1562     if (!task_runner_->BelongsToCurrentThread()) {
1563       ADD_FAILURE() << "DeliverInputForHighLatencyMode called on wrong thread";
1564     }
1565   }
1566 
1567  private:
1568   base::SingleThreadTaskRunner* task_runner_;
1569   bool* received_stop_flinging_;
1570 };
1571 
1572 class LayerTreeHostScrollTestLayerStructureChange
1573     : public LayerTreeHostScrollTest {
1574  public:
LayerTreeHostScrollTestLayerStructureChange()1575   LayerTreeHostScrollTestLayerStructureChange()
1576       : scroll_destroy_whole_tree_(false) {}
1577 
SetupTree()1578   void SetupTree() override {
1579     LayerTreeHostScrollTest::SetupTree();
1580     Layer* root_layer = layer_tree_host()->root_layer();
1581     Layer* outer_scroll_layer =
1582         layer_tree_host()->OuterViewportScrollLayerForTesting();
1583 
1584     Layer* root_scroll_layer = CreateScrollLayer(outer_scroll_layer);
1585     Layer* sibling_scroll_layer = CreateScrollLayer(outer_scroll_layer);
1586     Layer* child_scroll_layer = CreateScrollLayer(root_scroll_layer);
1587     root_scroll_layer_id_ = root_scroll_layer->id();
1588     sibling_scroll_layer_id_ = sibling_scroll_layer->id();
1589     child_scroll_layer_id_ = child_scroll_layer->id();
1590     fake_content_layer_client_.set_bounds(root_layer->bounds());
1591   }
1592 
BeginTest()1593   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1594 
DrawLayersOnThread(LayerTreeHostImpl * impl)1595   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1596     switch (impl->active_tree()->source_frame_number()) {
1597       case 0:
1598         SetScrollOffsetDelta(
1599             impl->active_tree()->LayerById(root_scroll_layer_id_),
1600             gfx::Vector2dF(5, 5));
1601         SetScrollOffsetDelta(
1602             impl->active_tree()->LayerById(child_scroll_layer_id_),
1603             gfx::Vector2dF(5, 5));
1604         SetScrollOffsetDelta(
1605             impl->active_tree()->LayerById(sibling_scroll_layer_id_),
1606             gfx::Vector2dF(5, 5));
1607         PostSetNeedsCommitToMainThread();
1608         break;
1609       case 1:
1610         EndTest();
1611         break;
1612     }
1613   }
1614 
DidScroll(ElementId element_id,const gfx::ScrollOffset &,const base::Optional<TargetSnapAreaElementIds> &)1615   void DidScroll(ElementId element_id,
1616                  const gfx::ScrollOffset&,
1617                  const base::Optional<TargetSnapAreaElementIds>&) override {
1618     if (scroll_destroy_whole_tree_) {
1619       layer_tree_host()->SetRootLayer(nullptr);
1620       layer_tree_host()->property_trees()->clear();
1621       layer_tree_host()->RegisterViewportPropertyIds(
1622           LayerTreeHost::ViewportPropertyIds());
1623       EndTest();
1624       return;
1625     }
1626     layer_tree_host()->LayerByElementId(element_id)->RemoveFromParent();
1627   }
1628 
1629  protected:
CreateScrollLayer(Layer * parent)1630   Layer* CreateScrollLayer(Layer* parent) {
1631     scoped_refptr<PictureLayer> scroll_layer =
1632         PictureLayer::Create(&fake_content_layer_client_);
1633     scroll_layer->SetIsDrawable(true);
1634     scroll_layer->SetHitTestable(true);
1635     scroll_layer->SetElementId(
1636         LayerIdToElementIdForTesting(scroll_layer->id()));
1637     scroll_layer->SetBounds(gfx::Size(parent->bounds().width() + 100,
1638                                       parent->bounds().height() + 100));
1639 
1640     CopyProperties(parent, scroll_layer.get());
1641     CreateTransformNode(scroll_layer.get());
1642     CreateScrollNode(scroll_layer.get(), parent->bounds());
1643     layer_tree_host()->root_layer()->AddChild(scroll_layer);
1644 
1645     return scroll_layer.get();
1646   }
1647 
SetScrollOffsetDelta(LayerImpl * layer_impl,const gfx::Vector2dF & delta)1648   static void SetScrollOffsetDelta(LayerImpl* layer_impl,
1649                                    const gfx::Vector2dF& delta) {
1650     if (layer_impl->layer_tree_impl()
1651             ->property_trees()
1652             ->scroll_tree.SetScrollOffsetDeltaForTesting(
1653                 layer_impl->element_id(), delta))
1654       layer_impl->layer_tree_impl()->DidUpdateScrollOffset(
1655           layer_impl->element_id());
1656   }
1657 
1658   int root_scroll_layer_id_;
1659   int sibling_scroll_layer_id_;
1660   int child_scroll_layer_id_;
1661 
1662   FakeContentLayerClient fake_content_layer_client_;
1663 
1664   bool scroll_destroy_whole_tree_;
1665 };
1666 
TEST_F(LayerTreeHostScrollTestLayerStructureChange,ScrollDestroyLayer)1667 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyLayer) {
1668   RunTest(CompositorMode::THREADED);
1669 }
1670 
TEST_F(LayerTreeHostScrollTestLayerStructureChange,ScrollDestroyWholeTree)1671 TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) {
1672   scroll_destroy_whole_tree_ = true;
1673   RunTest(CompositorMode::THREADED);
1674 }
1675 
1676 class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest {
1677  public:
LayerTreeHostScrollTestScrollMFBA()1678   LayerTreeHostScrollTestScrollMFBA()
1679       : initial_scroll_(10, 20),
1680         second_scroll_(40, 5),
1681         third_scroll_(20, 10),
1682         scroll_amount_(2, -1),
1683         num_commits_(0) {}
1684 
InitializeSettings(LayerTreeSettings * settings)1685   void InitializeSettings(LayerTreeSettings* settings) override {
1686     LayerTreeHostScrollTest::InitializeSettings(settings);
1687     settings->main_frame_before_activation_enabled = true;
1688   }
1689 
BeginTest()1690   void BeginTest() override {
1691     SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(),
1692                     initial_scroll_);
1693     PostSetNeedsCommitToMainThread();
1694   }
1695 
ReadyToCommitOnThread(LayerTreeHostImpl * impl)1696   void ReadyToCommitOnThread(LayerTreeHostImpl* impl) override {
1697     switch (num_commits_) {
1698       case 1:
1699         // Ask for commit here because activation (and draw) will be blocked.
1700         impl->SetNeedsCommit();
1701         // Block activation after second commit until third commit is ready.
1702         impl->BlockNotifyReadyToActivateForTesting(true);
1703         break;
1704       case 2:
1705         // Unblock activation after third commit is ready.
1706         impl->BlockNotifyReadyToActivateForTesting(false);
1707         break;
1708     }
1709     num_commits_++;
1710   }
1711 
UpdateLayerTreeHost()1712   void UpdateLayerTreeHost() override {
1713     Layer* scroll_layer =
1714         layer_tree_host()->OuterViewportScrollLayerForTesting();
1715     switch (layer_tree_host()->SourceFrameNumber()) {
1716       case 0:
1717         EXPECT_VECTOR_EQ(initial_scroll_, CurrentScrollOffset(scroll_layer));
1718         break;
1719       case 1:
1720         EXPECT_VECTOR_EQ(
1721             gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_),
1722             CurrentScrollOffset(scroll_layer));
1723         // Pretend like Javascript updated the scroll position itself.
1724         SetScrollOffset(scroll_layer, second_scroll_);
1725         break;
1726       case 2:
1727         // Third frame does not see a scroll delta because we only did one
1728         // scroll for the second and third frames.
1729         EXPECT_VECTOR_EQ(second_scroll_, CurrentScrollOffset(scroll_layer));
1730         // Pretend like Javascript updated the scroll position itself.
1731         SetScrollOffset(scroll_layer, third_scroll_);
1732         break;
1733     }
1734   }
1735 
DrawLayersOnThread(LayerTreeHostImpl * impl)1736   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1737     LayerImpl* scroll_layer =
1738         impl->active_tree()->OuterViewportScrollLayerForTesting();
1739     switch (impl->active_tree()->source_frame_number()) {
1740       case 0:
1741         EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer));
1742         EXPECT_VECTOR_EQ(initial_scroll_, ScrollOffsetBase(scroll_layer));
1743         Scroll(impl);
1744         EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer));
1745         // Ask for commit after we've scrolled.
1746         impl->SetNeedsCommit();
1747         break;
1748       case 1:
1749         EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer));
1750         EXPECT_VECTOR_EQ(second_scroll_, ScrollOffsetBase(scroll_layer));
1751         Scroll(impl);
1752         EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer));
1753         break;
1754       case 2:
1755         // The scroll hasn't been consumed by the main thread.
1756         EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer));
1757         EXPECT_VECTOR_EQ(third_scroll_, ScrollOffsetBase(scroll_layer));
1758         EndTest();
1759         break;
1760     }
1761   }
1762 
AfterTest()1763   void AfterTest() override {
1764     EXPECT_EQ(3, num_commits_);
1765     EXPECT_EQ(1, num_outer_viewport_scrolls_);
1766   }
1767 
1768  private:
Scroll(LayerTreeHostImpl * impl)1769   void Scroll(LayerTreeHostImpl* impl) {
1770     LayerImpl* root = impl->active_tree()->root_layer();
1771     LayerImpl* scroll_layer =
1772         impl->active_tree()->OuterViewportScrollLayerForTesting();
1773 
1774     scroll_layer->SetBounds(
1775         gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
1776     scroll_layer->ScrollBy(scroll_amount_);
1777   }
1778 
1779   gfx::ScrollOffset initial_scroll_;
1780   gfx::ScrollOffset second_scroll_;
1781   gfx::ScrollOffset third_scroll_;
1782   gfx::Vector2dF scroll_amount_;
1783   int num_commits_;
1784 };
1785 
1786 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMFBA);
1787 
1788 class LayerTreeHostScrollTestScrollAbortedCommitMFBA
1789     : public LayerTreeHostScrollTest {
1790  public:
LayerTreeHostScrollTestScrollAbortedCommitMFBA()1791   LayerTreeHostScrollTestScrollAbortedCommitMFBA()
1792       : initial_scroll_(50, 60),
1793         impl_scroll_(-3, 2),
1794         second_main_scroll_(14, -3),
1795         num_will_begin_main_frames_(0),
1796         num_did_begin_main_frames_(0),
1797         num_will_commits_(0),
1798         num_did_commits_(0),
1799         num_impl_commits_(0),
1800         num_aborted_commits_(0),
1801         num_draws_(0) {}
1802 
InitializeSettings(LayerTreeSettings * settings)1803   void InitializeSettings(LayerTreeSettings* settings) override {
1804     LayerTreeHostScrollTest::InitializeSettings(settings);
1805     settings->main_frame_before_activation_enabled = true;
1806   }
1807 
BeginTest()1808   void BeginTest() override {
1809     SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(),
1810                     initial_scroll_);
1811     PostSetNeedsCommitToMainThread();
1812   }
1813 
SetupTree()1814   void SetupTree() override {
1815     LayerTreeHostScrollTest::SetupTree();
1816 
1817     gfx::Size scroll_layer_bounds(200, 200);
1818     layer_tree_host()->OuterViewportScrollLayerForTesting()->SetBounds(
1819         scroll_layer_bounds);
1820     layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
1821   }
1822 
WillBeginMainFrame()1823   void WillBeginMainFrame() override {
1824     num_will_begin_main_frames_++;
1825     Layer* root_scroll_layer =
1826         layer_tree_host()->OuterViewportScrollLayerForTesting();
1827     switch (num_will_begin_main_frames_) {
1828       case 1:
1829         // This will not be aborted because of the initial prop changes.
1830         EXPECT_EQ(0, num_outer_viewport_scrolls_);
1831         EXPECT_EQ(0, layer_tree_host()->SourceFrameNumber());
1832         EXPECT_VECTOR_EQ(initial_scroll_,
1833                          CurrentScrollOffset(root_scroll_layer));
1834         break;
1835       case 2:
1836         // This commit will not be aborted because of the scroll change.
1837         EXPECT_EQ(1, num_outer_viewport_scrolls_);
1838         EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber());
1839         EXPECT_VECTOR_EQ(
1840             gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_),
1841             CurrentScrollOffset(root_scroll_layer));
1842         SetScrollOffset(
1843             root_scroll_layer,
1844             gfx::ScrollOffsetWithDelta(CurrentScrollOffset(root_scroll_layer),
1845                                        second_main_scroll_));
1846         break;
1847       case 3: {
1848         // This commit will be aborted.
1849         EXPECT_EQ(2, num_outer_viewport_scrolls_);
1850         // The source frame number still increases even with the abort.
1851         EXPECT_EQ(2, layer_tree_host()->SourceFrameNumber());
1852         gfx::Vector2dF delta =
1853             impl_scroll_ + impl_scroll_ + second_main_scroll_;
1854         EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
1855                          CurrentScrollOffset(root_scroll_layer));
1856         break;
1857       }
1858       case 4: {
1859         // This commit will also be aborted.
1860         EXPECT_EQ(3, num_outer_viewport_scrolls_);
1861         EXPECT_EQ(3, layer_tree_host()->SourceFrameNumber());
1862         gfx::Vector2dF delta =
1863             impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
1864         EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
1865                          CurrentScrollOffset(root_scroll_layer));
1866         break;
1867       }
1868     }
1869   }
1870 
DidBeginMainFrame()1871   void DidBeginMainFrame() override { num_did_begin_main_frames_++; }
1872 
WillCommit()1873   void WillCommit() override { num_will_commits_++; }
1874 
DidCommit()1875   void DidCommit() override { num_did_commits_++; }
1876 
BeginCommitOnThread(LayerTreeHostImpl * impl)1877   void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
1878     switch (num_impl_commits_) {
1879       case 1:
1880         // Redraw so that we keep scrolling.
1881         impl->SetNeedsRedraw();
1882         // Block activation until third commit is aborted.
1883         impl->BlockNotifyReadyToActivateForTesting(true);
1884         break;
1885     }
1886     num_impl_commits_++;
1887   }
1888 
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * impl,CommitEarlyOutReason reason)1889   void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* impl,
1890                                      CommitEarlyOutReason reason) override {
1891     switch (num_aborted_commits_) {
1892       case 0:
1893         EXPECT_EQ(2, num_impl_commits_);
1894         // Unblock activation when third commit is aborted.
1895         impl->BlockNotifyReadyToActivateForTesting(false);
1896         break;
1897       case 1:
1898         EXPECT_EQ(2, num_impl_commits_);
1899         // Redraw to end the test.
1900         impl->SetNeedsRedraw();
1901         break;
1902     }
1903     num_aborted_commits_++;
1904   }
1905 
DrawLayersOnThread(LayerTreeHostImpl * impl)1906   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1907     LayerImpl* root_scroll_layer =
1908         impl->active_tree()->OuterViewportScrollLayerForTesting();
1909     switch (impl->active_tree()->source_frame_number()) {
1910       case 0: {
1911         switch (num_impl_commits_) {
1912           case 1: {
1913             // First draw
1914             EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(root_scroll_layer));
1915             root_scroll_layer->ScrollBy(impl_scroll_);
1916             EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer));
1917             EXPECT_VECTOR_EQ(initial_scroll_,
1918                              ScrollOffsetBase(root_scroll_layer));
1919             impl->SetNeedsCommit();
1920             break;
1921           }
1922           case 2: {
1923             // Second draw but no new active tree because activation is blocked.
1924             EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer));
1925             root_scroll_layer->ScrollBy(impl_scroll_);
1926             EXPECT_VECTOR_EQ(impl_scroll_ + impl_scroll_,
1927                              ScrollDelta(root_scroll_layer));
1928             EXPECT_VECTOR_EQ(initial_scroll_,
1929                              ScrollOffsetBase(root_scroll_layer));
1930             // Ask for another commit (which will abort).
1931             impl->SetNeedsCommit();
1932             break;
1933           }
1934           default:
1935             NOTREACHED();
1936         }
1937         break;
1938       }
1939       case 1: {
1940         EXPECT_EQ(2, num_impl_commits_);
1941         // All scroll deltas so far should be consumed.
1942         EXPECT_EQ(gfx::ScrollOffset(), ScrollDelta(root_scroll_layer));
1943         switch (num_aborted_commits_) {
1944           case 1: {
1945             root_scroll_layer->ScrollBy(impl_scroll_);
1946             EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer));
1947             gfx::Vector2dF prev_delta =
1948                 impl_scroll_ + impl_scroll_ + second_main_scroll_;
1949             EXPECT_VECTOR_EQ(
1950                 gfx::ScrollOffsetWithDelta(initial_scroll_, prev_delta),
1951                 ScrollOffsetBase(root_scroll_layer));
1952             // Ask for another commit (which will abort).
1953             impl->SetNeedsCommit();
1954             break;
1955           }
1956           case 2: {
1957             gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + impl_scroll_ +
1958                                    second_main_scroll_;
1959             EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
1960                              ScrollOffsetBase(root_scroll_layer));
1961             // End test after second aborted commit (fourth commit request).
1962             EndTest();
1963             break;
1964           }
1965         }
1966         break;
1967       }
1968     }
1969     num_draws_++;
1970   }
1971 
AfterTest()1972   void AfterTest() override {
1973     EXPECT_EQ(3, num_outer_viewport_scrolls_);
1974     // Verify that the embedder sees aborted commits as real commits.
1975     EXPECT_EQ(4, num_will_begin_main_frames_);
1976     EXPECT_EQ(4, num_did_begin_main_frames_);
1977     EXPECT_EQ(4, num_will_commits_);
1978     EXPECT_EQ(4, num_did_commits_);
1979     // ...but the compositor thread only sees two real ones.
1980     EXPECT_EQ(2, num_impl_commits_);
1981     // ...and two aborted ones.
1982     EXPECT_EQ(2, num_aborted_commits_);
1983     // ...and four draws.
1984     EXPECT_EQ(4, num_draws_);
1985   }
1986 
1987  private:
1988   gfx::ScrollOffset initial_scroll_;
1989   gfx::Vector2dF impl_scroll_;
1990   gfx::Vector2dF second_main_scroll_;
1991   int num_will_begin_main_frames_;
1992   int num_did_begin_main_frames_;
1993   int num_will_commits_;
1994   int num_did_commits_;
1995   int num_impl_commits_;
1996   int num_aborted_commits_;
1997   int num_draws_;
1998 };
1999 
2000 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommitMFBA);
2001 
2002 class MockInputHandlerClient : public InputHandlerClient {
2003  public:
2004   MockInputHandlerClient() = default;
2005 
2006   MOCK_METHOD0(ReconcileElasticOverscrollAndRootScroll, void());
2007 
WillShutdown()2008   void WillShutdown() override {}
Animate(base::TimeTicks)2009   void Animate(base::TimeTicks) override {}
UpdateRootLayerStateForSynchronousInputHandler(const gfx::ScrollOffset & total_scroll_offset,const gfx::ScrollOffset & max_scroll_offset,const gfx::SizeF & scrollable_size,float page_scale_factor,float min_page_scale_factor,float max_page_scale_factor)2010   void UpdateRootLayerStateForSynchronousInputHandler(
2011       const gfx::ScrollOffset& total_scroll_offset,
2012       const gfx::ScrollOffset& max_scroll_offset,
2013       const gfx::SizeF& scrollable_size,
2014       float page_scale_factor,
2015       float min_page_scale_factor,
2016       float max_page_scale_factor) override {}
DeliverInputForBeginFrame(const viz::BeginFrameArgs & args)2017   void DeliverInputForBeginFrame(const viz::BeginFrameArgs& args) override {}
DeliverInputForHighLatencyMode()2018   void DeliverInputForHighLatencyMode() override {}
2019 };
2020 
2021 // This is a regression test, see crbug.com/639046.
2022 class LayerTreeHostScrollTestElasticOverscroll
2023     : public LayerTreeHostScrollTest {
2024  public:
LayerTreeHostScrollTestElasticOverscroll()2025   LayerTreeHostScrollTestElasticOverscroll()
2026       : num_begin_main_frames_impl_thread_(0),
2027         scroll_elasticity_helper_(nullptr),
2028         num_begin_main_frames_main_thread_(0) {}
2029 
InitializeSettings(LayerTreeSettings * settings)2030   void InitializeSettings(LayerTreeSettings* settings) override {
2031     LayerTreeHostScrollTest::InitializeSettings(settings);
2032     settings->enable_elastic_overscroll = true;
2033   }
2034 
BeginTest()2035   void BeginTest() override {
2036     DCHECK(HasImplThread());
2037     ImplThreadTaskRunner()->PostTask(
2038         FROM_HERE,
2039         base::BindOnce(
2040             &LayerTreeHostScrollTestElasticOverscroll::BindInputHandler,
2041             base::Unretained(this), layer_tree_host()->GetInputHandler()));
2042     PostSetNeedsCommitToMainThread();
2043   }
2044 
BindInputHandler(base::WeakPtr<InputHandler> input_handler)2045   void BindInputHandler(base::WeakPtr<InputHandler> input_handler) {
2046     DCHECK(task_runner_provider()->IsImplThread());
2047     input_handler->BindToClient(&input_handler_client_);
2048     scroll_elasticity_helper_ = input_handler->CreateScrollElasticityHelper();
2049     DCHECK(scroll_elasticity_helper_);
2050   }
2051 
ApplyViewportChanges(const ApplyViewportChangesArgs & args)2052   void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override {
2053     DCHECK_NE(0, num_begin_main_frames_main_thread_)
2054         << "The first BeginMainFrame has no deltas to report";
2055     DCHECK_LT(num_begin_main_frames_main_thread_, 5);
2056 
2057     gfx::Vector2dF expected_elastic_overscroll =
2058         elastic_overscroll_test_cases_[num_begin_main_frames_main_thread_];
2059     current_elastic_overscroll_ += args.elastic_overscroll_delta;
2060     EXPECT_EQ(expected_elastic_overscroll, current_elastic_overscroll_);
2061     EXPECT_EQ(expected_elastic_overscroll,
2062               layer_tree_host()->elastic_overscroll());
2063   }
2064 
WillBeginMainFrame()2065   void WillBeginMainFrame() override { num_begin_main_frames_main_thread_++; }
2066 
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * host_impl,CommitEarlyOutReason reason)2067   void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2068                                      CommitEarlyOutReason reason) override {
2069     VerifyBeginMainFrameResultOnImplThread(host_impl, true);
2070   }
2071 
WillCommitCompleteOnThread(LayerTreeHostImpl * host_impl)2072   void WillCommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2073     VerifyBeginMainFrameResultOnImplThread(host_impl, false);
2074   }
2075 
VerifyBeginMainFrameResultOnImplThread(LayerTreeHostImpl * host_impl,bool begin_main_frame_aborted)2076   void VerifyBeginMainFrameResultOnImplThread(LayerTreeHostImpl* host_impl,
2077                                               bool begin_main_frame_aborted) {
2078     gfx::Vector2dF expected_elastic_overscroll =
2079         elastic_overscroll_test_cases_[num_begin_main_frames_impl_thread_];
2080     EXPECT_EQ(expected_elastic_overscroll,
2081               scroll_elasticity_helper_->StretchAmount());
2082     if (!begin_main_frame_aborted)
2083       EXPECT_EQ(
2084           expected_elastic_overscroll,
2085           host_impl->pending_tree()->elastic_overscroll()->Current(false));
2086 
2087     ++num_begin_main_frames_impl_thread_;
2088     gfx::Vector2dF next_test_case;
2089     if (num_begin_main_frames_impl_thread_ < 5)
2090       next_test_case =
2091           elastic_overscroll_test_cases_[num_begin_main_frames_impl_thread_];
2092 
2093     switch (num_begin_main_frames_impl_thread_) {
2094       case 1:
2095         // The first BeginMainFrame is never aborted.
2096         EXPECT_FALSE(begin_main_frame_aborted);
2097         scroll_elasticity_helper_->SetStretchAmount(next_test_case);
2098         break;
2099       case 2:
2100         EXPECT_TRUE(begin_main_frame_aborted);
2101         scroll_elasticity_helper_->SetStretchAmount(next_test_case);
2102 
2103         // Since the elastic overscroll is never mutated on the main thread, the
2104         // BeginMainFrame which reports the delta is aborted. Post a commit
2105         // request to the main thread to make sure it goes through.
2106         PostSetNeedsCommitToMainThread();
2107         break;
2108       case 3:
2109         EXPECT_FALSE(begin_main_frame_aborted);
2110         scroll_elasticity_helper_->SetStretchAmount(next_test_case);
2111         PostSetNeedsCommitToMainThread();
2112         break;
2113       case 4:
2114         EXPECT_FALSE(begin_main_frame_aborted);
2115         scroll_elasticity_helper_->SetStretchAmount(next_test_case);
2116         break;
2117       case 5:
2118         EXPECT_TRUE(begin_main_frame_aborted);
2119         EndTest();
2120         break;
2121       default:
2122         NOTREACHED();
2123     }
2124   }
2125 
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)2126   void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2127     if (num_begin_main_frames_impl_thread_ == 5)
2128       return;
2129 
2130     // Ensure that the elastic overscroll value on the active tree remains
2131     // unmodified after activation.
2132     gfx::Vector2dF expected_elastic_overscroll =
2133         elastic_overscroll_test_cases_[num_begin_main_frames_impl_thread_];
2134     EXPECT_EQ(expected_elastic_overscroll,
2135               scroll_elasticity_helper_->StretchAmount());
2136   }
2137 
WillPrepareToDrawOnThread(LayerTreeHostImpl * host_impl)2138   void WillPrepareToDrawOnThread(LayerTreeHostImpl* host_impl) override {
2139     // The InputHandlerClient must receive a call to reconcile the overscroll
2140     // before each draw.
2141     EXPECT_CALL(input_handler_client_,
2142                 ReconcileElasticOverscrollAndRootScroll())
2143         .Times(1);
2144   }
2145 
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)2146   DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2147                                    LayerTreeHostImpl::FrameData* frame_data,
2148                                    DrawResult draw_result) override {
2149     Mock::VerifyAndClearExpectations(&input_handler_client_);
2150     return draw_result;
2151   }
2152 
AfterTest()2153   void AfterTest() override {
2154     EXPECT_EQ(num_begin_main_frames_impl_thread_, 5);
2155     EXPECT_EQ(num_begin_main_frames_main_thread_, 5);
2156     gfx::Vector2dF expected_elastic_overscroll =
2157         elastic_overscroll_test_cases_[4];
2158     EXPECT_EQ(expected_elastic_overscroll, current_elastic_overscroll_);
2159   }
2160 
2161  private:
2162   // These values should be used on the impl thread only.
2163   int num_begin_main_frames_impl_thread_;
2164   MockInputHandlerClient input_handler_client_;
2165   ScrollElasticityHelper* scroll_elasticity_helper_;
2166 
2167   // These values should be used on the main thread only.
2168   int num_begin_main_frames_main_thread_;
2169   gfx::Vector2dF current_elastic_overscroll_;
2170 
2171   const gfx::Vector2dF elastic_overscroll_test_cases_[5] = {
2172       gfx::Vector2dF(0, 0), gfx::Vector2dF(5, 10), gfx::Vector2dF(5, 5),
2173       gfx::Vector2dF(-4, -5), gfx::Vector2dF(0, 0)};
2174 };
2175 
2176 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestElasticOverscroll);
2177 
2178 class LayerTreeHostScrollTestPropertyTreeUpdate
2179     : public LayerTreeHostScrollTest {
2180  public:
LayerTreeHostScrollTestPropertyTreeUpdate()2181   LayerTreeHostScrollTestPropertyTreeUpdate()
2182       : initial_scroll_(10, 20), second_scroll_(0, 0) {}
2183 
BeginTest()2184   void BeginTest() override {
2185     SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(),
2186                     initial_scroll_);
2187     PostSetNeedsCommitToMainThread();
2188   }
2189 
UpdateLayerTreeHost()2190   void UpdateLayerTreeHost() override {
2191     Layer* scroll_layer =
2192         layer_tree_host()->OuterViewportScrollLayerForTesting();
2193     if (layer_tree_host()->SourceFrameNumber() == 0) {
2194       EXPECT_VECTOR_EQ(initial_scroll_, CurrentScrollOffset(scroll_layer));
2195     } else {
2196       EXPECT_VECTOR_EQ(
2197           gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_),
2198           CurrentScrollOffset(scroll_layer));
2199       SetScrollOffset(scroll_layer, second_scroll_);
2200       SetOpacity(scroll_layer, 0.5f);
2201     }
2202   }
2203 
DidActivateTreeOnThread(LayerTreeHostImpl * impl)2204   void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
2205     LayerImpl* scroll_layer =
2206         impl->active_tree()->OuterViewportScrollLayerForTesting();
2207 
2208     switch (impl->active_tree()->source_frame_number()) {
2209       case 0:
2210         EXPECT_VECTOR_EQ(initial_scroll_, ScrollOffsetBase(scroll_layer));
2211         EXPECT_VECTOR_EQ(initial_scroll_,
2212                          GetTransformNode(scroll_layer)->scroll_offset);
2213         PostSetNeedsCommitToMainThread();
2214         break;
2215       case 1:
2216         EXPECT_VECTOR_EQ(second_scroll_, ScrollOffsetBase(scroll_layer));
2217         EXPECT_VECTOR_EQ(second_scroll_,
2218                          GetTransformNode(scroll_layer)->scroll_offset);
2219         EndTest();
2220         break;
2221     }
2222   }
2223 
2224  private:
2225   gfx::ScrollOffset initial_scroll_;
2226   gfx::ScrollOffset second_scroll_;
2227   gfx::Vector2dF scroll_amount_;
2228 };
2229 
2230 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostScrollTestPropertyTreeUpdate);
2231 
2232 class LayerTreeHostScrollTestImplSideInvalidation
2233     : public LayerTreeHostScrollTest {
BeginTest()2234   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2235 
DidScrollOuterViewport(const gfx::ScrollOffset & offset)2236   void DidScrollOuterViewport(const gfx::ScrollOffset& offset) override {
2237     LayerTreeHostScrollTest::DidScrollOuterViewport(offset);
2238 
2239     // Defer responding to the main frame until an impl-side pending tree is
2240     // created for the invalidation request.
2241     {
2242       CompletionEvent completion;
2243       task_runner_provider()->ImplThreadTaskRunner()->PostTask(
2244           FROM_HERE,
2245           base::BindOnce(&LayerTreeHostScrollTestImplSideInvalidation::
2246                              WaitForInvalidationOnImplThread,
2247                          base::Unretained(this), &completion));
2248       completion.Wait();
2249     }
2250 
2251     switch (++num_of_deltas_) {
2252       case 1: {
2253         // First set of deltas is here. The impl thread will scroll to the
2254         // second case on activation, so add a delta from the main thread that
2255         // takes us to the final value.
2256         Layer* outer_viewport_layer =
2257             layer_tree_host()->OuterViewportScrollLayerForTesting();
2258         gfx::ScrollOffset delta_to_send =
2259             outer_viewport_offsets_[2] - outer_viewport_offsets_[1];
2260         SetScrollOffset(
2261             outer_viewport_layer,
2262             CurrentScrollOffset(outer_viewport_layer) + delta_to_send);
2263       } break;
2264       case 2:
2265         // Let the commit abort for the second set of deltas.
2266         break;
2267       default:
2268         NOTREACHED();
2269     }
2270   }
2271 
WaitForInvalidationOnImplThread(CompletionEvent * completion)2272   void WaitForInvalidationOnImplThread(CompletionEvent* completion) {
2273     impl_side_invalidation_event_ = completion;
2274     SignalCompletionIfPossible();
2275   }
2276 
DidInvalidateContentOnImplSide(LayerTreeHostImpl * host_impl)2277   void DidInvalidateContentOnImplSide(LayerTreeHostImpl* host_impl) override {
2278     invalidated_on_impl_thread_ = true;
2279     SignalCompletionIfPossible();
2280   }
2281 
WillNotifyReadyToActivateOnThread(LayerTreeHostImpl * host_impl)2282   void WillNotifyReadyToActivateOnThread(
2283       LayerTreeHostImpl* host_impl) override {
2284     // Ensure that the scroll-offsets on the TransformTree are consistent with
2285     // the synced scroll offsets, for the pending tree.
2286     if (!host_impl->pending_tree())
2287       return;
2288 
2289     LayerImpl* scroll_layer =
2290         host_impl->pending_tree()->OuterViewportScrollLayerForTesting();
2291     gfx::ScrollOffset scroll_offset = CurrentScrollOffset(scroll_layer);
2292     int transform_index = scroll_layer->transform_tree_index();
2293     gfx::ScrollOffset transform_tree_scroll_offset =
2294         host_impl->pending_tree()
2295             ->property_trees()
2296             ->transform_tree.Node(transform_index)
2297             ->scroll_offset;
2298     EXPECT_EQ(scroll_offset, transform_tree_scroll_offset);
2299   }
2300 
SignalCompletionIfPossible()2301   void SignalCompletionIfPossible() {
2302     if (!invalidated_on_impl_thread_ || !impl_side_invalidation_event_)
2303       return;
2304 
2305     impl_side_invalidation_event_->Signal();
2306     impl_side_invalidation_event_ = nullptr;
2307     invalidated_on_impl_thread_ = false;
2308   }
2309 
DidSendBeginMainFrameOnThread(LayerTreeHostImpl * host_impl)2310   void DidSendBeginMainFrameOnThread(LayerTreeHostImpl* host_impl) override {
2311     switch (++num_of_main_frames_) {
2312       case 1:
2313         // Do nothing for the first BeginMainFrame.
2314         break;
2315       case 2:
2316         // Add some more delta to the active tree state of the scroll offset and
2317         // a commit to send this additional delta to the main thread.
2318         host_impl->active_tree()
2319             ->OuterViewportScrollLayerForTesting()
2320             ->SetCurrentScrollOffset(outer_viewport_offsets_[1]);
2321         host_impl->SetNeedsCommit();
2322 
2323         // Request an impl-side invalidation to create an impl-side pending
2324         // tree.
2325         host_impl->RequestImplSideInvalidationForCheckerImagedTiles();
2326         break;
2327       case 3:
2328         // Request another impl-side invalidation so the aborted commit comes
2329         // after this tree is activated.
2330         host_impl->RequestImplSideInvalidationForCheckerImagedTiles();
2331         break;
2332       default:
2333         NOTREACHED();
2334     }
2335   }
2336 
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * host_impl,CommitEarlyOutReason reason)2337   void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2338                                      CommitEarlyOutReason reason) override {
2339     EXPECT_EQ(CommitEarlyOutReason::FINISHED_NO_UPDATES, reason);
2340     EXPECT_EQ(3, num_of_main_frames_);
2341     EXPECT_EQ(
2342         outer_viewport_offsets_[2],
2343         CurrentScrollOffset(
2344             host_impl->active_tree()->OuterViewportScrollLayerForTesting()));
2345   }
2346 
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)2347   void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2348     switch (++num_of_activations_) {
2349       case 1:
2350         // Now that we have the active tree, scroll a layer and ask for a commit
2351         // to send a BeginMainFrame with the scroll delta to the main thread.
2352         host_impl->active_tree()
2353             ->OuterViewportScrollLayerForTesting()
2354             ->SetCurrentScrollOffset(outer_viewport_offsets_[0]);
2355         host_impl->SetNeedsCommit();
2356         break;
2357       case 2:
2358         // The second activation is from an impl-side pending tree so the source
2359         // frame number on the active tree remains unchanged, and the scroll
2360         // offset on the active tree should also remain unchanged.
2361         EXPECT_EQ(0, host_impl->active_tree()->source_frame_number());
2362         EXPECT_EQ(
2363             outer_viewport_offsets_[1],
2364             CurrentScrollOffset(host_impl->active_tree()
2365                                     ->OuterViewportScrollLayerForTesting()));
2366         break;
2367       case 3:
2368         // The third activation is from a commit. The scroll offset on the
2369         // active tree should include deltas sent from the main thread.
2370         EXPECT_EQ(1, host_impl->active_tree()->source_frame_number());
2371         EXPECT_EQ(
2372             outer_viewport_offsets_[2],
2373             CurrentScrollOffset(host_impl->active_tree()
2374                                     ->OuterViewportScrollLayerForTesting()));
2375         break;
2376       case 4:
2377         // The fourth activation is from an impl-side pending tree, which should
2378         // leave the scroll offset unchanged.
2379         EXPECT_EQ(1, host_impl->active_tree()->source_frame_number());
2380         EXPECT_EQ(
2381             outer_viewport_offsets_[2],
2382             CurrentScrollOffset(host_impl->active_tree()
2383                                     ->OuterViewportScrollLayerForTesting()));
2384         EndTest();
2385         break;
2386       default:
2387         NOTREACHED();
2388     }
2389   }
2390 
AfterTest()2391   void AfterTest() override {
2392     EXPECT_EQ(4, num_of_activations_);
2393     EXPECT_EQ(2, num_of_deltas_);
2394     EXPECT_EQ(3, num_of_main_frames_);
2395   }
2396 
2397   const gfx::ScrollOffset outer_viewport_offsets_[3] = {
2398       gfx::ScrollOffset(20, 20), gfx::ScrollOffset(50, 50),
2399       gfx::ScrollOffset(70, 70)};
2400 
2401   // Impl thread.
2402   int num_of_activations_ = 0;
2403   int num_of_main_frames_ = 0;
2404   bool invalidated_on_impl_thread_ = false;
2405   CompletionEvent* impl_side_invalidation_event_ = nullptr;
2406 
2407   // Main thread.
2408   int num_of_deltas_ = 0;
2409 };
2410 
2411 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplSideInvalidation);
2412 
2413 class NonScrollingNonFastScrollableRegion : public LayerTreeHostScrollTest {
2414  public:
NonScrollingNonFastScrollableRegion()2415   NonScrollingNonFastScrollableRegion() { SetUseLayerLists(); }
2416 
2417   // Setup 3 Layers:
2418   // 1) bottom_ which has a non-fast region in the bottom-right.
2419   // 2) middle_scrollable_ which is scrollable.
2420   // 3) top_ which has a non-fast region in the top-left and is offset by
2421   //    |middle_scrollable_|'s scroll offset.
SetupTree()2422   void SetupTree() override {
2423     SetInitialRootBounds(gfx::Size(800, 600));
2424     LayerTreeHostScrollTest::SetupTree();
2425     Layer* root = layer_tree_host()->root_layer();
2426     fake_content_layer_client_.set_bounds(root->bounds());
2427 
2428     bottom_ = FakePictureLayer::Create(&fake_content_layer_client_);
2429     bottom_->SetElementId(LayerIdToElementIdForTesting(bottom_->id()));
2430     bottom_->SetBounds(gfx::Size(100, 100));
2431     bottom_->SetNonFastScrollableRegion(Region(gfx::Rect(50, 50, 50, 50)));
2432     bottom_->SetHitTestable(true);
2433     CopyProperties(root, bottom_.get());
2434     root->AddChild(bottom_);
2435 
2436     middle_scrollable_ = FakePictureLayer::Create(&fake_content_layer_client_);
2437     middle_scrollable_->SetElementId(
2438         LayerIdToElementIdForTesting(middle_scrollable_->id()));
2439     middle_scrollable_->SetBounds(gfx::Size(100, 100));
2440     middle_scrollable_->SetIsDrawable(true);
2441     middle_scrollable_->SetHitTestable(true);
2442     CopyProperties(bottom_.get(), middle_scrollable_.get());
2443     CreateTransformNode(middle_scrollable_.get());
2444     CreateScrollNode(middle_scrollable_.get(), gfx::Size(100, 200));
2445     root->AddChild(middle_scrollable_);
2446 
2447     top_ = FakePictureLayer::Create(&fake_content_layer_client_);
2448     top_->SetElementId(LayerIdToElementIdForTesting(top_->id()));
2449     top_->SetBounds(gfx::Size(100, 100));
2450     top_->SetNonFastScrollableRegion(Region(gfx::Rect(0, 0, 50, 50)));
2451     top_->SetHitTestable(true);
2452     CopyProperties(middle_scrollable_.get(), top_.get());
2453     root->AddChild(top_);
2454   }
2455 
BeginTest()2456   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2457 
CommitCompleteOnThread(LayerTreeHostImpl * impl)2458   void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2459     if (TestEnded())
2460       return;
2461 
2462     // The top-left hit should immediately hit the top layer's non-fast region
2463     // which forces main-thread scrolling.
2464     auto top_left_status = impl->ScrollBegin(
2465         BeginState(gfx::Point(20, 20)).get(), ScrollInputType::kTouchscreen);
2466     EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, top_left_status.thread);
2467     EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
2468               top_left_status.main_thread_scrolling_reasons);
2469 
2470     // The top-right hit should hit the top layer but not the non-fast region so
2471     // the scroll should continue to scroll on the impl.
2472     InputHandler::ScrollStatus top_right_status = impl->ScrollBegin(
2473         BeginState(gfx::Point(80, 20)).get(), ScrollInputType::kTouchscreen);
2474     EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, top_right_status.thread);
2475     EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
2476               top_right_status.main_thread_scrolling_reasons);
2477     impl->ScrollEnd();
2478 
2479     // The bottom-right should hit the bottom layer's non-fast region. Though
2480     // the middle layer is a composited scroller and is hit first, we cannot do
2481     // a fast scroll because an ancestor on the scroll chain has hit a non-fast
2482     // region.
2483     InputHandler::ScrollStatus bottom_right_status = impl->ScrollBegin(
2484         BeginState(gfx::Point(80, 80)).get(), ScrollInputType::kTouchscreen);
2485     EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, bottom_right_status.thread);
2486     EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
2487               bottom_right_status.main_thread_scrolling_reasons);
2488 
2489     EndTest();
2490   }
2491 
2492  private:
2493   FakeContentLayerClient fake_content_layer_client_;
2494   scoped_refptr<Layer> bottom_;
2495   scoped_refptr<Layer> middle_scrollable_;
2496   scoped_refptr<Layer> top_;
2497 };
2498 
2499 SINGLE_THREAD_TEST_F(NonScrollingNonFastScrollableRegion);
2500 
2501 }  // namespace
2502 }  // namespace cc
2503