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