Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 315fb715d136d0057225087b703abe6bffac7a82
      
https://github.com/WebKit/WebKit/commit/315fb715d136d0057225087b703abe6bffac7a82
  Author: Nikolas Zimmermann <[email protected]>
  Date:   2026-04-29 (Wed, 29 Apr 2026)

  Changed paths:
    M Source/WebCore/Headers.cmake
    M Source/WebCore/WebCore.xcodeproj/project.pbxproj
    M Source/WebCore/rendering/RenderElement.cpp
    M Source/WebCore/rendering/RenderElement.h
    M Source/WebCore/rendering/RenderLayer.cpp
    M Source/WebCore/rendering/RenderLayer.h
    M Source/WebCore/rendering/RenderLayerModelObject.cpp
    M Source/WebCore/rendering/RenderLayerSVGAdditions.cpp
    A Source/WebCore/rendering/RenderLayerSVGAdditions.h
    M Source/WebCore/rendering/updating/RenderTreeBuilder.cpp

  Log Message:
  -----------
  [LBSE] Introduce DOM-order children cache infrastructure for SVG layers
https://bugs.webkit.org/show_bug.cgi?id=313177

Reviewed by Simon Fraser.

Introduce the storage, invalidation, and collection of a cached, DOM-order
list of children for SVG layers. This infrastructure prepares for upcoming
SVG-specific painting and hit-testing that needs to walk children in DOM
order while interleaving layered and non-layered subtrees, and while
honoring z-index.

A new RenderLayerSVGAdditions.h header defines SVGPaintOrderLayerItem,
which classifies each entry via three factories:

 1) makeLayered: the child has its own RenderLayer; the consumer will
    delegate to the layer's own paint/hit-test machinery.
 2) makeAtomic: a transformed non-layer SVG renderer, or any leaf - painted
    in a single recursive pass at the precomputed ancestor offset.
 3) makeOutlineOnly: a non-layer container whose subtree contains
    independently painted descendants. The container is kept in the list
    so its own self-outline still paints in DOM order, while its
    descendants appear as separate entries; the container's own paint
    must therefore skip child recursion to avoid double-painting.

RenderLayer::SVGData gains the cached vector plus a dirty flag.
childrenInDOMOrderForSVG() is the lazy accessor and rebuilds via
collectChildrenInDOMOrderForSVG() when dirty. Collection walks the render
tree recursively: layered descendants and transformed non-layer descendants
are appended directly, while non-layer containers are recursed
speculatively — kept as a split makeOutlineOnly entry if the subtree contains
any independently painted descendants, otherwise collapsed into a single
makeAtomic entry. The final list is stable-sorted by z-index only when at
least one child uses a non-zero z-index, so the common case stays in DOM
order without sort overhead. Storage uses Vector::shrink(0) on
invalidation and rebuild to retain capacity across churn.

The cache is dirtied via dirtyChildrenInDOMOrderForSVG(), wired into every
site that can change the list's membership, classification, or sort order:

  - RenderLayer::dirtyPaintOrderListsOnChildChange, dirtyZOrderLists, and
    dirtyNormalFlowList — layer-children changes within an SVG ancestor.
    Note that the existing dirtyStackingContextZOrderLists() only dirties
    the stacking context ancestor, not necessarily the immediate parent,
    so an explicit dirty is required.
  - The z-index branch of RenderLayer::styleChanged — z-index drives sort
    order, so the parent layer's cache must be dirtied when it changes.
  - RenderElement::insertedIntoTree and willBeRemovedFromTree, via the
    new dirtyEnclosingLayerSVGChildrenIfNeeded() helper — non-layer SVG
    renderers do not go through RenderLayer::addChild/removeChild, so
    their insertion and removal must be intercepted at the RenderElement
    level.
  - RenderLayerModelObject::updateHasSVGTransformFlags and
    repaintOrRelayoutAfterSVGTransformChange — when isTransformed() flips
    on a non-layer renderer, its classification flips between Atomic and
    the container path, requiring a rebuild of the enclosing layer's
    cache.
  - RenderTreeBuilder::detachFromRenderElement on the early-teardown
    path, where resetRendererStateOnDetach() does not run and would
    otherwise leave stale entries pointing into the detached subtree.

The cache has no consumers yet; they follow in subsequent patches.
Covered by existing tests once conditional-layer support is enabled.

* Source/WebCore/Headers.cmake:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/rendering/RenderElement.cpp:
(WebCore::RenderElement::dirtyEnclosingLayerSVGChildrenIfNeeded):
(WebCore::RenderElement::insertedIntoTree):
(WebCore::RenderElement::willBeRemovedFromTree):
* Source/WebCore/rendering/RenderElement.h:
* Source/WebCore/rendering/RenderLayer.cpp:
(WebCore::RenderLayer::dirtyPaintOrderListsOnChildChange):
(WebCore::RenderLayer::dirtyZOrderLists):
(WebCore::RenderLayer::dirtyNormalFlowList):
(WebCore::RenderLayer::calculateClipRects const):
* Source/WebCore/rendering/RenderLayer.h:
* Source/WebCore/rendering/RenderLayerModelObject.cpp:
(WebCore::RenderLayerModelObject::updateHasSVGTransformFlags):
(WebCore::RenderLayerModelObject::repaintOrRelayoutAfterSVGTransformChange):
* Source/WebCore/rendering/RenderLayerSVGAdditions.cpp:
(WebCore::RenderLayer::dirtyChildrenInDOMOrderForSVG):
(WebCore::RenderLayer::collectChildrenInDOMOrderForSVG):
(WebCore::RenderLayer::appendChildrenInDOMOrderForSVG):
(WebCore::RenderLayer::childrenInDOMOrderForSVG):
* Source/WebCore/rendering/RenderLayerSVGAdditions.h: Added.
(WebCore::SVGPaintOrderLayerItem::makeLayered):
(WebCore::SVGPaintOrderLayerItem::makeAtomic):
(WebCore::SVGPaintOrderLayerItem::makeOutlineOnly):
(WebCore::SVGPaintOrderLayerItem::SVGPaintOrderLayerItem):
* Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:
(WebCore::RenderTreeBuilder::detachFromRenderElement):

Canonical link: https://commits.webkit.org/312337@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to