OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "core/layout/compositing/CompositedLayerMapping.h" | 5 #include "core/layout/compositing/CompositedLayerMapping.h" |
6 | 6 |
7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
8 #include "core/layout/LayoutBoxModelObject.h" | 8 #include "core/layout/LayoutBoxModelObject.h" |
9 #include "core/layout/LayoutTestHelper.h" | 9 #include "core/layout/LayoutTestHelper.h" |
10 #include "core/layout/api/LayoutViewItem.h" | 10 #include "core/layout/api/LayoutViewItem.h" |
| 11 #include "core/page/scrolling/TopDocumentRootScrollerController.h" |
11 #include "core/paint/PaintLayer.h" | 12 #include "core/paint/PaintLayer.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
13 | 14 |
14 namespace blink { | 15 namespace blink { |
15 | 16 |
16 class CompositedLayerMappingTest : public RenderingTest { | 17 class CompositedLayerMappingTest : public RenderingTest { |
17 public: | 18 public: |
18 CompositedLayerMappingTest() | 19 CompositedLayerMappingTest() |
19 : RenderingTest(SingleChildFrameLoaderClient::create()) | 20 : RenderingTest(SingleChildFrameLoaderClient::create()) |
20 { } | 21 { } |
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 Element* negativeCompositedChild = document().getElementById("negative-compo
sited-child"); | 640 Element* negativeCompositedChild = document().getElementById("negative-compo
sited-child"); |
640 negativeCompositedChild->parentNode()->removeChild(negativeCompositedChild); | 641 negativeCompositedChild->parentNode()->removeChild(negativeCompositedChild); |
641 document().view()->updateAllLifecyclePhases(); | 642 document().view()->updateAllLifecyclePhases(); |
642 | 643 |
643 mapping = toLayoutBlock(getLayoutObjectByElementId("container"))->layer()->c
ompositedLayerMapping(); | 644 mapping = toLayoutBlock(getLayoutObjectByElementId("container"))->layer()->c
ompositedLayerMapping(); |
644 ASSERT_TRUE(mapping->scrollingContentsLayer()); | 645 ASSERT_TRUE(mapping->scrollingContentsLayer()); |
645 EXPECT_EQ(static_cast<GraphicsLayerPaintingPhase>(GraphicsLayerPaintOverflow
Contents | GraphicsLayerPaintCompositedScroll | GraphicsLayerPaintForeground), m
apping->scrollingContentsLayer()->paintingPhase()); | 646 EXPECT_EQ(static_cast<GraphicsLayerPaintingPhase>(GraphicsLayerPaintOverflow
Contents | GraphicsLayerPaintCompositedScroll | GraphicsLayerPaintForeground), m
apping->scrollingContentsLayer()->paintingPhase()); |
646 EXPECT_FALSE(mapping->foregroundLayer()); | 647 EXPECT_FALSE(mapping->foregroundLayer()); |
647 } | 648 } |
648 | 649 |
| 650 // Make sure that clipping layers are removed or their masking bit turned off |
| 651 // when they're an ancestor of the root scroller element. |
| 652 TEST_F(CompositedLayerMappingTest, RootScrollerAncestorsNotClipped) |
| 653 { |
| 654 NonThrowableExceptionState nonThrow; |
| 655 |
| 656 // TODO(bokan): Avoid cast once follow-up patch separates TDRSC from |
| 657 // RootScrollerController. |
| 658 TopDocumentRootScrollerController* rootScrollerController = |
| 659 (TopDocumentRootScrollerController*)document().rootScrollerController(); |
| 660 |
| 661 setBodyInnerHTML( |
| 662 // The container DIV is composited with scrolling contents and a |
| 663 // non-composited parent that clips it. |
| 664 "<div id='clip' style='overflow: hidden; width: 200px; height: 200px; po
sition: absolute; left: 0px; top: 0px;'>" |
| 665 " <div id='container' style='transform: translateZ(0); overflow: scro
ll; width: 300px; height: 300px'>" |
| 666 " <div style='width: 2000px; height: 2000px;'>lorem ipsum</div>" |
| 667 " <div id='innerScroller' style='width: 800px; height: 600px; lef
t: 0px; top: 0px; position: absolute; overflow: scroll'>" |
| 668 " <div style='height: 2000px; width: 2000px'></div>" |
| 669 " </div>" |
| 670 " </div>" |
| 671 "</div>" |
| 672 |
| 673 // The container DIV is composited with scrolling contents and a |
| 674 // composited parent that clips it. |
| 675 "<div id='clip2' style='transform: translateZ(0); position: absolute; le
ft: 0px; top: 0px; overflow: hidden; width: 200px; height: 200px'>" |
| 676 " <div id='container2' style='transform: translateZ(0); overflow: scr
oll; width: 300px; height: 300px'>" |
| 677 " <div style='width: 2000px; height: 2000px;'>lorem ipsum</div>" |
| 678 " <div id='innerScroller2' style='width: 800px; height: 600px; le
ft: 0px; top: 0px; position: absolute; overflow: scroll'>" |
| 679 " <div style='height: 2000px; width: 2000px'></div>" |
| 680 " </div>" |
| 681 " </div>" |
| 682 "</div>" |
| 683 |
| 684 // The container DIV is composited without scrolling contents but |
| 685 // composited children that it clips. |
| 686 "<div id='container3' style='translateZ(0); position: absolute; left: 0p
x; top: 0px; z-index: 1; overflow: hidden; width: 300px; height: 300px'>" |
| 687 " <div style='transform: translateZ(0); z-index: -1; width: 2000px; h
eight: 2000px;'>lorem ipsum</div>" |
| 688 " <div id='innerScroller3' style='width: 800px; height: 600px; le
ft: 0px; top: 0px; position: absolute; overflow: scroll'>" |
| 689 " <div style='height: 2000px; width: 2000px'></div>" |
| 690 " </div>" |
| 691 "</div>" |
| 692 ); |
| 693 |
| 694 CompositedLayerMapping* mapping = toLayoutBlock(getLayoutObjectByElementId("
container"))->layer()->compositedLayerMapping(); |
| 695 CompositedLayerMapping* mapping2 = toLayoutBlock(getLayoutObjectByElementId(
"container2"))->layer()->compositedLayerMapping(); |
| 696 CompositedLayerMapping* mapping3 = toLayoutBlock(getLayoutObjectByElementId(
"container3"))->layer()->compositedLayerMapping(); |
| 697 Element* innerScroller = document().getElementById("innerScroller"); |
| 698 Element* innerScroller2 = document().getElementById("innerScroller2"); |
| 699 Element* innerScroller3 = document().getElementById("innerScroller3"); |
| 700 |
| 701 ASSERT_TRUE(mapping); |
| 702 ASSERT_TRUE(mapping2); |
| 703 ASSERT_TRUE(mapping3); |
| 704 ASSERT_TRUE(innerScroller); |
| 705 ASSERT_TRUE(innerScroller2); |
| 706 ASSERT_TRUE(innerScroller3); |
| 707 |
| 708 // Since there's no need to composite the clip and we prefer LCD text, the |
| 709 // mapping should create an ancestorClippingLayer. |
| 710 ASSERT_TRUE(mapping->scrollingLayer()); |
| 711 ASSERT_TRUE(mapping->ancestorClippingLayer()); |
| 712 |
| 713 // Since the clip has a transform it should be composited so there's no |
| 714 // need for an ancestor clipping layer. |
| 715 ASSERT_TRUE(mapping2->scrollingLayer()); |
| 716 |
| 717 // The third <div> should have a clipping layer since it's composited and cl
ips |
| 718 // composited children. |
| 719 ASSERT_TRUE(mapping3->clippingLayer()); |
| 720 |
| 721 // All scrolling and clipping layers should have masksToBounds set on them. |
| 722 { |
| 723 EXPECT_TRUE(mapping->scrollingLayer()->platformLayer()->masksToBounds())
; |
| 724 EXPECT_TRUE(mapping->ancestorClippingLayer()->platformLayer()->masksToBo
unds()); |
| 725 EXPECT_TRUE(mapping2->scrollingLayer()->platformLayer()->masksToBounds()
); |
| 726 EXPECT_TRUE(mapping3->clippingLayer()->platformLayer()->masksToBounds())
; |
| 727 } |
| 728 |
| 729 // Set the inner scroller in the first container as the root scroller. Its |
| 730 // clipping layer should be removed and the scrolling layer should not |
| 731 // mask. |
| 732 { |
| 733 document().setRootScroller(innerScroller, nonThrow); |
| 734 document().view()->updateAllLifecyclePhases(); |
| 735 ASSERT_EQ(innerScroller, rootScrollerController->globalRootScroller()); |
| 736 |
| 737 EXPECT_FALSE(mapping->ancestorClippingLayer()); |
| 738 EXPECT_FALSE(mapping->scrollingLayer()->platformLayer()->masksToBounds()
); |
| 739 } |
| 740 |
| 741 // Set the inner scroller in the second container as the root scroller. Its |
| 742 // scrolling layer should no longer mask. The clipping and scrolling layers |
| 743 // on the first container should now reset back. |
| 744 { |
| 745 document().setRootScroller(innerScroller2, nonThrow); |
| 746 document().view()->updateAllLifecyclePhases(); |
| 747 ASSERT_EQ(innerScroller2, rootScrollerController->globalRootScroller()); |
| 748 |
| 749 EXPECT_TRUE(mapping->ancestorClippingLayer()); |
| 750 EXPECT_TRUE(mapping->ancestorClippingLayer()->platformLayer()->masksToBo
unds()); |
| 751 EXPECT_TRUE(mapping->scrollingLayer()->platformLayer()->masksToBounds())
; |
| 752 |
| 753 EXPECT_FALSE(mapping2->scrollingLayer()->platformLayer()->masksToBounds(
)); |
| 754 } |
| 755 |
| 756 // Set the inner scroller in the third container as the root scroller. Its |
| 757 // clipping layer should be removed. |
| 758 { |
| 759 document().setRootScroller(innerScroller3, nonThrow); |
| 760 document().view()->updateAllLifecyclePhases(); |
| 761 ASSERT_EQ(innerScroller3, rootScrollerController->globalRootScroller()); |
| 762 |
| 763 EXPECT_TRUE(mapping2->scrollingLayer()->platformLayer()->masksToBounds()
); |
| 764 |
| 765 EXPECT_FALSE(mapping3->clippingLayer()); |
| 766 } |
| 767 |
| 768 // Unset the root scroller. The clipping layer on the third container should |
| 769 // be restored. |
| 770 { |
| 771 document().setRootScroller(nullptr, nonThrow); |
| 772 document().view()->updateAllLifecyclePhases(); |
| 773 ASSERT_EQ(document().documentElement(), rootScrollerController->globalRo
otScroller()); |
| 774 |
| 775 EXPECT_TRUE(mapping3->clippingLayer()); |
| 776 EXPECT_TRUE(mapping3->clippingLayer()->platformLayer()->masksToBounds())
; |
| 777 } |
| 778 } |
| 779 |
649 } // namespace blink | 780 } // namespace blink |
OLD | NEW |