Changeset 240941 in webkit


Ignore:
Timestamp:
Feb 4, 2019, 1:51:32 PM (7 years ago)
Author:
Simon Fraser
Message:

Async overflow scroll with border-radius renders incorrectly
https://bugs.webkit.org/show_bug.cgi?id=194205
<rdar://problem/47771668>

Reviewed by Zalan Bujtas.

Source/WebCore:

When an element has composited overflow:scroll and border-radius, we need to make a layer
to clip to the inside of the border radius if necessary.

Existing code simply turned off needsDescendantsClippingLayer for composited scrolling
layers, but now we check to see if the inner border is rounded. If we have both a m_childContainmentLayer
and scrolling layers, we need to adjust the location of the scrolling layers (which are parented
in m_childContainmentLayer).

Also fix offsetFromRenderer for these layers; it's positive for layers inset from the top left
of the border box.

Tests: compositing/clipping/border-radius-async-overflow-clipping-layer.html

compositing/clipping/border-radius-async-overflow-non-stacking.html
compositing/clipping/border-radius-async-overflow-stacking.html

  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::updateConfiguration):
(WebCore::RenderLayerBacking::updateGeometry):
(WebCore::RenderLayerBacking::updateChildClippingStrategy): Layout is always up-to-date now, so remove the comment.

LayoutTests:

New baselines, mostly correcting offsetFromRenderer.

  • compositing/clipping/border-radius-async-overflow-clipping-layer-expected.txt: Added.
  • compositing/clipping/border-radius-async-overflow-clipping-layer.html: Added.
  • compositing/clipping/border-radius-async-overflow-non-stacking-expected.html: Added.
  • compositing/clipping/border-radius-async-overflow-non-stacking.html: Added.
  • compositing/clipping/border-radius-async-overflow-stacking-expected.html: Added.
  • compositing/clipping/border-radius-async-overflow-stacking.html: Added.
  • compositing/scrolling/overflow-scrolling-layers-are-self-painting-expected.txt:
  • platform/ios/compositing/overflow/scrolling-without-painting-expected.txt:
  • platform/ios/compositing/overflow/textarea-scroll-touch-expected.txt: html.css specifies a border-radius on <textarea> for iOS, so we make additional

clipping layers.

  • platform/ios/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt:
  • platform/ios/compositing/scrolling/overflow-scrolling-layers-are-self-painting-expected.txt:
