Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp

Issue 2911463002: Unify the calculation of main thread offset of sticky element (Closed)
Patch Set: Bug fix Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/LocalFrameView.h" 7 #include "core/frame/LocalFrameView.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"
(...skipping 1458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 ToLayoutBoxModelObject(child->GetLayoutObject())->Layer(); 1469 ToLayoutBoxModelObject(child->GetLayoutObject())->Layer();
1470 ASSERT_TRUE(child_paint_layer); 1470 ASSERT_TRUE(child_paint_layer);
1471 CompositedLayerMapping* child_mapping = 1471 CompositedLayerMapping* child_mapping =
1472 child_paint_layer->GetCompositedLayerMapping(); 1472 child_paint_layer->GetCompositedLayerMapping();
1473 ASSERT_TRUE(child_mapping); 1473 ASSERT_TRUE(child_mapping);
1474 EXPECT_TRUE(child_mapping->AncestorClippingLayer()); 1474 EXPECT_TRUE(child_mapping->AncestorClippingLayer());
1475 EXPECT_FALSE(child_mapping->AncestorClippingLayer()->MaskLayer()); 1475 EXPECT_FALSE(child_mapping->AncestorClippingLayer()->MaskLayer());
1476 EXPECT_FALSE(child_mapping->AncestorClippingMaskLayer()); 1476 EXPECT_FALSE(child_mapping->AncestorClippingMaskLayer());
1477 } 1477 }
1478 1478
1479 TEST_P(CompositedLayerMappingTest, StickyPositionContentOffset) { 1479 TEST_P(CompositedLayerMappingTest, StickyPositionMainThreadOffset) {
1480 SetBodyInnerHTML(
1481 "<div style='width: 400px; height: 400px; overflow: auto; "
1482 "will-change: transform;' >"
1483 " <div id='sticky1' style='position: sticky; top: 0px; width: 100px; "
1484 "height: 100px; box-shadow: -5px -5px 5px 0 black; "
1485 "will-change: transform;'></div>"
1486 " <div style='height: 2000px;'></div>"
1487 "</div>"
1488
1489 "<div style='width: 400px; height: 400px; overflow: auto; "
1490 "will-change: transform;' >"
1491 " <div id='sticky2' style='position: sticky; top: 0px; width: 100px; "
1492 "height: 100px; will-change: transform;'>"
1493 " <div style='position: absolute; top: -50px; left: -50px; "
1494 "width: 5px; height: 5px; background: red;'></div></div>"
1495 " <div style='height: 2000px;'></div>"
1496 "</div>");
1497 GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling();
1498
1499 CompositedLayerMapping* sticky1 =
1500 ToLayoutBlock(GetLayoutObjectByElementId("sticky1"))
1501 ->Layer()
1502 ->GetCompositedLayerMapping();
1503 CompositedLayerMapping* sticky2 =
1504 ToLayoutBlock(GetLayoutObjectByElementId("sticky2"))
1505 ->Layer()
1506 ->GetCompositedLayerMapping();
1507
1508 // Box offsets the content by the combination of the shadow offset and blur
1509 // radius plus an additional pixel of anti-aliasing.
1510 ASSERT_TRUE(sticky1);
1511 WebLayerStickyPositionConstraint constraint1 =
1512 sticky1->MainGraphicsLayer()
1513 ->ContentLayer()
1514 ->Layer()
1515 ->StickyPositionConstraint();
1516 EXPECT_EQ(IntPoint(-11, -11),
1517 IntPoint(constraint1.parent_relative_sticky_box_offset));
1518
1519 // Since the nested div will be squashed into the same composited layer the
1520 // sticky element is offset by the nested element's offset.
1521 ASSERT_TRUE(sticky2);
1522 WebLayerStickyPositionConstraint constraint2 =
1523 sticky2->MainGraphicsLayer()
1524 ->ContentLayer()
1525 ->Layer()
1526 ->StickyPositionConstraint();
1527 EXPECT_EQ(IntPoint(-50, -50),
1528 IntPoint(constraint2.parent_relative_sticky_box_offset));
1529 }
1530
1531 TEST_P(CompositedLayerMappingTest, StickyPositionTableCellContentOffset) {
1532 SetBodyInnerHTML(
1533 "<style>body {height: 2000px; width: 2000px;} "
1534 "td, th { height: 50px; width: 50px; } "
1535 "table {border: none; }"
1536 "#scroller { overflow: auto; will-change: transform; height: 50px; }"
1537 "#sticky { position: sticky; left: 0; will-change: transform; }"
1538 "</style>"
1539 "<div id='scroller'><table cellspacing='0' cellpadding='0'>"
1540 " <thead><tr><td></td></tr></thead>"
1541 " <tr><td id='sticky'></td></tr>"
1542 "</table></div>");
1543 GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling();
1544
1545 CompositedLayerMapping* sticky =
1546 ToLayoutBlock(GetLayoutObjectByElementId("sticky"))
1547 ->Layer()
1548 ->GetCompositedLayerMapping();
1549
1550 ASSERT_TRUE(sticky);
1551 WebLayerStickyPositionConstraint constraint =
1552 sticky->MainGraphicsLayer()
1553 ->ContentLayer()
1554 ->Layer()
1555 ->StickyPositionConstraint();
1556 EXPECT_EQ(IntPoint(0, 50),
1557 IntPoint(constraint.parent_relative_sticky_box_offset));
1558 }
1559
1560 TEST_P(CompositedLayerMappingTest, StickyPositionEnclosingLayersContentOffset) {
1561 // Using backface-visibility: hidden causes the scroller to become composited
1562 // without creating a stacking context. This is important as enclosing layer
1563 // scroll correction works differently depending on whether you are in a
1564 // stacking context or not.
1565 SetBodyInnerHTML( 1480 SetBodyInnerHTML(
1566 "<style>.composited { backface-visibility: hidden; }" 1481 "<style>.composited { backface-visibility: hidden; }"
1567 "#scroller { overflow: auto; height: 200px; width: 200px; }" 1482 "#scroller { overflow: auto; height: 200px; width: 200px; }"
1568 ".container { height: 500px; }" 1483 ".container { height: 500px; }"
1569 ".innerPadding { height: 10px; }" 1484 ".innerPadding { height: 10px; }"
1570 "#sticky { position: sticky; top: 25px; height: 50px; }</style>" 1485 "#sticky { position: sticky; top: 25px; height: 50px; }</style>"
1571 "<div id='scroller' class='composited'>" 1486 "<div id='scroller' class='composited'>"
1572 " <div class='composited container'>" 1487 " <div class='composited container'>"
1573 " <div class='composited container'>" 1488 " <div class='composited container'>"
1574 " <div class='innerPadding'></div>" 1489 " <div class='innerPadding'></div>"
1575 " <div id='sticky' class='composited'></div>" 1490 " <div id='sticky' class='composited'></div>"
1576 " </div></div></div>"); 1491 " </div></div></div>");
1577 1492
1578 PaintLayer* sticky_layer = 1493 PaintLayer* sticky_layer =
1579 ToLayoutBox(GetLayoutObjectByElementId("sticky"))->Layer(); 1494 ToLayoutBox(GetLayoutObjectByElementId("sticky"))->Layer();
1580 CompositedLayerMapping* sticky_mapping = 1495 CompositedLayerMapping* sticky_mapping =
1581 sticky_layer->GetCompositedLayerMapping(); 1496 sticky_layer->GetCompositedLayerMapping();
1582 ASSERT_TRUE(sticky_mapping); 1497 ASSERT_TRUE(sticky_mapping);
1498 // Main thread offset for sticky should be "StickyTop - InnerPadding".
1499 EXPECT_EQ(IntPoint(0, 15), IntPoint(sticky_mapping->MainGraphicsLayer()
1500 ->ContentLayer()
1501 ->Layer()
1502 ->OffsetForStickyPosition()));
1583 1503
1584 WebLayerStickyPositionConstraint constraint = 1504 // Now scroll the page - this should increase the main thread offset.
1585 sticky_mapping->MainGraphicsLayer()
1586 ->ContentLayer()
1587 ->Layer()
1588 ->StickyPositionConstraint();
1589 EXPECT_EQ(IntPoint(0, 10),
1590 IntPoint(constraint.parent_relative_sticky_box_offset));
1591
1592 // Now scroll the page - this should not affect the parent-relative offset.
1593 LayoutBoxModelObject* scroller = 1505 LayoutBoxModelObject* scroller =
1594 ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); 1506 ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
1595 PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); 1507 PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
1596 scrollable_area->ScrollToAbsolutePosition( 1508 scrollable_area->ScrollToAbsolutePosition(
1597 FloatPoint(scrollable_area->ScrollPosition().X(), 100)); 1509 FloatPoint(scrollable_area->ScrollPosition().X(), 100));
1598 ASSERT_EQ(100.0, scrollable_area->ScrollPosition().Y()); 1510 ASSERT_EQ(100.0, scrollable_area->ScrollPosition().Y());
1599 1511
1600 sticky_layer->SetNeedsCompositingInputsUpdate(); 1512 sticky_layer->SetNeedsCompositingInputsUpdate();
1601 EXPECT_TRUE(sticky_layer->NeedsCompositingInputsUpdate()); 1513 EXPECT_TRUE(sticky_layer->NeedsCompositingInputsUpdate());
1602 GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling(); 1514 GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling();
1603 EXPECT_FALSE(sticky_layer->NeedsCompositingInputsUpdate()); 1515 EXPECT_FALSE(sticky_layer->NeedsCompositingInputsUpdate());
1604 1516
1605 constraint = sticky_mapping->MainGraphicsLayer() 1517 EXPECT_EQ(IntPoint(0, 115), IntPoint(sticky_mapping->MainGraphicsLayer()
1606 ->ContentLayer() 1518 ->ContentLayer()
1607 ->Layer() 1519 ->Layer()
1608 ->StickyPositionConstraint(); 1520 ->OffsetForStickyPosition()));
1609 EXPECT_EQ(IntPoint(0, 10),
1610 IntPoint(constraint.parent_relative_sticky_box_offset));
1611 }
1612
1613 TEST_P(CompositedLayerMappingTest,
1614 StickyPositionEnclosingLayersWithStackingContextContentOffset) {
1615 // Using will-change: transform causes the scroller to become a stacking
1616 // context. This changes how its descendant layers interact with it; they no
1617 // longer have a scrollParent and instead just refer to it only as their
1618 // ancestorOverflowLayer.
1619 SetBodyInnerHTML(
1620 "<style>.composited { will-change: transform; }"
1621 "#scroller { overflow: auto; height: 200px; width: 200px; }"
1622 ".container { height: 500px; }"
1623 ".innerPadding { height: 10px; }"
1624 "#sticky { position: sticky; top: 25px; height: 50px; }</style>"
1625 "<div id='scroller' class='composited'>"
1626 " <div class='composited container'>"
1627 " <div class='composited container'>"
1628 " <div class='innerPadding'></div>"
1629 " <div id='sticky' class='composited'></div>"
1630 " </div></div></div>");
1631
1632 PaintLayer* sticky_layer =
1633 ToLayoutBox(GetLayoutObjectByElementId("sticky"))->Layer();
1634 CompositedLayerMapping* sticky_mapping =
1635 sticky_layer->GetCompositedLayerMapping();
1636 ASSERT_TRUE(sticky_mapping);
1637
1638 WebLayerStickyPositionConstraint constraint =
1639 sticky_mapping->MainGraphicsLayer()
1640 ->ContentLayer()
1641 ->Layer()
1642 ->StickyPositionConstraint();
1643 EXPECT_EQ(IntPoint(0, 10),
1644 IntPoint(constraint.parent_relative_sticky_box_offset));
1645
1646 // Now scroll the page - this should not affect the parent-relative offset.
1647 LayoutBoxModelObject* scroller =
1648 ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
1649 PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
1650 scrollable_area->ScrollToAbsolutePosition(
1651 FloatPoint(scrollable_area->ScrollPosition().X(), 100));
1652 ASSERT_EQ(100.0, scrollable_area->ScrollPosition().Y());
1653
1654 sticky_layer->SetNeedsCompositingInputsUpdate();
1655 EXPECT_TRUE(sticky_layer->NeedsCompositingInputsUpdate());
1656 GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling();
1657 EXPECT_FALSE(sticky_layer->NeedsCompositingInputsUpdate());
1658
1659 constraint = sticky_mapping->MainGraphicsLayer()
1660 ->ContentLayer()
1661 ->Layer()
1662 ->StickyPositionConstraint();
1663 EXPECT_EQ(IntPoint(0, 10),
1664 IntPoint(constraint.parent_relative_sticky_box_offset));
1665 } 1521 }
1666 1522
1667 TEST_P(CompositedLayerMappingTest, StickyPositionNotSquashed) { 1523 TEST_P(CompositedLayerMappingTest, StickyPositionNotSquashed) {
1668 SetBodyInnerHTML( 1524 SetBodyInnerHTML(
1669 "<style>" 1525 "<style>"
1670 "#scroller { overflow: auto; height: 200px; }" 1526 "#scroller { overflow: auto; height: 200px; }"
1671 "#sticky1, #sticky2, #sticky3 {position: sticky; top: 0; width: 50px;" 1527 "#sticky1, #sticky2, #sticky3 {position: sticky; top: 0; width: 50px;"
1672 " height: 50px; background: rgba(0, 128, 0, 0.5);}" 1528 " height: 50px; background: rgba(0, 128, 0, 0.5);}"
1673 "#sticky1 {backface-visibility: hidden;}" 1529 "#sticky1 {backface-visibility: hidden;}"
1674 ".spacer {height: 2000px;}" 1530 ".spacer {height: 2000px;}"
(...skipping 23 matching lines...) Expand all
1698 GetDocument().View()->UpdateAllLifecyclePhases(); 1554 GetDocument().View()->UpdateAllLifecyclePhases();
1699 1555
1700 // Now that sticky2 and sticky3 overlap sticky1 they will be promoted, but 1556 // Now that sticky2 and sticky3 overlap sticky1 they will be promoted, but
1701 // they should not be squashed into the same layer because they scroll with 1557 // they should not be squashed into the same layer because they scroll with
1702 // respect to each other. 1558 // respect to each other.
1703 EXPECT_EQ(kPaintsIntoOwnBacking, sticky1->GetCompositingState()); 1559 EXPECT_EQ(kPaintsIntoOwnBacking, sticky1->GetCompositingState());
1704 EXPECT_EQ(kPaintsIntoOwnBacking, sticky2->GetCompositingState()); 1560 EXPECT_EQ(kPaintsIntoOwnBacking, sticky2->GetCompositingState());
1705 EXPECT_EQ(kPaintsIntoOwnBacking, sticky3->GetCompositingState()); 1561 EXPECT_EQ(kPaintsIntoOwnBacking, sticky3->GetCompositingState());
1706 } 1562 }
1707 1563
1708 TEST_P(CompositedLayerMappingTest, StickyPositionNestedStickyContentOffset) {
1709 SetBodyInnerHTML(
1710 "<style>.composited { will-change: transform; }"
1711 "#scroller { overflow: auto; height: 200px; width: 200px; }"
1712 ".container { height: 500px; }"
1713 "#outerSticky { position: sticky; top: 0; height: 100px; }"
1714 "#middleSticky { position: sticky; top: 10px; height: 50px; }"
1715 "#innerSticky { position: sticky; top: 25px; height: 25px; }</style>"
1716 "<div id='scroller' class='composited'>"
1717 " <div style='height: 50px'></div>"
1718 " <div class='composited container'>"
1719 " <div style='height: 10px;'></div>"
1720 " <div id='outerSticky' class='composited'>"
1721 " <div id='middleSticky' class='composited'>"
1722 " <div style='height: 5px;'></div>"
1723 " <div id='innerSticky' class='composited'></div>"
1724 " </div>"
1725 " </div>"
1726 " </div>"
1727 "</div>");
1728
1729 PaintLayer* outer_sticky =
1730 ToLayoutBox(GetLayoutObjectByElementId("outerSticky"))->Layer();
1731 PaintLayer* middle_sticky =
1732 ToLayoutBox(GetLayoutObjectByElementId("middleSticky"))->Layer();
1733 PaintLayer* inner_sticky =
1734 ToLayoutBox(GetLayoutObjectByElementId("innerSticky"))->Layer();
1735
1736 WebLayerStickyPositionConstraint outer_sticky_constraint =
1737 outer_sticky->GetCompositedLayerMapping()
1738 ->MainGraphicsLayer()
1739 ->ContentLayer()
1740 ->Layer()
1741 ->StickyPositionConstraint();
1742 WebLayerStickyPositionConstraint middle_sticky_constraint =
1743 middle_sticky->GetCompositedLayerMapping()
1744 ->MainGraphicsLayer()
1745 ->ContentLayer()
1746 ->Layer()
1747 ->StickyPositionConstraint();
1748 WebLayerStickyPositionConstraint inner_sticky_constraint =
1749 inner_sticky->GetCompositedLayerMapping()
1750 ->MainGraphicsLayer()
1751 ->ContentLayer()
1752 ->Layer()
1753 ->StickyPositionConstraint();
1754
1755 EXPECT_EQ(
1756 IntPoint(0, 10),
1757 IntPoint(outer_sticky_constraint.parent_relative_sticky_box_offset));
1758 EXPECT_EQ(
1759 IntPoint(0, 0),
1760 IntPoint(middle_sticky_constraint.parent_relative_sticky_box_offset));
1761 EXPECT_EQ(
1762 IntPoint(0, 5),
1763 IntPoint(inner_sticky_constraint.parent_relative_sticky_box_offset));
1764
1765 // Scroll the content to engage the sticky elements.
1766 LayoutBoxModelObject* scroller =
1767 ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
1768 PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
1769 scrollable_area->ScrollToAbsolutePosition(
1770 FloatPoint(scrollable_area->ScrollPosition().X(), 110));
1771 ASSERT_EQ(110.0, scrollable_area->ScrollPosition().Y());
1772
1773 outer_sticky->SetNeedsCompositingInputsUpdate();
1774 middle_sticky->SetNeedsCompositingInputsUpdate();
1775 inner_sticky->SetNeedsCompositingInputsUpdate();
1776
1777 GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling();
1778
1779 outer_sticky_constraint = outer_sticky->GetCompositedLayerMapping()
1780 ->MainGraphicsLayer()
1781 ->ContentLayer()
1782 ->Layer()
1783 ->StickyPositionConstraint();
1784 middle_sticky_constraint = middle_sticky->GetCompositedLayerMapping()
1785 ->MainGraphicsLayer()
1786 ->ContentLayer()
1787 ->Layer()
1788 ->StickyPositionConstraint();
1789 inner_sticky_constraint = inner_sticky->GetCompositedLayerMapping()
1790 ->MainGraphicsLayer()
1791 ->ContentLayer()
1792 ->Layer()
1793 ->StickyPositionConstraint();
1794
1795 // After scrolling and despite ancestor sticky changes, the offset relative to
1796 // the parent layer should remain constant.
1797 EXPECT_EQ(
1798 IntPoint(0, 10),
1799 IntPoint(outer_sticky_constraint.parent_relative_sticky_box_offset));
1800 EXPECT_EQ(
1801 IntPoint(0, 0),
1802 IntPoint(middle_sticky_constraint.parent_relative_sticky_box_offset));
1803 EXPECT_EQ(
1804 IntPoint(0, 5),
1805 IntPoint(inner_sticky_constraint.parent_relative_sticky_box_offset));
1806 }
1807
1808 } // namespace blink 1564 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698