OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/trees/layer_tree_host_impl.h" | 5 #include "cc/trees/layer_tree_host_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 | 566 |
567 // We should still be scrolling, because the scrolled layer also exists in the | 567 // We should still be scrolling, because the scrolled layer also exists in the |
568 // new tree. | 568 // new tree. |
569 gfx::Vector2d scroll_delta(0, 10); | 569 gfx::Vector2d scroll_delta(0, 10); |
570 host_impl_->ScrollBy(gfx::Point(), scroll_delta); | 570 host_impl_->ScrollBy(gfx::Point(), scroll_delta); |
571 host_impl_->ScrollEnd(); | 571 host_impl_->ScrollEnd(); |
572 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); | 572 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); |
573 ExpectContains(*scroll_info, scroll_layer->id(), scroll_delta); | 573 ExpectContains(*scroll_info, scroll_layer->id(), scroll_delta); |
574 } | 574 } |
575 | 575 |
576 TEST_F(LayerTreeHostImplTest, WheelEventHandlers) { | 576 TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) { |
577 SetupScrollAndContentsLayers(gfx::Size(100, 100)); | 577 SetupScrollAndContentsLayers(gfx::Size(100, 100)); |
578 host_impl_->SetViewportSize(gfx::Size(50, 50)); | 578 host_impl_->SetViewportSize(gfx::Size(50, 50)); |
579 DrawFrame(); | 579 DrawFrame(); |
580 LayerImpl* root = host_impl_->active_tree()->root_layer(); | 580 LayerImpl* root = host_impl_->active_tree()->root_layer(); |
581 | 581 |
| 582 // With registered event handlers, wheel scrolls don't necessarily |
| 583 // have to go to the main thread. |
582 root->SetHaveWheelEventHandlers(true); | 584 root->SetHaveWheelEventHandlers(true); |
| 585 EXPECT_EQ(InputHandler::ScrollStarted, |
| 586 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); |
| 587 host_impl_->ScrollEnd(); |
583 | 588 |
584 // With registered event handlers, wheel scrolls have to go to the main | 589 // But typically the scroll-blocks-on mode will require them to. |
585 // thread. | 590 root->SetScrollBlocksOn(ScrollBlocksOnWheelEvent | ScrollBlocksOnStartTouch); |
586 EXPECT_EQ(InputHandler::ScrollOnMainThread, | 591 EXPECT_EQ(InputHandler::ScrollOnMainThread, |
587 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); | 592 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); |
588 | 593 |
589 // But gesture scrolls can still be handled. | 594 // But gesture scrolls can still be handled. |
590 EXPECT_EQ(InputHandler::ScrollStarted, | 595 EXPECT_EQ(InputHandler::ScrollStarted, |
591 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); | 596 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); |
| 597 host_impl_->ScrollEnd(); |
| 598 |
| 599 // And if the handlers go away, wheel scrolls can again be processed |
| 600 // on impl (despite the scroll-blocks-on mode). |
| 601 root->SetHaveWheelEventHandlers(false); |
| 602 EXPECT_EQ(InputHandler::ScrollStarted, |
| 603 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); |
| 604 host_impl_->ScrollEnd(); |
| 605 } |
| 606 |
| 607 TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) { |
| 608 LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100)); |
| 609 host_impl_->SetViewportSize(gfx::Size(50, 50)); |
| 610 DrawFrame(); |
| 611 LayerImpl* root = host_impl_->active_tree()->root_layer(); |
| 612 |
| 613 LayerImpl* child = 0; |
| 614 { |
| 615 scoped_ptr<LayerImpl> child_layer = |
| 616 LayerImpl::Create(host_impl_->active_tree(), 6); |
| 617 child = child_layer.get(); |
| 618 child_layer->SetDrawsContent(true); |
| 619 child_layer->SetPosition(gfx::PointF(0, 20)); |
| 620 child_layer->SetBounds(gfx::Size(50, 50)); |
| 621 child_layer->SetContentBounds(gfx::Size(50, 50)); |
| 622 scroll->AddChild(child_layer.Pass()); |
| 623 } |
| 624 |
| 625 // Touch handler regions determine whether touch events block scroll. |
| 626 root->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100)); |
| 627 EXPECT_FALSE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 10))); |
| 628 root->SetScrollBlocksOn(ScrollBlocksOnStartTouch | ScrollBlocksOnWheelEvent); |
| 629 EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 10))); |
| 630 |
| 631 // But they don't influence the actual handling of the scroll gestures. |
| 632 EXPECT_EQ(InputHandler::ScrollStarted, |
| 633 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); |
| 634 host_impl_->ScrollEnd(); |
| 635 |
| 636 // It's the union of scroll-blocks-on mode bits across all layers in the |
| 637 // scroll paret chain that matters. |
| 638 EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 30))); |
| 639 root->SetScrollBlocksOn(ScrollBlocksOnNone); |
| 640 EXPECT_FALSE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 30))); |
| 641 child->SetScrollBlocksOn(ScrollBlocksOnStartTouch); |
| 642 EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 30))); |
| 643 } |
| 644 |
| 645 TEST_F(LayerTreeHostImplTest, ScrollBlocksOnScrollEventHandlers) { |
| 646 SetupScrollAndContentsLayers(gfx::Size(100, 100)); |
| 647 host_impl_->SetViewportSize(gfx::Size(50, 50)); |
| 648 DrawFrame(); |
| 649 LayerImpl* root = host_impl_->active_tree()->root_layer(); |
| 650 |
| 651 // With registered scroll handlers, scrolls don't generally have to go |
| 652 // to the main thread. |
| 653 root->SetHaveScrollEventHandlers(true); |
| 654 EXPECT_EQ(InputHandler::ScrollStarted, |
| 655 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); |
| 656 host_impl_->ScrollEnd(); |
| 657 |
| 658 // Even the default scroll blocks on mode doesn't require this. |
| 659 root->SetScrollBlocksOn(ScrollBlocksOnWheelEvent | ScrollBlocksOnStartTouch); |
| 660 EXPECT_EQ(InputHandler::ScrollStarted, |
| 661 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); |
| 662 host_impl_->ScrollEnd(); |
| 663 |
| 664 // But the page can opt in to blocking on scroll event handlers. |
| 665 root->SetScrollBlocksOn(ScrollBlocksOnScrollEvent); |
| 666 EXPECT_EQ(InputHandler::ScrollOnMainThread, |
| 667 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); |
| 668 |
| 669 // Gesture and Wheel scrolls behave identically in this regard. |
| 670 EXPECT_EQ(InputHandler::ScrollOnMainThread, |
| 671 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); |
| 672 |
| 673 // And if the handlers go away, scrolls can again be processed on impl |
| 674 // (despite the scroll-blocks-on mode). |
| 675 root->SetHaveScrollEventHandlers(false); |
| 676 EXPECT_EQ(InputHandler::ScrollStarted, |
| 677 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); |
| 678 host_impl_->ScrollEnd(); |
| 679 } |
| 680 |
| 681 TEST_F(LayerTreeHostImplTest, ScrollBlocksOnLayerTopology) { |
| 682 host_impl_->SetViewportSize(gfx::Size(50, 50)); |
| 683 |
| 684 // Create a normal scrollable root layer |
| 685 LayerImpl* root_scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100)); |
| 686 LayerImpl* root_child = root_scroll->children()[0]; |
| 687 LayerImpl* root = host_impl_->active_tree()->root_layer(); |
| 688 DrawFrame(); |
| 689 |
| 690 // Create two child scrollable layers |
| 691 LayerImpl* child1 = 0; |
| 692 { |
| 693 scoped_ptr<LayerImpl> scrollable_child_clip_1 = |
| 694 LayerImpl::Create(host_impl_->active_tree(), 6); |
| 695 scoped_ptr<LayerImpl> scrollable_child_1 = CreateScrollableLayer( |
| 696 7, gfx::Size(10, 10), scrollable_child_clip_1.get()); |
| 697 child1 = scrollable_child_1.get(); |
| 698 scrollable_child_1->SetPosition(gfx::Point(5, 5)); |
| 699 scrollable_child_1->SetHaveWheelEventHandlers(true); |
| 700 scrollable_child_1->SetHaveScrollEventHandlers(true); |
| 701 scrollable_child_clip_1->AddChild(scrollable_child_1.Pass()); |
| 702 root_child->AddChild(scrollable_child_clip_1.Pass()); |
| 703 } |
| 704 |
| 705 LayerImpl* child2 = 0; |
| 706 { |
| 707 scoped_ptr<LayerImpl> scrollable_child_clip_2 = |
| 708 LayerImpl::Create(host_impl_->active_tree(), 8); |
| 709 scoped_ptr<LayerImpl> scrollable_child_2 = CreateScrollableLayer( |
| 710 9, gfx::Size(10, 10), scrollable_child_clip_2.get()); |
| 711 child2 = scrollable_child_2.get(); |
| 712 scrollable_child_2->SetPosition(gfx::Point(5, 20)); |
| 713 scrollable_child_2->SetHaveWheelEventHandlers(true); |
| 714 scrollable_child_2->SetHaveScrollEventHandlers(true); |
| 715 scrollable_child_clip_2->AddChild(scrollable_child_2.Pass()); |
| 716 root_child->AddChild(scrollable_child_clip_2.Pass()); |
| 717 } |
| 718 |
| 719 // Scroll-blocks-on on a layer affects scrolls that hit that layer. |
| 720 EXPECT_EQ(InputHandler::ScrollStarted, |
| 721 host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture)); |
| 722 host_impl_->ScrollEnd(); |
| 723 child1->SetScrollBlocksOn(ScrollBlocksOnScrollEvent); |
| 724 EXPECT_EQ(InputHandler::ScrollOnMainThread, |
| 725 host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture)); |
| 726 |
| 727 // But not those that hit only other layers. |
| 728 EXPECT_EQ(InputHandler::ScrollStarted, |
| 729 host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Gesture)); |
| 730 host_impl_->ScrollEnd(); |
| 731 |
| 732 // It's the union of bits set across the scroll ancestor chain that matters. |
| 733 EXPECT_EQ(InputHandler::ScrollStarted, |
| 734 host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Gesture)); |
| 735 host_impl_->ScrollEnd(); |
| 736 EXPECT_EQ(InputHandler::ScrollStarted, |
| 737 host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Wheel)); |
| 738 host_impl_->ScrollEnd(); |
| 739 root->SetScrollBlocksOn(ScrollBlocksOnWheelEvent); |
| 740 EXPECT_EQ(InputHandler::ScrollStarted, |
| 741 host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Gesture)); |
| 742 host_impl_->ScrollEnd(); |
| 743 EXPECT_EQ(InputHandler::ScrollOnMainThread, |
| 744 host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Wheel)); |
| 745 child2->SetScrollBlocksOn(ScrollBlocksOnScrollEvent); |
| 746 EXPECT_EQ(InputHandler::ScrollOnMainThread, |
| 747 host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Wheel)); |
| 748 EXPECT_EQ(InputHandler::ScrollOnMainThread, |
| 749 host_impl_->ScrollBegin(gfx::Point(10, 25), InputHandler::Gesture)); |
592 } | 750 } |
593 | 751 |
594 TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) { | 752 TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) { |
595 SetupScrollAndContentsLayers(gfx::Size(100, 100)); | 753 SetupScrollAndContentsLayers(gfx::Size(100, 100)); |
596 host_impl_->SetViewportSize(gfx::Size(50, 50)); | 754 host_impl_->SetViewportSize(gfx::Size(50, 50)); |
597 DrawFrame(); | 755 DrawFrame(); |
598 | 756 |
599 // Ignore the fling since no layer is being scrolled | 757 // Ignore the fling since no layer is being scrolled |
600 EXPECT_EQ(InputHandler::ScrollIgnored, | 758 EXPECT_EQ(InputHandler::ScrollIgnored, |
601 host_impl_->FlingScrollBegin()); | 759 host_impl_->FlingScrollBegin()); |
(...skipping 7451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8053 // surface. | 8211 // surface. |
8054 EXPECT_EQ(0, num_lost_surfaces_); | 8212 EXPECT_EQ(0, num_lost_surfaces_); |
8055 host_impl_->DidLoseOutputSurface(); | 8213 host_impl_->DidLoseOutputSurface(); |
8056 EXPECT_EQ(1, num_lost_surfaces_); | 8214 EXPECT_EQ(1, num_lost_surfaces_); |
8057 host_impl_->DidLoseOutputSurface(); | 8215 host_impl_->DidLoseOutputSurface(); |
8058 EXPECT_LE(1, num_lost_surfaces_); | 8216 EXPECT_LE(1, num_lost_surfaces_); |
8059 } | 8217 } |
8060 | 8218 |
8061 } // namespace | 8219 } // namespace |
8062 } // namespace cc | 8220 } // namespace cc |
OLD | NEW |