Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVG clip-path is sometimes broken on stevejobsarchive.com #12845

Conversation

smfr
Copy link
Contributor

@smfr smfr commented Apr 18, 2023

e4d2a74

SVG clip-path is sometimes broken on stevejobsarchive.com
https://bugs.webkit.org/show_bug.cgi?id=255577
rdar://107885344

Reviewed by Said Abou-Hallawa.

http://book.stevejobsarchive.com/ uses CSS clip-path with a reference to an SVG <clipPath> element
which contains text.

In this configuration, RenderSVGResourceClipper::applyClippingToContext() falls back to a code path
that uses an ImageBuffer as a mask, and it caches the ImageBuffer between calls. This caused a
problem when DOM Rendering in the GPU Process was enabled; this code is first hit for a "fake" paint
with a NullGraphicsContext which is updating EventRegions, called out of
`RenderLayerBacking::updateEventRegion()`. The NullGraphicsContext will make a local ImageBuffer.

If we then hit this same code for actual painting with a painting GraphicsContext, we'll use that
cached ImageBuffer, rather than creating a new one with appropriate GPU Process backing.

Fix this by adding `isPaintingDisabled` to the criteria used to decide if the cached buffer can be
re-used.

* LayoutTests/svg/masking/masking-with-event-region-expected.html: Added.
* LayoutTests/svg/masking/masking-with-event-region.html: Added.
* Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp:
(WebCore::RenderSVGResourceClipper::computeInputs):
(WebCore::RenderSVGResourceClipper::applyClippingToContext):
* Source/WebCore/rendering/svg/RenderSVGResourceClipper.h:
(WebCore::ClipperData::Inputs::operator== const):

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

0ad7712

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  wincairo
βœ… πŸ§ͺ bindings βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug   πŸ§ͺ wpe-wk2
βœ… πŸ§ͺ webkitperl   πŸ§ͺ ios-wk2 βœ… πŸ§ͺ api-mac βœ… πŸ›  gtk
  πŸ§ͺ ios-wk2-wpt βœ… πŸ§ͺ mac-wk1   πŸ§ͺ gtk-wk2
  πŸ§ͺ api-ios βœ… πŸ§ͺ mac-wk2 ❌ πŸ§ͺ api-gtk
βœ… πŸ›  tv   πŸ§ͺ mac-AS-debug-wk2
βœ… πŸ›  tv-sim βœ… πŸ§ͺ mac-wk2-stress
βœ… πŸ›  πŸ§ͺ merge βœ… πŸ›  watch
βœ… πŸ›  watch-sim

@smfr smfr self-assigned this Apr 18, 2023
@smfr smfr added the SVG For bugs in the SVG implementation. label Apr 18, 2023
@@ -167,7 +167,7 @@ bool RenderSVGResourceClipper::applyClippingToContext(GraphicsContext& context,
if (!clipperData.imageBuffer && pathOnlyClipping(context, animatedLocalTransform, objectBoundingBox, effectiveZoom))
return true;

if (clipperData.invalidate(computeInputs(renderer, objectBoundingBox, clippedContentBounds, effectiveZoom))) {
if (clipperData.invalidate(computeInputs(renderer, context, objectBoundingBox, clippedContentBounds, effectiveZoom))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not computeInputs() and applyClippingToContext() have the arguments: RenderElement and GraphicsContext in the same order: (const RenderElement&, const GraphicsContext& ...) or (const GraphicsContext&, const RenderElement& ...)?

@@ -45,6 +45,7 @@ struct ClipperData {
FloatRect clippedContentBounds;
FloatSize scale;
float effectiveZoom = 1;
bool paintingDisabled { false };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively ClipperData::invalidate() can check

context.hasPlatformContext() == imageBuffer->context().hasPlatformContext()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That won't work; both the NullGraphicsContext and the GPUP-based GraphicsContext have no platform contexts.

Comment on lines 37 to 40
bool operator==(const Inputs& other) const
{
return std::tie(objectBoundingBox, clippedContentBounds, scale, effectiveZoom) == std::tie(other.objectBoundingBox, other.clippedContentBounds, other.scale, other.effectiveZoom);
return std::tie(objectBoundingBox, clippedContentBounds, scale, effectiveZoom, paintingDisabled) == std::tie(other.objectBoundingBox, other.clippedContentBounds, other.scale, other.effectiveZoom, other.paintingDisabled);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this just be

bool operator==(const Inputs&) const = default;

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Apr 18, 2023
@smfr smfr removed the merging-blocked Applied to prevent a change from being merged label Apr 18, 2023
@smfr smfr force-pushed the eng/SVG-clip-path-is-sometimes-broken-on-stevejobsarchive-com branch from aadf5e6 to 0ad7712 Compare April 18, 2023 16:58
@smfr smfr added the merge-queue Applied to send a pull request to merge-queue label Apr 18, 2023
https://bugs.webkit.org/show_bug.cgi?id=255577
rdar://107885344

Reviewed by Said Abou-Hallawa.

http://book.stevejobsarchive.com/ uses CSS clip-path with a reference to an SVG <clipPath> element
which contains text.

In this configuration, RenderSVGResourceClipper::applyClippingToContext() falls back to a code path
that uses an ImageBuffer as a mask, and it caches the ImageBuffer between calls. This caused a
problem when DOM Rendering in the GPU Process was enabled; this code is first hit for a "fake" paint
with a NullGraphicsContext which is updating EventRegions, called out of
`RenderLayerBacking::updateEventRegion()`. The NullGraphicsContext will make a local ImageBuffer.

If we then hit this same code for actual painting with a painting GraphicsContext, we'll use that
cached ImageBuffer, rather than creating a new one with appropriate GPU Process backing.

Fix this by adding `isPaintingDisabled` to the criteria used to decide if the cached buffer can be
re-used.

* LayoutTests/svg/masking/masking-with-event-region-expected.html: Added.
* LayoutTests/svg/masking/masking-with-event-region.html: Added.
* Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp:
(WebCore::RenderSVGResourceClipper::computeInputs):
(WebCore::RenderSVGResourceClipper::applyClippingToContext):
* Source/WebCore/rendering/svg/RenderSVGResourceClipper.h:
(WebCore::ClipperData::Inputs::operator== const):

Canonical link: https://commits.webkit.org/263087@main
@webkit-commit-queue webkit-commit-queue force-pushed the eng/SVG-clip-path-is-sometimes-broken-on-stevejobsarchive-com branch from 0ad7712 to e4d2a74 Compare April 18, 2023 18:20
@webkit-commit-queue
Copy link
Collaborator

Committed 263087@main (e4d2a74): https://commits.webkit.org/263087@main

Reviewed commits have been landed. Closing PR #12845 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit e4d2a74 into WebKit:main Apr 18, 2023
@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Apr 18, 2023
@smfr smfr deleted the eng/SVG-clip-path-is-sometimes-broken-on-stevejobsarchive-com branch October 1, 2023 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SVG For bugs in the SVG implementation.
Projects
None yet
5 participants