Skip to content

Commit

Permalink
An SVG element with a CSS reference filter fails to repaint when the …
Browse files Browse the repository at this point in the history
…filter changes

https://bugs.webkit.org/show_bug.cgi?id=263229
rdar://117047658

Reviewed by Nikolas Zimmermann.

If an SVG element has a CSS filter which references an SVG element (which may be a child of that SVG,
or some other SVG in the document), then we fail to repaint the SVG when the filter changes.

This is a followup to 267236@main, removing the `&& !renderer().isSVGRootOrLegacySVGRoot()` check in
`RenderLayer::updateFiltersAfterStyleChange()`, since in this configuration we do need to have
the RenderLayer track the filter dependencies.

* LayoutTests/svg/filters/css-repaint-reference-filter-on-root-expected.txt: Added.
* LayoutTests/svg/filters/css-repaint-reference-filter-on-root.html: Added.
* Source/WebCore/rendering/RenderLayer.cpp:
(WebCore::RenderLayer::updateFiltersAfterStyleChange):

Canonical link: https://commits.webkit.org/269413@main
  • Loading branch information
smfr committed Oct 17, 2023
1 parent afe960e commit ea2c363
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(repaint rects
(rect 49 313 100 111)
)

46 changes: 46 additions & 0 deletions LayoutTests/svg/filters/css-repaint-reference-filter-on-root.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<style>
svg {
display: block;
margin: 20px;
height: 200px;
}

.container {
padding: 10px;
width: 300px;
margin: 10px;
border: 1px solid black;
}
</style>
<script src="../../fast/repaint/resources/text-based-repaint.js"></script>
<script>
function repaintTest()
{
let filter = document.getElementById('targetFilter');
filter.querySelector('feColorMatrix').setAttribute('values', '90')
}

window.addEventListener('load', () => {
runRepaintTest();
}, false);
</script>
</head>
<body>
<div class="container">
<svg id="gammaTarget1" width="100" height="100">
<filter id="targetFilter">
<feColorMatrix type="hueRotate" values="180" />
</filter>
<rect width="100" height="100" fill="red" filter="url(#targetFilter)"/>
</svg>
</div>
<div class="container">
<svg width="100" height="100" style="filter: url(#targetFilter);">
<rect width="100" height="100" fill="red"/>
</svg>
</div>
</body>
</html>
4 changes: 1 addition & 3 deletions Source/WebCore/rendering/RenderLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5623,9 +5623,7 @@ void RenderLayer::updateFiltersAfterStyleChange(StyleDifference diff, const Rend
return;
}

// Add the filter as a client to this renderer, unless we are a RenderLayer accommodating
// an SVG. In that case it takes care of its own resource management for filters.
if (renderer().style().filter().hasReferenceFilter() && !renderer().isSVGRootOrLegacySVGRoot()) {
if (renderer().style().filter().hasReferenceFilter()) {
ensureLayerFilters();
m_filters->updateReferenceFilterClients(renderer().style().filter());
} else if (m_filters)
Expand Down

0 comments on commit ea2c363

Please sign in to comment.