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