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 20namespace cc { 21namespace { 22 23class LayerTreeHostScrollTest : public LayerTreeTest {}; 24 25class 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 89MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple); 90 91class 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 165MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw); 166 167class 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_frames_(0), 176 num_did_begin_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 WillBeginFrame() OVERRIDE { 198 num_will_begin_frames_++; 199 Layer* root_scroll_layer = layer_tree_host()->root_layer()->children()[0]; 200 switch (num_will_begin_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 DidBeginFrame() OVERRIDE { num_did_begin_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_frames_); 321 EXPECT_EQ(4, num_did_begin_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_frames_; 334 int num_did_begin_frames_; 335 int num_will_commits_; 336 int num_did_commits_; 337 int num_impl_commits_; 338 int num_impl_scrolls_; 339}; 340 341MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit); 342 343class 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 391MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll); 392 393class 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 601TEST_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 608TEST_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 615TEST_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 622TEST_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 629TEST_F(LayerTreeHostScrollTestCaseWithChild, 630 DeviceScaleFactor15_ScrollChild_DirectRenderer) { 631 device_scale_factor_ = 1.5f; 632 scroll_child_layer_ = true; 633 RunTest(true, false, true); 634} 635 636TEST_F(LayerTreeHostScrollTestCaseWithChild, 637 DeviceScaleFactor15_ScrollChild_DelegatingRenderer) { 638 device_scale_factor_ = 1.5f; 639 scroll_child_layer_ = true; 640 RunTest(true, true, true); 641} 642 643TEST_F(LayerTreeHostScrollTestCaseWithChild, 644 DeviceScaleFactor2_ScrollChild_DirectRenderer) { 645 device_scale_factor_ = 2.f; 646 scroll_child_layer_ = true; 647 RunTest(true, false, true); 648} 649 650TEST_F(LayerTreeHostScrollTestCaseWithChild, 651 DeviceScaleFactor2_ScrollChild_DelegatingRenderer) { 652 device_scale_factor_ = 2.f; 653 scroll_child_layer_ = true; 654 RunTest(true, true, true); 655} 656 657TEST_F(LayerTreeHostScrollTestCaseWithChild, 658 DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer) { 659 device_scale_factor_ = 1.f; 660 scroll_child_layer_ = false; 661 RunTest(true, false, true); 662} 663 664TEST_F(LayerTreeHostScrollTestCaseWithChild, 665 DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer) { 666 device_scale_factor_ = 1.f; 667 scroll_child_layer_ = false; 668 RunTest(true, true, true); 669} 670 671TEST_F(LayerTreeHostScrollTestCaseWithChild, 672 DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer) { 673 device_scale_factor_ = 1.5f; 674 scroll_child_layer_ = false; 675 RunTest(true, false, true); 676} 677 678TEST_F(LayerTreeHostScrollTestCaseWithChild, 679 DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer) { 680 device_scale_factor_ = 1.5f; 681 scroll_child_layer_ = false; 682 RunTest(true, true, true); 683} 684 685TEST_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 692TEST_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 699TEST_F(LayerTreeHostScrollTestCaseWithChild, 700 DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer) { 701 device_scale_factor_ = 2.f; 702 scroll_child_layer_ = false; 703 RunTest(true, true, true); 704} 705 706class 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 718class 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 can_activate_(true) {} 727 728 virtual void BeginTest() OVERRIDE { 729 layer_tree_host()->root_layer()->SetScrollable(true); 730 layer_tree_host()->root_layer() 731 ->SetMaxScrollOffset(gfx::Vector2d(100, 100)); 732 layer_tree_host()->root_layer()->SetScrollOffset(initial_scroll_); 733 PostSetNeedsCommitToMainThread(); 734 } 735 736 virtual void Layout() OVERRIDE { 737 Layer* root = layer_tree_host()->root_layer(); 738 if (!layer_tree_host()->source_frame_number()) { 739 EXPECT_VECTOR_EQ(root->scroll_offset(), initial_scroll_); 740 } else { 741 EXPECT_VECTOR_EQ(root->scroll_offset(), 742 initial_scroll_ + impl_thread_scroll1_); 743 744 // Pretend like Javascript updated the scroll position itself with a 745 // change of main_thread_scroll. 746 root->SetScrollOffset(initial_scroll_ + main_thread_scroll_ + 747 impl_thread_scroll1_); 748 } 749 } 750 751 virtual bool CanActivatePendingTree(LayerTreeHostImpl* impl) OVERRIDE { 752 return can_activate_; 753 } 754 755 virtual bool CanActivatePendingTreeIfNeeded(LayerTreeHostImpl* impl) 756 OVERRIDE { 757 return can_activate_; 758 } 759 760 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 761 // We force a second draw here of the first commit before activating 762 // the second commit. 763 if (impl->active_tree()->source_frame_number() == 0) 764 impl->SetNeedsRedraw(); 765 } 766 767 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 768 ImplSidePaintingScrollTest::DrawLayersOnThread(impl); 769 770 LayerImpl* root = impl->active_tree()->root_layer(); 771 LayerImpl* pending_root = 772 impl->active_tree()->FindPendingTreeLayerById(root->id()); 773 774 switch (impl->active_tree()->source_frame_number()) { 775 case 0: 776 if (!impl->pending_tree()) { 777 can_activate_ = false; 778 EXPECT_VECTOR_EQ(root->ScrollDelta(), gfx::Vector2d()); 779 root->ScrollBy(impl_thread_scroll1_); 780 781 EXPECT_VECTOR_EQ(root->scroll_offset(), initial_scroll_); 782 EXPECT_VECTOR_EQ(root->ScrollDelta(), impl_thread_scroll1_); 783 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), gfx::Vector2d()); 784 PostSetNeedsCommitToMainThread(); 785 786 // CommitCompleteOnThread will trigger this function again 787 // and cause us to take the else clause. 788 } else { 789 can_activate_ = true; 790 ASSERT_TRUE(pending_root); 791 EXPECT_EQ(impl->pending_tree()->source_frame_number(), 1); 792 793 root->ScrollBy(impl_thread_scroll2_); 794 EXPECT_VECTOR_EQ(root->scroll_offset(), initial_scroll_); 795 EXPECT_VECTOR_EQ(root->ScrollDelta(), 796 impl_thread_scroll1_ + impl_thread_scroll2_); 797 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), impl_thread_scroll1_); 798 799 EXPECT_VECTOR_EQ( 800 pending_root->scroll_offset(), 801 initial_scroll_ + main_thread_scroll_ + impl_thread_scroll1_); 802 EXPECT_VECTOR_EQ(pending_root->ScrollDelta(), impl_thread_scroll2_); 803 EXPECT_VECTOR_EQ(pending_root->sent_scroll_delta(), gfx::Vector2d()); 804 } 805 break; 806 case 1: 807 EXPECT_FALSE(impl->pending_tree()); 808 EXPECT_VECTOR_EQ( 809 root->scroll_offset(), 810 initial_scroll_ + main_thread_scroll_ + impl_thread_scroll1_); 811 EXPECT_VECTOR_EQ(root->ScrollDelta(), impl_thread_scroll2_); 812 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), gfx::Vector2d()); 813 EndTest(); 814 break; 815 } 816 } 817 818 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, 819 float scale) OVERRIDE { 820 num_scrolls_++; 821 } 822 823 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); } 824 825 private: 826 gfx::Vector2d initial_scroll_; 827 gfx::Vector2d main_thread_scroll_; 828 gfx::Vector2d impl_thread_scroll1_; 829 gfx::Vector2d impl_thread_scroll2_; 830 int num_scrolls_; 831 bool can_activate_; 832}; 833 834MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple); 835 836class LayerTreeHostScrollTestScrollZeroMaxScrollOffset 837 : public LayerTreeHostScrollTest { 838 public: 839 LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {} 840 841 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 842 843 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 844 LayerImpl* root = impl->active_tree()->root_layer(); 845 root->SetScrollable(true); 846 847 root->SetMaxScrollOffset(gfx::Vector2d(100, 100)); 848 EXPECT_EQ(InputHandler::ScrollStarted, 849 root->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::Gesture)); 850 851 root->SetMaxScrollOffset(gfx::Vector2d(0, 0)); 852 EXPECT_EQ(InputHandler::ScrollIgnored, 853 root->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::Gesture)); 854 855 root->SetMaxScrollOffset(gfx::Vector2d(-100, -100)); 856 EXPECT_EQ(InputHandler::ScrollIgnored, 857 root->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::Gesture)); 858 859 EndTest(); 860 } 861 862 virtual void AfterTest() OVERRIDE {} 863}; 864 865SINGLE_AND_MULTI_THREAD_TEST_F( 866 LayerTreeHostScrollTestScrollZeroMaxScrollOffset); 867 868class ThreadCheckingInputHandlerClient : public InputHandlerClient { 869 public: 870 ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner* runner, 871 bool* received_stop_flinging) 872 : task_runner_(runner), received_stop_flinging_(received_stop_flinging) {} 873 874 virtual void WillShutdown() OVERRIDE { 875 if (!received_stop_flinging_) 876 ADD_FAILURE() << "WillShutdown() called before fling stopped"; 877 } 878 879 virtual void Animate(base::TimeTicks time) OVERRIDE { 880 if (!task_runner_->BelongsToCurrentThread()) 881 ADD_FAILURE() << "Animate called on wrong thread"; 882 } 883 884 virtual void MainThreadHasStoppedFlinging() OVERRIDE { 885 if (!task_runner_->BelongsToCurrentThread()) 886 ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread"; 887 *received_stop_flinging_ = true; 888 } 889 890 virtual void DidOverscroll(const DidOverscrollParams& params) OVERRIDE { 891 if (!task_runner_->BelongsToCurrentThread()) 892 ADD_FAILURE() << "DidOverscroll called on wrong thread"; 893 } 894 895 private: 896 base::SingleThreadTaskRunner* task_runner_; 897 bool* received_stop_flinging_; 898}; 899 900void BindInputHandlerOnCompositorThread( 901 const base::WeakPtr<InputHandler>& input_handler, 902 ThreadCheckingInputHandlerClient* client) { 903 input_handler->BindToClient(client); 904} 905 906TEST(LayerTreeHostFlingTest, DidStopFlingingThread) { 907 base::Thread impl_thread("cc"); 908 ASSERT_TRUE(impl_thread.Start()); 909 910 bool received_stop_flinging = false; 911 LayerTreeSettings settings; 912 913 ThreadCheckingInputHandlerClient input_handler_client( 914 impl_thread.message_loop_proxy().get(), &received_stop_flinging); 915 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); 916 917 ASSERT_TRUE(impl_thread.message_loop_proxy().get()); 918 scoped_ptr<LayerTreeHost> layer_tree_host = LayerTreeHost::Create( 919 &client, settings, impl_thread.message_loop_proxy()); 920 921 impl_thread.message_loop_proxy() 922 ->PostTask(FROM_HERE, 923 base::Bind(&BindInputHandlerOnCompositorThread, 924 layer_tree_host->GetInputHandler(), 925 base::Unretained(&input_handler_client))); 926 927 layer_tree_host->DidStopFlinging(); 928 layer_tree_host.reset(); 929 impl_thread.Stop(); 930 EXPECT_TRUE(received_stop_flinging); 931} 932 933class LayerTreeHostScrollTestLayerStructureChange 934 : public LayerTreeHostScrollTest { 935 public: 936 LayerTreeHostScrollTestLayerStructureChange() 937 : scroll_destroy_whole_tree_(false) {} 938 939 virtual void SetupTree() OVERRIDE { 940 scoped_refptr<Layer> root_layer = Layer::Create(); 941 root_layer->SetBounds(gfx::Size(10, 10)); 942 943 Layer* root_scroll_layer = 944 CreateScrollLayer(root_layer.get(), &root_scroll_layer_client_); 945 CreateScrollLayer(root_layer.get(), &sibling_scroll_layer_client_); 946 CreateScrollLayer(root_scroll_layer, &child_scroll_layer_client_); 947 948 layer_tree_host()->SetRootLayer(root_layer); 949 LayerTreeHostScrollTest::SetupTree(); 950 } 951 952 virtual void BeginTest() OVERRIDE { 953 PostSetNeedsCommitToMainThread(); 954 } 955 956 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 957 LayerImpl* root = impl->active_tree()->root_layer(); 958 switch (impl->active_tree()->source_frame_number()) { 959 case 0: 960 root->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5)); 961 root->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5)); 962 root->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5)); 963 PostSetNeedsCommitToMainThread(); 964 break; 965 case 1: 966 EndTest(); 967 break; 968 } 969 } 970 971 virtual void AfterTest() OVERRIDE {} 972 973 virtual void DidScroll(Layer* layer) { 974 if (scroll_destroy_whole_tree_) { 975 layer_tree_host()->SetRootLayer(NULL); 976 EndTest(); 977 return; 978 } 979 layer->RemoveFromParent(); 980 } 981 982 protected: 983 class FakeLayerScrollClient { 984 public: 985 void DidScroll() { 986 owner_->DidScroll(layer_); 987 } 988 LayerTreeHostScrollTestLayerStructureChange* owner_; 989 Layer* layer_; 990 }; 991 992 Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) { 993 scoped_refptr<Layer> scroll_layer = 994 ContentLayer::Create(&fake_content_layer_client_); 995 scroll_layer->SetBounds(gfx::Size(110, 110)); 996 scroll_layer->SetPosition(gfx::Point(0, 0)); 997 scroll_layer->SetAnchorPoint(gfx::PointF()); 998 scroll_layer->SetIsDrawable(true); 999 scroll_layer->SetScrollable(true); 1000 scroll_layer->SetMaxScrollOffset(gfx::Vector2d(100, 100)); 1001 scroll_layer->set_did_scroll_callback(base::Bind( 1002 &FakeLayerScrollClient::DidScroll, base::Unretained(client))); 1003 client->owner_ = this; 1004 client->layer_ = scroll_layer.get(); 1005 parent->AddChild(scroll_layer); 1006 return scroll_layer.get(); 1007 } 1008 1009 FakeLayerScrollClient root_scroll_layer_client_; 1010 FakeLayerScrollClient sibling_scroll_layer_client_; 1011 FakeLayerScrollClient child_scroll_layer_client_; 1012 1013 FakeContentLayerClient fake_content_layer_client_; 1014 1015 bool scroll_destroy_whole_tree_; 1016}; 1017 1018TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyLayer) { 1019 RunTest(true, false, false); 1020} 1021 1022TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) { 1023 scroll_destroy_whole_tree_ = true; 1024 RunTest(true, false, false); 1025} 1026 1027} // namespace 1028} // namespace cc 1029