Changeset 288429 in webkit


Ignore:
Timestamp:
Jan 23, 2022 8:48:29 PM (6 months ago)
Author:
commit-queue@webkit.org
Message:

Position:fixed layers shouldn't allocate a backing buffer if all children are offscreen.
https://bugs.webkit.org/show_bug.cgi?id=235420
<rdar://86612099>

Patch by Matt Woodrow <Matt Woodrow> on 2022-01-23
Reviewed by Simon Fraser and Darin Adler.

Source/WebCore:

Adds a bounds intersection check to isPaintDestinationForDescendantLayers,
so that we can exclude descendants that definitely won't draw anything into
the compositing layer. Uses a conservative check, which gives up if there are
any transforms in the ancestor chain.

Test: compositing/backing/no-backing-for-offscreen-children-of-position-fixed.html

  • rendering/RenderLayerBacking.cpp:

(WebCore::intersectsWithAncestor):
(WebCore::RenderLayerBacking::isPaintDestinationForDescendantLayers const):

LayoutTests:

Adds a test that has a viewport sized position:fixed element (with compositing
layer), and a single child which is entirely offscreen. Tests that we correctly
determine that we don't need a backing store for the layer.

  • compositing/backing/no-backing-for-offscreen-children-of-position-fixed-expected.txt: Added.
  • compositing/backing/no-backing-for-offscreen-children-of-position-fixed.html: Added.
Location:
trunk
Files:
1 added
6 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r288425 r288429  
     12022-01-23  Matt Woodrow  <mattwoodrow@apple.com>
     2
     3        Position:fixed layers shouldn't allocate a backing buffer if all children are offscreen.
     4        https://bugs.webkit.org/show_bug.cgi?id=235420
     5        <rdar://86612099>
     6
     7        Reviewed by Simon Fraser and Darin Adler.
     8
     9        Adds a test that has a viewport sized position:fixed element (with compositing
     10        layer), and a single child which is entirely offscreen. Tests that we correctly
     11        determine that we don't need a backing store for the layer.
     12
     13        * compositing/backing/no-backing-for-offscreen-children-of-position-fixed-expected.txt: Added.
     14        * compositing/backing/no-backing-for-offscreen-children-of-position-fixed.html: Added.
     15
    1162022-01-23  Tyler Wilcock  <tyler_w@apple.com>
    217
  • trunk/LayoutTests/compositing/backing/no-backing-for-offscreen-children-of-position-fixed-expected.txt

    r288428 r288429  
    88      (children 1
    99        (GraphicsLayer
    10           (position 8.00 8.00)
    11           (bounds 100.00 100.00)
    12           (contentsOpaque 1)
    13           (drawsContent 1)
     10          (bounds 200.00 200.00)
    1411        )
    1512      )
  • trunk/LayoutTests/compositing/clip-child-by-non-stacking-ancestor-expected.txt

    r168244 r288429  
    1111          (bounds 100.00 100.00)
    1212          (contentsOpaque 1)
    13           (drawsContent 1)
    1413        )
    1514      )
  • trunk/LayoutTests/compositing/geometry/limit-layer-bounds-fixed-expected.txt

    r225897 r288429  
    1616          (position 0.00 3000.00)
    1717          (bounds 300.00 200.00)
    18           (drawsContent 1)
    1918        )
    2019      )
  • trunk/LayoutTests/platform/ios-wk2/compositing/geometry/limit-layer-bounds-fixed-expected.txt

    r225897 r288429  
    1616          (position 0.00 3000.00)
    1717          (bounds 300.00 200.00)
    18           (drawsContent 1)
    1918        )
    2019      )
  • trunk/Source/WebCore/ChangeLog

    r288428 r288429  
     12022-01-23  Matt Woodrow  <mattwoodrow@apple.com>
     2
     3        Position:fixed layers shouldn't allocate a backing buffer if all children are offscreen.
     4        https://bugs.webkit.org/show_bug.cgi?id=235420
     5        <rdar://86612099>
     6
     7        Reviewed by Simon Fraser and Darin Adler.
     8
     9        Adds a bounds intersection check to isPaintDestinationForDescendantLayers,
     10        so that we can exclude descendants that definitely won't draw anything into
     11        the compositing layer. Uses a conservative check, which gives up if there are
     12        any transforms in the ancestor chain.
     13
     14        Test: compositing/backing/no-backing-for-offscreen-children-of-position-fixed.html
     15
     16        * rendering/RenderLayerBacking.cpp:
     17        (WebCore::intersectsWithAncestor):
     18        (WebCore::RenderLayerBacking::isPaintDestinationForDescendantLayers const):
     19
    1202022-01-23  Darin Adler  <darin@apple.com>
    221
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r287757 r288429  
    27912791}
    27922792
     2793static std::optional<bool> intersectsWithAncestor(const RenderLayer& child, const RenderLayer& ancestor, const LayoutRect& ancestorCompositedBounds)
     2794{
     2795    // If any layers between child and ancestor are transformed, then adjusting the offset is
     2796    // insufficient to convert coordinates into ancestor's coordinate space.
     2797    for (auto* layer = &child; layer != &ancestor; layer = layer->parent()) {
     2798        if (!layer->canUseOffsetFromAncestor())
     2799            return std::nullopt;
     2800    }
     2801
     2802    auto offset = child.convertToLayerCoords(&ancestor, { }, RenderLayer::AdjustForColumns);
     2803    auto overlap = child.overlapBounds();
     2804    overlap.moveBy(offset);
     2805    return overlap.intersects(ancestorCompositedBounds);
     2806}
     2807
    27932808// Conservative test for having no rendered children.
    27942809bool RenderLayerBacking::isPaintDestinationForDescendantLayers(RenderLayer::PaintedContentRequest& request) const
    27952810{
    27962811    bool hasPaintingDescendant = false;
    2797     traverseVisibleNonCompositedDescendantLayers(m_owningLayer, [&hasPaintingDescendant, &request](const RenderLayer& layer) {
    2798         hasPaintingDescendant |= layer.isVisuallyNonEmpty(&request);
     2812    traverseVisibleNonCompositedDescendantLayers(m_owningLayer, [&hasPaintingDescendant, &request, this](const RenderLayer& layer) {
     2813        RenderLayer::PaintedContentRequest localRequest;
     2814        if (layer.isVisuallyNonEmpty(&localRequest)) {
     2815            bool mayIntersect = intersectsWithAncestor(layer, m_owningLayer, compositedBounds()).value_or(true);
     2816            if (mayIntersect) {
     2817                hasPaintingDescendant = true;
     2818                request.setHasPaintedContent();
     2819            }
     2820        }
    27992821        return (hasPaintingDescendant && request.isSatisfied()) ? LayerTraversal::Stop : LayerTraversal::Continue;
    28002822    });
Note: See TracChangeset for help on using the changeset viewer.