Changeset 246845 in webkit


Ignore:
Timestamp:
Jun 26, 2019 12:12:40 PM (5 years ago)
Author:
Simon Fraser
Message:

Incorrect clippping with overflow:scroll inside oveflow:hidden with border-radius
https://bugs.webkit.org/show_bug.cgi?id=199135
rdar://problem/51882383

Reviewed by Zalan Bujtas.
Source/WebCore:

In some cases the geometry of the shape mask layer added to m_childContainmentLayer, for
border-radius, was incorrect. GraphicsLayerCA::updateClippingStrategy() treated
the rounded rect as if it were in renderer coordinates, but to match the other geometry
on GraphicsLayer, it should in GraphicsLayer coordinates, so we need to offset by
clipLayer->offsetFromRenderer().

In addition, RenderLayerBacking::updateChildClippingStrategy() is called from
the updateConfiguration(), which is before we've set offsetFromRenderer() on the clipLayer.
This first call is really to find out whether the platform supports this rounded rect
as a shape mask.

So we need to call setMasksToBoundsRect() a second time in RenderLayerBacking::updateGeometry()
after clipLayers's offsetFromRenderer() has been computed.

Test: compositing/scrolling/async-overflow-scrolling/border-radius-on-scroll-container.html

  • platform/graphics/ca/GraphicsLayerCA.cpp:

(WebCore::GraphicsLayerCA::updateClippingStrategy):

  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::createPrimaryGraphicsLayer):
(WebCore::RenderLayerBacking::updateDescendantClippingLayer):
(WebCore::RenderLayerBacking::updateChildClippingStrategy):

LayoutTests:

  • compositing/scrolling/async-overflow-scrolling/border-radius-on-scroll-container-expected.html: Added.
  • compositing/scrolling/async-overflow-scrolling/border-radius-on-scroll-container.html: Added.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r246844 r246845  
     12019-06-26  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Incorrect clippping with overflow:scroll inside oveflow:hidden with border-radius
     4        https://bugs.webkit.org/show_bug.cgi?id=199135
     5        rdar://problem/51882383
     6
     7        Reviewed by Zalan Bujtas.
     8
     9        * compositing/scrolling/async-overflow-scrolling/border-radius-on-scroll-container-expected.html: Added.
     10        * compositing/scrolling/async-overflow-scrolling/border-radius-on-scroll-container.html: Added.
     11
    1122019-06-26  Antoine Quint  <graouts@apple.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r246844 r246845  
     12019-06-26  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Incorrect clippping with overflow:scroll inside oveflow:hidden with border-radius
     4        https://bugs.webkit.org/show_bug.cgi?id=199135
     5        rdar://problem/51882383
     6
     7        Reviewed by Zalan Bujtas.
     8       
     9        In some cases the geometry of the shape mask layer added to m_childContainmentLayer, for
     10        border-radius, was incorrect. GraphicsLayerCA::updateClippingStrategy() treated
     11        the rounded rect as if it were in renderer coordinates, but to match the other geometry
     12        on GraphicsLayer, it should in GraphicsLayer coordinates, so we need to offset by
     13        clipLayer->offsetFromRenderer().
     14       
     15        In addition, RenderLayerBacking::updateChildClippingStrategy() is called from
     16        the updateConfiguration(), which is before we've set offsetFromRenderer() on the clipLayer.
     17        This first call is really to find out whether the platform supports this rounded rect
     18        as a shape mask.
     19       
     20        So we need to call setMasksToBoundsRect() a second time in RenderLayerBacking::updateGeometry()
     21        after clipLayers's offsetFromRenderer() has been computed.
     22
     23        Test: compositing/scrolling/async-overflow-scrolling/border-radius-on-scroll-container.html
     24
     25        * platform/graphics/ca/GraphicsLayerCA.cpp:
     26        (WebCore::GraphicsLayerCA::updateClippingStrategy):
     27        * rendering/RenderLayerBacking.cpp:
     28        (WebCore::RenderLayerBacking::createPrimaryGraphicsLayer):
     29        (WebCore::RenderLayerBacking::updateDescendantClippingLayer):
     30        (WebCore::RenderLayerBacking::updateChildClippingStrategy):
     31
    1322019-06-26  Antoine Quint  <graouts@apple.com>
    233
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

    r246471 r246845  
    26032603    }
    26042604   
    2605     shapeMaskLayer->setPosition(roundedRect.rect().location() - offsetFromRenderer());
     2605    shapeMaskLayer->setPosition(roundedRect.rect().location());
    26062606    FloatRect shapeBounds({ }, roundedRect.rect().size());
    26072607    shapeMaskLayer->setBounds(shapeBounds);
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r246725 r246845  
    11731173        clipLayer->setOffsetFromRenderer(toLayoutSize(clippingBox.location() - snappedClippingGraphicsLayer.m_snapDelta));
    11741174
     1175        if ((renderer().style().clipPath() || renderer().style().hasBorderRadius()) && !m_childClippingMaskLayer) {
     1176            LayoutRect boxRect(LayoutPoint(), downcast<RenderBox>(renderer()).size());
     1177            FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
     1178            contentsClippingRect.move(LayoutSize(-clipLayer->offsetFromRenderer()));
     1179            clipLayer->setMasksToBoundsRect(contentsClippingRect);
     1180        }
     1181
    11751182        if (m_childClippingMaskLayer && !m_scrollContainerLayer) {
    11761183            m_childClippingMaskLayer->setSize(clipLayer->size());
     
    18691876    if (hasClippingLayer() && needsDescendantsClippingLayer) {
    18701877        if (is<RenderBox>(renderer()) && (renderer().style().clipPath() || renderer().style().hasBorderRadius())) {
     1878            auto* clipLayer = clippingLayer();
    18711879            LayoutRect boxRect(LayoutPoint(), downcast<RenderBox>(renderer()).size());
    1872             boxRect.move(contentOffsetInCompositingLayer());
    18731880            FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
    1874             if (clippingLayer()->setMasksToBoundsRect(contentsClippingRect)) {
    1875                 clippingLayer()->setMaskLayer(nullptr);
     1881            contentsClippingRect.move(LayoutSize(clipLayer->offsetFromRenderer()));
     1882            // Note that we have to set this rounded rect again during the geometry update (clipLayer->offsetFromRenderer() may be stale here).
     1883            if (clipLayer->setMasksToBoundsRect(contentsClippingRect)) {
     1884                clipLayer->setMaskLayer(nullptr);
    18761885                GraphicsLayer::clear(m_childClippingMaskLayer);
    18771886                return;
     
    18921901        } else
    18931902            if (hasClippingLayer())
    1894                 clippingLayer()->setMasksToBoundsRect(FloatRoundedRect(FloatRect(FloatPoint(), clippingLayer()->size())));
     1903                clippingLayer()->setMasksToBoundsRect(FloatRoundedRect(FloatRect({ }, clippingLayer()->size())));
    18951904    }
    18961905}
Note: See TracChangeset for help on using the changeset viewer.