Location:
trunk
Files:
6 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r240940 r240941  
     12019-02-04  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Async overflow scroll with border-radius renders incorrectly
     4        https://bugs.webkit.org/show_bug.cgi?id=194205
     5        <rdar://problem/47771668>
     6
     7        Reviewed by Zalan Bujtas.
     8
     9        New baselines, mostly correcting offsetFromRenderer.
     10
     11        * compositing/clipping/border-radius-async-overflow-clipping-layer-expected.txt: Added.
     12        * compositing/clipping/border-radius-async-overflow-clipping-layer.html: Added.
     13        * compositing/clipping/border-radius-async-overflow-non-stacking-expected.html: Added.
     14        * compositing/clipping/border-radius-async-overflow-non-stacking.html: Added.
     15        * compositing/clipping/border-radius-async-overflow-stacking-expected.html: Added.
     16        * compositing/clipping/border-radius-async-overflow-stacking.html: Added.
     17        * compositing/scrolling/overflow-scrolling-layers-are-self-painting-expected.txt:
     18        * platform/ios/compositing/overflow/scrolling-without-painting-expected.txt:
     19        * platform/ios/compositing/overflow/textarea-scroll-touch-expected.txt: html.css specifies a border-radius on <textarea> for iOS, so we make additional
     20        clipping layers.
     21        * platform/ios/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt:
     22        * platform/ios/compositing/scrolling/overflow-scrolling-layers-are-self-painting-expected.txt:
     23
    1242019-02-04  Simon Fraser  <simon.fraser@apple.com>
    225
  • trunk/LayoutTests/compositing/scrolling/overflow-scrolling-layers-are-self-painting-expected.txt

    r240713 r240941  
    1313          (children 1
    1414            (GraphicsLayer
    15               (offsetFromRenderer width=-1 height=-1)
     15              (offsetFromRenderer width=1 height=1)
    1616              (position 1.00 1.00)
    1717              (bounds 285.00 285.00)
  • trunk/LayoutTests/fast/scrolling/ios/change-scrollability-on-content-resize-expected.txt

    r240713 r240941  
    7777              (children 1
    7878                (GraphicsLayer
    79                   (offsetFromRenderer width=-5 height=-5)
     79                  (offsetFromRenderer width=5 height=5)
    8080                  (position 5.00 5.00)
    8181                  (bounds 200.00 200.00)
     
    109109              (children 1
    110110                (GraphicsLayer
    111                   (offsetFromRenderer width=-5 height=-5)
     111                  (offsetFromRenderer width=5 height=5)
    112112                  (position 5.00 5.00)
    113113                  (bounds 200.00 200.00)
  • trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-touch-expected.txt

    r240713 r240941  
    1616          (children 1
    1717            (GraphicsLayer
    18               (offsetFromRenderer width=-1 height=-1)
     18              (offsetFromRenderer width=1 height=1)
    1919              (position 1.00 1.00)
    2020              (bounds origin 0.00 50.00)
     
    3838          (children 1
    3939            (GraphicsLayer
    40               (offsetFromRenderer width=-1 height=-1)
     40              (offsetFromRenderer width=1 height=1)
    4141              (position 1.00 1.00)
    4242              (bounds origin 0.00 50.00)
  • trunk/LayoutTests/fast/scrolling/ios/reconcile-layer-position-recursive-expected.txt

    r240713 r240941  
    5454                      (children 1
    5555                        (GraphicsLayer
    56                           (offsetFromRenderer width=-5 height=-5)
     56                          (offsetFromRenderer width=5 height=5)
    5757                          (position 5.00 5.00)
    5858                          (bounds 200.00 400.00)
  • trunk/LayoutTests/platform/ios/compositing/overflow/scrolling-without-painting-expected.txt

    r240713 r240941  
    1313          (children 1
    1414            (GraphicsLayer
    15               (offsetFromRenderer width=-1 height=-1)
     15              (offsetFromRenderer width=1 height=1)
    1616              (position 1.00 1.00)
    1717              (bounds origin 0.00 25.00)
  • trunk/LayoutTests/platform/ios/compositing/overflow/textarea-scroll-touch-expected.txt

    r240713 r240941  
    1414          (children 1
    1515            (GraphicsLayer
    16               (offsetFromRenderer width=-1 height=-1)
     16              (offsetFromRenderer width=1 height=1)
    1717              (position 1.00 1.00)
    18               (bounds origin 0.00 50.00)
    1918              (bounds 204.00 124.00)
    2019              (children 1
    2120                (GraphicsLayer
    2221                  (offsetFromRenderer width=1 height=1)
    23                   (scrollOffset (0,50))
    24                   (anchor 0.00 0.00)
    25                   (bounds 204.00 270.00)
    26                   (drawsContent 1)
     22                  (bounds origin 0.00 50.00)
     23                  (bounds 204.00 124.00)
     24                  (children 1
     25                    (GraphicsLayer
     26                      (offsetFromRenderer width=1 height=1)
     27                      (scrollOffset (0,50))
     28                      (anchor 0.00 0.00)
     29                      (bounds 204.00 270.00)
     30                      (drawsContent 1)
     31                    )
     32                  )
    2733                )
    2834              )
     
    3743          (children 1
    3844            (GraphicsLayer
    39               (offsetFromRenderer width=-1 height=-1)
     45              (offsetFromRenderer width=1 height=1)
    4046              (position 1.00 1.00)
    41               (bounds origin 0.00 50.00)
    4247              (bounds 204.00 124.00)
    4348              (children 1
    4449                (GraphicsLayer
    4550                  (offsetFromRenderer width=1 height=1)
    46                   (scrollOffset (0,50))
    47                   (anchor 0.00 0.00)
    48                   (bounds 204.00 270.00)
    49                   (drawsContent 1)
     51                  (bounds origin 0.00 50.00)
     52                  (bounds 204.00 124.00)
     53                  (children 1
     54                    (GraphicsLayer
     55                      (offsetFromRenderer width=1 height=1)
     56                      (scrollOffset (0,50))
     57                      (anchor 0.00 0.00)
     58                      (bounds 204.00 270.00)
     59                      (drawsContent 1)
     60                    )
     61                  )
    5062                )
    5163              )
  • trunk/LayoutTests/platform/ios/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt

    r240713 r240941  
    1414          (children 1
    1515            (GraphicsLayer
    16               (offsetFromRenderer width=-2 height=-2)
     16              (offsetFromRenderer width=2 height=2)
    1717              (position 2.00 2.00)
    1818              (bounds origin 366.00 0.00)
  • trunk/LayoutTests/platform/ios/compositing/scrolling/overflow-scrolling-layers-are-self-painting-expected.txt

    r240713 r240941  
    1313          (children 1
    1414            (GraphicsLayer
    15               (offsetFromRenderer width=-1 height=-1)
     15              (offsetFromRenderer width=1 height=1)
    1616              (position 1.00 1.00)
    1717              (bounds 300.00 300.00)
  • trunk/LayoutTests/platform/ios/fast/scrolling/ios/overflow-scrolling-ancestor-clip-expected.txt

    r240713 r240941  
    1313          (children 1
    1414            (GraphicsLayer
    15               (offsetFromRenderer width=-1 height=-1)
     15              (offsetFromRenderer width=1 height=1)
    1616              (position 1.00 1.00)
    1717              (bounds origin 0.00 30.00)
  • trunk/LayoutTests/platform/ios/fast/scrolling/ios/overflow-scrolling-ancestor-clip-size-expected.txt

    r240713 r240941  
    1313          (children 1
    1414            (GraphicsLayer
    15               (offsetFromRenderer width=-11 height=-11)
     15              (offsetFromRenderer width=11 height=11)
    1616              (position 11.00 11.00)
    1717              (bounds origin 0.00 30.00)
  • trunk/LayoutTests/platform/ios/fast/scrolling/ios/textarea-scroll-touch-expected.txt

    r240713 r240941  
    1414          (children 1
    1515            (GraphicsLayer
    16               (offsetFromRenderer width=-1 height=-1)
     16              (offsetFromRenderer width=1 height=1)
    1717              (position 1.00 1.00)
    18               (bounds origin 0.00 50.00)
    1918              (bounds 204.00 124.00)
    2019              (children 1
    2120                (GraphicsLayer
    2221                  (offsetFromRenderer width=1 height=1)
    23                   (scrollOffset (0,50))
    24                   (anchor 0.00 0.00)
    25                   (bounds 204.00 270.00)
    26                   (drawsContent 1)
     22                  (bounds origin 0.00 50.00)
     23                  (bounds 204.00 124.00)
     24                  (children 1
     25                    (GraphicsLayer
     26                      (offsetFromRenderer width=1 height=1)
     27                      (scrollOffset (0,50))
     28                      (anchor 0.00 0.00)
     29                      (bounds 204.00 270.00)
     30                      (drawsContent 1)
     31                    )
     32                  )
    2733                )
    2834              )
     
    3743          (children 1
    3844            (GraphicsLayer
    39               (offsetFromRenderer width=-1 height=-1)
     45              (offsetFromRenderer width=1 height=1)
    4046              (position 1.00 1.00)
    41               (bounds origin 0.00 50.00)
    4247              (bounds 204.00 124.00)
    4348              (children 1
    4449                (GraphicsLayer
    4550                  (offsetFromRenderer width=1 height=1)
    46                   (scrollOffset (0,50))
    47                   (anchor 0.00 0.00)
    48                   (bounds 204.00 270.00)
    49                   (drawsContent 1)
     51                  (bounds origin 0.00 50.00)
     52                  (bounds 204.00 124.00)
     53                  (children 1
     54                    (GraphicsLayer
     55                      (offsetFromRenderer width=1 height=1)
     56                      (scrollOffset (0,50))
     57                      (anchor 0.00 0.00)
     58                      (bounds 204.00 270.00)
     59                      (drawsContent 1)
     60                    )
     61                  )
    5062                )
    5163              )
  • trunk/Source/WebCore/ChangeLog

    r240940 r240941  
     12019-02-04  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Async overflow scroll with border-radius renders incorrectly
     4        https://bugs.webkit.org/show_bug.cgi?id=194205
     5        <rdar://problem/47771668>
     6
     7        Reviewed by Zalan Bujtas.
     8
     9        When an element has composited overflow:scroll and border-radius, we need to make a layer
     10        to clip to the inside of the border radius if necessary.
     11
     12        Existing code simply turned off needsDescendantsClippingLayer for composited scrolling
     13        layers, but now we check to see if the inner border is rounded. If we have both a m_childContainmentLayer
     14        and scrolling layers, we need to adjust the location of the scrolling layers (which are parented
     15        in m_childContainmentLayer).
     16
     17        Also fix offsetFromRenderer for these layers; it's positive for layers inset from the top left
     18        of the border box.
     19
     20        Tests: compositing/clipping/border-radius-async-overflow-clipping-layer.html
     21               compositing/clipping/border-radius-async-overflow-non-stacking.html
     22               compositing/clipping/border-radius-async-overflow-stacking.html
     23
     24        * rendering/RenderLayerBacking.cpp:
     25        (WebCore::RenderLayerBacking::updateConfiguration):
     26        (WebCore::RenderLayerBacking::updateGeometry):
     27        (WebCore::RenderLayerBacking::updateChildClippingStrategy): Layout is always up-to-date now, so remove the comment.
     28
    1292019-02-04  Simon Fraser  <simon.fraser@apple.com>
    230
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r240918 r240941  
    703703
    704704    bool layerConfigChanged = false;
    705 
    706     setBackgroundLayerPaintsFixedRootBackground(compositor().needsFixedRootBackgroundLayer(m_owningLayer));
     705    auto& compositor = this->compositor();
     706
     707    setBackgroundLayerPaintsFixedRootBackground(compositor.needsFixedRootBackgroundLayer(m_owningLayer));
    707708
    708709    if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground || m_requiresBackgroundLayer))
    709710        layerConfigChanged = true;
    710711
    711     if (updateForegroundLayer(compositor().needsContentsCompositingLayer(m_owningLayer)))
     712    if (updateForegroundLayer(compositor.needsContentsCompositingLayer(m_owningLayer)))
    712713        layerConfigChanged = true;
    713714   
    714     // This requires descendants to have been updated.
    715     bool needsDescendantsClippingLayer = compositor().clipsCompositingDescendants(m_owningLayer);
     715    bool needsDescendantsClippingLayer = false;
    716716    bool usesCompositedScrolling = m_owningLayer.hasCompositedScrollableOverflow();
    717717
    718     // Our scrolling layer will clip.
    719     if (usesCompositedScrolling)
    720         needsDescendantsClippingLayer = false;
     718    if (usesCompositedScrolling) {
     719        // If it's scrollable, it has to be a box.
     720        auto& renderBox = downcast<RenderBox>(renderer());
     721        FloatRoundedRect contentsClippingRect = renderer().style().getRoundedInnerBorderFor(renderBox.borderBoxRect()).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
     722        needsDescendantsClippingLayer = contentsClippingRect.isRounded();
     723    } else
     724        needsDescendantsClippingLayer = compositor.clipsCompositingDescendants(m_owningLayer);
    721725
    722726    if (updateScrollingLayers(usesCompositedScrolling))
     
    727731
    728732    // clippedByAncestor() does a tree walk.
    729     if (updateAncestorClippingLayer(compositor().clippedByAncestor(m_owningLayer)))
     733    if (updateAncestorClippingLayer(compositor.clippedByAncestor(m_owningLayer)))
    730734        layerConfigChanged = true;
    731735
     
    795799    }
    796800#endif
    797     if (is<RenderWidget>(renderer()) && compositor().parentFrameContentLayers(downcast<RenderWidget>(renderer()))) {
     801    if (is<RenderWidget>(renderer()) && compositor.parentFrameContentLayers(downcast<RenderWidget>(renderer()))) {
    798802        m_owningLayer.setNeedsCompositingGeometryUpdate();
    799803        layerConfigChanged = true;
     
    10831087    LayoutRect clippingBox;
    10841088    if (auto* clipLayer = clippingLayer()) {
     1089        // clipLayer is the m_childContainmentLayer.
    10851090        clippingBox = clipBox(downcast<RenderBox>(renderer()));
    10861091        // Clipping layer is parented in the primary graphics layer.
     
    11861191        auto& renderBox = downcast<RenderBox>(renderer());
    11871192        LayoutRect paddingBoxIncludingScrollbar = renderBox.paddingBoxRectIncludingScrollbar();
     1193        LayoutRect parentLayerBounds = clippingLayer() ? clippingBox : compositedBounds();
     1194
     1195        // FIXME: need to do some pixel snapping here.
     1196        m_scrollContainerLayer->setPosition(FloatPoint(paddingBoxIncludingScrollbar.location() - parentLayerBounds.location()));
     1197        m_scrollContainerLayer->setSize(roundedIntSize(LayoutSize(renderBox.paddingBoxWidth(), renderBox.paddingBoxHeight())));
     1198
    11881199        ScrollOffset scrollOffset = m_owningLayer.scrollOffset();
    1189 
    1190         // FIXME: need to do some pixel snapping here.
    1191         m_scrollContainerLayer->setPosition(FloatPoint(paddingBoxIncludingScrollbar.location() - compositedBounds().location()));
    1192         m_scrollContainerLayer->setSize(roundedIntSize(LayoutSize(renderBox.clientWidth(), renderBox.clientHeight())));
    1193 
    11941200        updateScrollOffset(scrollOffset);
    11951201#if PLATFORM(IOS_FAMILY)
     
    11981204
    11991205        FloatSize oldScrollingLayerOffset = m_scrollContainerLayer->offsetFromRenderer();
    1200         m_scrollContainerLayer->setOffsetFromRenderer(-toFloatSize(paddingBoxIncludingScrollbar.location()));
     1206        m_scrollContainerLayer->setOffsetFromRenderer(toFloatSize(paddingBoxIncludingScrollbar.location()));
    12011207
    12021208        if (m_childClippingMaskLayer) {
    12031209            m_childClippingMaskLayer->setPosition(m_scrollContainerLayer->position());
    12041210            m_childClippingMaskLayer->setSize(m_scrollContainerLayer->size());
    1205             m_childClippingMaskLayer->setOffsetFromRenderer(-toFloatSize(paddingBoxIncludingScrollbar.location()));
     1211            m_childClippingMaskLayer->setOffsetFromRenderer(toFloatSize(paddingBoxIncludingScrollbar.location()));
    12061212        }
    12071213
     
    17091715    if (hasClippingLayer() && needsDescendantsClippingLayer) {
    17101716        if (is<RenderBox>(renderer()) && (renderer().style().clipPath() || renderer().style().hasBorderRadius())) {
    1711             // FIXME: we shouldn't get geometry here as layout may not have been udpated.
    17121717            LayoutRect boxRect(LayoutPoint(), downcast<RenderBox>(renderer()).size());
    17131718            boxRect.move(contentOffsetInCompostingLayer());
Note: See TracChangeset for help on using the changeset viewer.