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