Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 6574b387998abad57a67aa53491eef8ab2bc384c
https://github.com/WebKit/WebKit/commit/6574b387998abad57a67aa53491eef8ab2bc384c
Author: Nikolas Zimmermann <[email protected]>
Date: 2026-07-14 (Tue, 14 Jul 2026)
Changed paths:
A LayoutTests/svg/clip-path/clip-path-child-transform-change-expected.html
A LayoutTests/svg/clip-path/clip-path-child-transform-change.html
M Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
M Source/WebCore/rendering/svg/RenderSVGModelObject.h
M Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
M Source/WebCore/rendering/svg/RenderSVGResourceClipper.h
M Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
M Source/WebCore/rendering/svg/RenderSVGResourceContainer.h
Log Message:
-----------
[LBSE] Cache the clip-path geometry instead of rebuilding it per clipped
shape per frame
https://bugs.webkit.org/show_bug.cgi?id=319371
Reviewed by Rob Buis.
RenderSVGResourceClipper::applyPathClipping() rebuilt the clip geometry for
every clipped shape
on every frame: computeClipPath() -> pathFromGraphicsElement() re-parses the
clip child's
attributes into a new Path, and context.clipPath() then converts it to a CGPath
via
Path::platformPath() -> PathCG::create(). The geometry is constant for a given
clip-path,
only the per-target transform differs and is applied separately via the CTM.
On MotionMark/Suits half the shapes carry a clip-path, so this rebuilt
thousands of
identical clip paths per frame. Sampling at fixed, high complexity showed
setupClipPathForRenderer
at ~12% of the WebProcess main thread (PathCG::create alone ~5%) - caching
drops it to ~3% and
PathCG::create disappears.
Therefore cache the geometry as a Path on the clipper, flushed via a new
clearCachesForLayout()
hook on RenderSVGResourceContainer, called from layout(). Only a relayout of
the clip subtree
can change the clip geometry. Split computeClipPath() into
computeClipPathGeometry() (cacheable) and
computeClipContentTransform(): the content transform is recomputed live every
frame rather
than cached, because it can animate via the SVG/CSS transform fast path, which
repaints the
clipper's clients without relaying out the <clipPath>.
Test: svg/clip-path/clip-path-child-transform-change.html
* LayoutTests/svg/clip-path/clip-path-child-transform-change-expected.html:
Added.
* LayoutTests/svg/clip-path/clip-path-child-transform-change.html: Added.
* Source/WebCore/rendering/svg/RenderSVGModelObject.cpp:
(WebCore::RenderSVGModelObject::computeClipContentTransform const):
(WebCore::RenderSVGModelObject::computeClipPathGeometry const):
(WebCore::RenderSVGModelObject::computeClipPath const): Deleted.
* Source/WebCore/rendering/svg/RenderSVGModelObject.h:
* Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp:
(WebCore::RenderSVGResourceClipper::applyPathClipping):
(WebCore::RenderSVGResourceClipper::clearCacheBeforeLayout):
* Source/WebCore/rendering/svg/RenderSVGResourceClipper.h:
* Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp:
(WebCore::RenderSVGResourceContainer::layout):
* Source/WebCore/rendering/svg/RenderSVGResourceContainer.h:
(WebCore::RenderSVGResourceContainer::clearCacheBeforeLayout):
Canonical link: https://commits.webkit.org/317143@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications