Title: [264098] releases/WebKitGTK/webkit-2.28
Revision
264098
Author
[email protected]
Date
2020-07-08 05:38:59 -0700 (Wed, 08 Jul 2020)

Log Message

Merge r259137 - Hovering over countries at https://covidinc.io/ shows bizarre rendering artifacts
https://bugs.webkit.org/show_bug.cgi?id=209635
<rdar://problem/60935010>

Reviewed by Said Abou-Hallawa.
Source/WebCore:

RenderSVGResourceClipper::applyClippingToContext() cached an ImageBuffer per RenderObject
when using a image buffer mask. However, the function created and rendered into this image buffer
using repaintRect, which can change between invocations. Painting with different repaintRects
is very common when rendering into page tiles.

The buffer can only be re-used if the inputs used to create the buffer (objectBoundingBox, absoluteTransform)
are the same, so store those and compare them when determining when to use the cached buffer, and
don't use repaintRect when setting up the buffer.

This revealed another problem where renderers with visual overflow could be truncated by
the clipping, tested by imported/mozilla/svg/svg-integration/clipPath-html-03.xhtml, which occurred
because RenderLayer::setupClipPath() used the 'svgReferenceBox' for the clipping bounds, which
is the content box of the renderer excluding overflow. Fix this by using the bounds of the layer,
which includes the bounds of descendants.

Tests: svg/clip-path/clip-path-on-overflowing.html
       svg/clip-path/resource-clipper-multiple-repaints.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::setupClipPath):
* rendering/svg/RenderSVGResourceClipper.cpp:
(WebCore::RenderSVGResourceClipper::removeAllClientsFromCache):
(WebCore::RenderSVGResourceClipper::applyClippingToContext):
(WebCore::RenderSVGResourceClipper::drawContentIntoMaskImage):
(WebCore::RenderSVGResourceClipper::addRendererToClipper):
(WebCore::RenderSVGResourceClipper::resourceBoundingBox):
* rendering/svg/RenderSVGResourceClipper.h:

LayoutTests:

Ref test that exercises the code path by painting into a tiled compositing
layer.

* svg/clip-path/clip-path-on-overflowing-expected.html: Added.
* svg/clip-path/clip-path-on-overflowing.html: Added.
* svg/clip-path/mask-nested-clip-path-010-expected.svg:
* svg/clip-path/mask-nested-clip-path-010.svg: Copied from imported/mozilla/svg/svg-integration/clipPath-html-03.xhtml,
and modified to have a non-zero offset for better testing of the clipping bounds computation.
* svg/clip-path/resource-clipper-multiple-repaints-expected.html: Added.
* svg/clip-path/resource-clipper-multiple-repaints.html: Added.

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.28/LayoutTests/ChangeLog (264097 => 264098)


--- releases/WebKitGTK/webkit-2.28/LayoutTests/ChangeLog	2020-07-08 11:26:08 UTC (rev 264097)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/ChangeLog	2020-07-08 12:38:59 UTC (rev 264098)
@@ -1,3 +1,22 @@
+2020-03-27  Simon Fraser  <[email protected]>
+
+        Hovering over countries at https://covidinc.io/ shows bizarre rendering artifacts
+        https://bugs.webkit.org/show_bug.cgi?id=209635
+        <rdar://problem/60935010>
+
+        Reviewed by Said Abou-Hallawa.
+        
+        Ref test that exercises the code path by painting into a tiled compositing
+        layer.
+
+        * svg/clip-path/clip-path-on-overflowing-expected.html: Added.
+        * svg/clip-path/clip-path-on-overflowing.html: Added.
+        * svg/clip-path/mask-nested-clip-path-010-expected.svg:
+        * svg/clip-path/mask-nested-clip-path-010.svg: Copied from imported/mozilla/svg/svg-integration/clipPath-html-03.xhtml,
+        and modified to have a non-zero offset for better testing of the clipping bounds computation.
+        * svg/clip-path/resource-clipper-multiple-repaints-expected.html: Added.
+        * svg/clip-path/resource-clipper-multiple-repaints.html: Added.
+
 2020-05-12  Philippe Normand  <[email protected]>
 
         [GStreamer] Audio messages in web.whatsapp.com only play once.

Added: releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/clip-path-on-overflowing-expected.html (0 => 264098)


--- releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/clip-path-on-overflowing-expected.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/clip-path-on-overflowing-expected.html	2020-07-08 12:38:59 UTC (rev 264098)
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+    <div style="margin: 123px; position: relative">
+        <div style="width:200px; height:150px; background:lime;"></div>
+        <div style="position: absolute; left: 100px; top: 150px; width:100px; height:100px; background:lime;"></div>
+        <div style="position: absolute; left: 100px; top: 200px; width:100px; height:100px; background:blue;"></div>
+    </div>
+</body>
+</html>

Added: releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/clip-path-on-overflowing.html (0 => 264098)


--- releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/clip-path-on-overflowing.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/clip-path-on-overflowing.html	2020-07-08 12:38:59 UTC (rev 264098)
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+  <div style="clip-path: url(#clipper); width:500px; height:200px; background:lime; margin: 123px">
+    <div style="height:200px;"></div>
+    <div style="height:200px; background:blue;"></div>
+  </div>
+
+  <svg height="0">
+    <clipPath id="clipper">
+      <rect x="0" y="0" width="100" height="150"/>
+      <rect x="100" y="0" width="100" height="300"/>
+    </clipPath>
+  </svg>
+</body>
+</html>

Modified: releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/mask-nested-clip-path-010-expected.svg (264097 => 264098)


--- releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/mask-nested-clip-path-010-expected.svg	2020-07-08 11:26:08 UTC (rev 264097)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/mask-nested-clip-path-010-expected.svg	2020-07-08 12:38:59 UTC (rev 264098)
@@ -1,4 +1,4 @@
 <svg xmlns="http://www.w3.org/2000/svg" width="10000" height="400">
     <rect x="99" width="101" height="100" fill="green"/>
-    <rect x="299" width="101" height="100" fill="green"/>
+    <rect x="295" width="105" height="100" fill="green"/>
 </svg>

Modified: releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/mask-nested-clip-path-010.svg (264097 => 264098)


--- releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/mask-nested-clip-path-010.svg	2020-07-08 11:26:08 UTC (rev 264097)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/mask-nested-clip-path-010.svg	2020-07-08 12:38:59 UTC (rev 264098)
@@ -28,6 +28,6 @@
 
   <g mask="url(#crop)" transform="translate(100, 0)">
     <rect width="10000" height="400" fill="red" clip-path="url(#clip2)"/>
-    <rect x="199" width="101" height="100" fill="green"/>
+    <rect x="195" width="105" height="100" fill="green"/>
   </g>
 </svg>

Added: releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/resource-clipper-multiple-repaints-expected.html (0 => 264098)


--- releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/resource-clipper-multiple-repaints-expected.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/resource-clipper-multiple-repaints-expected.html	2020-07-08 12:38:59 UTC (rev 264098)
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        .container {
+            position: relative;
+            width: 600px;
+            height: 400px;
+            border: 1px solid black;
+            overflow: hidden;
+        }
+        .composited {
+            position: absolute;
+            left: -200px;
+            width: 800px;
+            height: 100%;
+            transform: translateZ(1px);
+        }
+        #clipped {
+            margin-left: 200px;
+            width: 600px;
+            height: 400px;
+            background-color: green;
+            clip-path: url(#boxes);
+        }
+    </style>
+</head>
+<body>
+    <div class="container">
+        <div class="composited">
+            <div id="clipped"></div>
+        </div>
+    </div>
+    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" style="overflow: hidden;">
+        <defs>
+        <clipPath id="boxes" transform="matrix(1.8, 0, 0, 1.8, 20, 30)">
+            <path d="M50,50 L150,50 L150,150 L50,150 z" fill="transparent"></path>
+            <path d="M155,50 L255,50 L255,150 L155,150 z" fill="transparent"></path>
+        </clipPath>
+    </defs>
+</svg>
+</body>
+</html>

Added: releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/resource-clipper-multiple-repaints.html (0 => 264098)


--- releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/resource-clipper-multiple-repaints.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/svg/clip-path/resource-clipper-multiple-repaints.html	2020-07-08 12:38:59 UTC (rev 264098)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        .container {
+            position: relative;
+            width: 600px;
+            height: 400px;
+            border: 1px solid black;
+            overflow: hidden;
+        }
+        /* This creates a tiled layer so the clipped element is drawn across two tiles */
+        .composited {
+            position: absolute;
+            left: -200px;
+            width: 6600px;
+            height: 100%;
+            transform: translateZ(1px);
+        }
+        #clipped {
+            margin-left: 200px;
+            width: 600px;
+            height: 400px;
+            background-color: green;
+            clip-path: url(#boxes);
+        }
+    </style>
+</head>
+<body>
+    <div class="container">
+        <div class="composited">
+            <div id="clipped"></div>
+        </div>
+    </div>
+    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" style="overflow: hidden;">
+        <defs>
+        <clipPath id="boxes" transform="matrix(1.8, 0, 0, 1.8, 20, 30)">
+            <path d="M50,50 L150,50 L150,150 L50,150 z" fill="transparent"></path>
+            <path d="M155,50 L255,50 L255,150 L155,150 z" fill="transparent"></path>
+        </clipPath>
+    </defs>
+</svg>
+</body>
+</html>

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/ChangeLog (264097 => 264098)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/ChangeLog	2020-07-08 11:26:08 UTC (rev 264097)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/ChangeLog	2020-07-08 12:38:59 UTC (rev 264098)
@@ -1,3 +1,39 @@
+2020-03-27  Simon Fraser  <[email protected]>
+
+        Hovering over countries at https://covidinc.io/ shows bizarre rendering artifacts
+        https://bugs.webkit.org/show_bug.cgi?id=209635
+        <rdar://problem/60935010>
+
+        Reviewed by Said Abou-Hallawa.
+
+        RenderSVGResourceClipper::applyClippingToContext() cached an ImageBuffer per RenderObject
+        when using a image buffer mask. However, the function created and rendered into this image buffer
+        using repaintRect, which can change between invocations. Painting with different repaintRects
+        is very common when rendering into page tiles.
+
+        The buffer can only be re-used if the inputs used to create the buffer (objectBoundingBox, absoluteTransform)
+        are the same, so store those and compare them when determining when to use the cached buffer, and
+        don't use repaintRect when setting up the buffer.
+
+        This revealed another problem where renderers with visual overflow could be truncated by
+        the clipping, tested by imported/mozilla/svg/svg-integration/clipPath-html-03.xhtml, which occurred
+        because RenderLayer::setupClipPath() used the 'svgReferenceBox' for the clipping bounds, which
+        is the content box of the renderer excluding overflow. Fix this by using the bounds of the layer,
+        which includes the bounds of descendants.
+
+        Tests: svg/clip-path/clip-path-on-overflowing.html
+               svg/clip-path/resource-clipper-multiple-repaints.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::setupClipPath):
+        * rendering/svg/RenderSVGResourceClipper.cpp:
+        (WebCore::RenderSVGResourceClipper::removeAllClientsFromCache):
+        (WebCore::RenderSVGResourceClipper::applyClippingToContext):
+        (WebCore::RenderSVGResourceClipper::drawContentIntoMaskImage):
+        (WebCore::RenderSVGResourceClipper::addRendererToClipper):
+        (WebCore::RenderSVGResourceClipper::resourceBoundingBox):
+        * rendering/svg/RenderSVGResourceClipper.h:
+
 2020-05-14  Philippe Normand  <[email protected]>
 
         [GStreamer] Can't replay blob videos in web.whatsapp.com

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/RenderLayer.cpp (264097 => 264098)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/RenderLayer.cpp	2020-07-08 11:26:08 UTC (rev 264097)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/RenderLayer.cpp	2020-07-08 12:38:59 UTC (rev 264098)
@@ -4414,7 +4414,7 @@
 
 bool RenderLayer::setupClipPath(GraphicsContext& context, const LayerPaintingInfo& paintingInfo, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)
 {
-    if (!renderer().hasClipPath() || context.paintingDisabled())
+    if (!renderer().hasClipPath() || context.paintingDisabled() || paintingInfo.paintDirtyRect.isEmpty())
         return false;
 
     if (!rootRelativeBoundsComputed) {
@@ -4442,13 +4442,12 @@
         Element* element = renderer().document().getElementById(referenceClipPathOperation->fragment());
         if (element && element->renderer() && is<RenderSVGResourceClipper>(element->renderer())) {
             context.save();
-            float deviceSaleFactor = renderer().document().deviceScaleFactor();
-            FloatRect referenceBox = snapRectToDevicePixels(computeReferenceBox(renderer(), CSSBoxType::ContentBox, paintingOffsetFromRoot, rootRelativeBounds), deviceSaleFactor);
-            FloatPoint offset {referenceBox.location()};
+            auto referenceBox = snapRectToDevicePixels(rootRelativeBounds, renderer().document().deviceScaleFactor());
+            auto offset = referenceBox.location();
             context.translate(offset);
-            FloatRect svgReferenceBox {FloatPoint(), referenceBox.size()};
-            downcast<RenderSVGResourceClipper>(*element->renderer()).applyClippingToContext(renderer(), svgReferenceBox, paintingInfo.paintDirtyRect, context);
-            context.translate(FloatPoint(-offset.x(), -offset.y()));
+            FloatRect svgReferenceBox { {}, referenceBox.size() };
+            downcast<RenderSVGResourceClipper>(*element->renderer()).applyClippingToContext(renderer(), svgReferenceBox, context);
+            context.translate(-offset);
             return true;
         }
     }

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp (264097 => 264098)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp	2020-07-08 11:26:08 UTC (rev 264097)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp	2020-07-08 12:38:59 UTC (rev 264098)
@@ -30,6 +30,7 @@
 #include "HitTestResult.h"
 #include "IntRect.h"
 #include "RenderObject.h"
+#include "Logging.h"
 #include "RenderStyle.h"
 #include "RenderView.h"
 #include "SVGNames.h"
@@ -38,6 +39,7 @@
 #include "SVGResourcesCache.h"
 #include "SVGUseElement.h"
 #include <wtf/IsoMallocInlines.h>
+#include <wtf/text/TextStream.h>
 
 namespace WebCore {
 
@@ -52,7 +54,7 @@
 
 void RenderSVGResourceClipper::removeAllClientsFromCache(bool markForInvalidation)
 {
-    m_clipBoundaries = FloatRect();
+    m_clipBoundaries = { };
     m_clipper.clear();
 
     markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInvalidation : ParentOnlyInvalidation);
@@ -70,7 +72,11 @@
     ASSERT(context);
     ASSERT_UNUSED(resourceMode, !resourceMode);
 
-    return applyClippingToContext(renderer, renderer.objectBoundingBox(), renderer.repaintRectInLocalCoordinates(), *context);
+    auto repaintRect = renderer.repaintRectInLocalCoordinates();
+    if (repaintRect.isEmpty())
+        return true;
+
+    return applyClippingToContext(renderer, renderer.objectBoundingBox(), *context);
 }
 
 bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext& context, const AffineTransform& animatedLocalTransform, const FloatRect& objectBoundingBox)
@@ -128,25 +134,27 @@
     return true;
 }
 
-bool RenderSVGResourceClipper::applyClippingToContext(RenderElement& renderer, const FloatRect& objectBoundingBox, const FloatRect& repaintRect, GraphicsContext& context)
+bool RenderSVGResourceClipper::applyClippingToContext(RenderElement& renderer, const FloatRect& objectBoundingBox, GraphicsContext& context)
 {
-    ClipperMaskImage& clipperMaskImage = addRendererToClipper(renderer);
-    bool shouldCreateClipperMaskImage = !clipperMaskImage;
+    ClipperData& clipperData = addRendererToClipper(renderer);
+    
+    LOG_WITH_STREAM(SVG, stream << "RenderSVGResourceClipper " << this << " applyClippingToContext: renderer " << &renderer << " objectBoundingBox " << objectBoundingBox << " (existing image buffer " << clipperData.imageBuffer.get() << ")");
 
     AffineTransform animatedLocalTransform = clipPathElement().animatedLocalTransform();
 
-    if (shouldCreateClipperMaskImage && pathOnlyClipping(context, animatedLocalTransform, objectBoundingBox))
+    if (!clipperData.imageBuffer && pathOnlyClipping(context, animatedLocalTransform, objectBoundingBox))
         return true;
 
     AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
-
-    if (shouldCreateClipperMaskImage && !repaintRect.isEmpty()) {
+    if (!clipperData.isValidForGeometry(objectBoundingBox, absoluteTransform)) {
         // FIXME (149469): This image buffer should not be unconditionally unaccelerated. Making it match the context breaks nested clipping, though.
-        clipperMaskImage = SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, ColorSpace::SRGB, RenderingMode::Unaccelerated, &context);
-        if (!clipperMaskImage)
+        auto maskImage = SVGRenderingContext::createImageBuffer(objectBoundingBox, absoluteTransform, ColorSpace::SRGB, RenderingMode::Unaccelerated, &context);
+        if (!maskImage)
             return false;
 
-        GraphicsContext& maskContext = clipperMaskImage->context();
+        clipperData = { WTFMove(maskImage), objectBoundingBox, absoluteTransform };
+
+        GraphicsContext& maskContext = clipperData.imageBuffer->context();
         maskContext.concatCTM(animatedLocalTransform);
 
         // clipPath can also be clipped by another clipPath.
@@ -156,31 +164,29 @@
         if (resources && (clipper = resources->clipper())) {
             GraphicsContextStateSaver stateSaver(maskContext);
 
-            if (!clipper->applyClippingToContext(*this, objectBoundingBox, repaintRect, maskContext))
+            if (!clipper->applyClippingToContext(*this, objectBoundingBox, maskContext))
                 return false;
 
-            succeeded = drawContentIntoMaskImage(clipperMaskImage, objectBoundingBox);
+            succeeded = drawContentIntoMaskImage(*clipperData.imageBuffer, objectBoundingBox);
             // The context restore applies the clipping on non-CG platforms.
         } else
-            succeeded = drawContentIntoMaskImage(clipperMaskImage, objectBoundingBox);
+            succeeded = drawContentIntoMaskImage(*clipperData.imageBuffer, objectBoundingBox);
 
         if (!succeeded)
-            clipperMaskImage.reset();
+            clipperData = { };
     }
 
-    if (!clipperMaskImage)
+    if (!clipperData.imageBuffer)
         return false;
 
-    SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, repaintRect, clipperMaskImage, shouldCreateClipperMaskImage);
+    SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, objectBoundingBox, clipperData.imageBuffer, true);
     return true;
 }
 
-bool RenderSVGResourceClipper::drawContentIntoMaskImage(const ClipperMaskImage& clipperMaskImage, const FloatRect& objectBoundingBox)
+bool RenderSVGResourceClipper::drawContentIntoMaskImage(ImageBuffer& maskImageBuffer, const FloatRect& objectBoundingBox)
 {
-    ASSERT(clipperMaskImage);
+    GraphicsContext& maskContext = maskImageBuffer.context();
 
-    GraphicsContext& maskContext = clipperMaskImage->context();
-
     AffineTransform maskContentTransformation;
     if (clipPathElement().clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
         maskContentTransformation.translate(objectBoundingBox.location());
@@ -229,7 +235,7 @@
         // In the case of a <use> element, we obtained its renderere above, to retrieve its clipRule.
         // We have to pass the <use> renderer itself to renderSubtreeToImageBuffer() to apply it's x/y/transform/etc. values when rendering.
         // So if isUseElement is true, refetch the childNode->renderer(), as renderer got overridden above.
-        SVGRenderingContext::renderSubtreeToImageBuffer(clipperMaskImage.get(), isUseElement ? *child.renderer() : *renderer, maskContentTransformation);
+        SVGRenderingContext::renderSubtreeToImageBuffer(&maskImageBuffer, isUseElement ? *child.renderer() : *renderer, maskContentTransformation);
     }
 
     view().frameView().setPaintBehavior(oldBehavior);
@@ -253,9 +259,9 @@
     m_clipBoundaries = clipPathElement().animatedLocalTransform().mapRect(m_clipBoundaries);
 }
 
-ClipperMaskImage& RenderSVGResourceClipper::addRendererToClipper(const RenderObject& object)
+RenderSVGResourceClipper::ClipperData& RenderSVGResourceClipper::addRendererToClipper(const RenderObject& object)
 {
-    return m_clipper.add(&object, ClipperMaskImage()).iterator->value;
+    return m_clipper.add(&object, ClipperData()).iterator->value;
 }
 
 bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint)
@@ -302,7 +308,7 @@
 {
     // Resource was not layouted yet. Give back the boundingBox of the object.
     if (selfNeedsLayout()) {
-        addRendererToClipper(object);
+        addRendererToClipper(object); // For selfNeedsClientInvalidation().
         return object.objectBoundingBox();
     }
     

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h (264097 => 264098)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h	2020-07-08 11:26:08 UTC (rev 264097)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h	2020-07-08 12:38:59 UTC (rev 264098)
@@ -30,8 +30,6 @@
 class GraphicsContext;
 class ImageBuffer;
 
-typedef std::unique_ptr<ImageBuffer> ClipperMaskImage;
-
 class RenderSVGResourceClipper final : public RenderSVGResourceContainer {
     WTF_MAKE_ISO_ALLOCATED(RenderSVGResourceClipper);
 public:
@@ -47,7 +45,7 @@
     // clipPath can be clipped too, but don't have a boundingBox or repaintRect. So we can't call
     // applyResource directly and use the rects from the object, since they are empty for RenderSVGResources
     // FIXME: We made applyClippingToContext public because we cannot call applyResource on HTML elements (it asserts on RenderObject::objectBoundingBox)
-    bool applyClippingToContext(RenderElement&, const FloatRect&, const FloatRect&, GraphicsContext&);
+    bool applyClippingToContext(RenderElement&, const FloatRect&, GraphicsContext&);
     FloatRect resourceBoundingBox(const RenderObject&) override;
 
     RenderSVGResourceType resourceType() const override { return ClipperResourceType; }
@@ -60,6 +58,25 @@
     bool selfNeedsClientInvalidation() const override { return (everHadLayout() || m_clipper.size()) && selfNeedsLayout(); }
 
 private:
+    struct ClipperData {
+        FloatRect objectBoundingBox;
+        AffineTransform absoluteTransform;
+        std::unique_ptr<ImageBuffer> imageBuffer;
+        
+        ClipperData() = default;
+        ClipperData(std::unique_ptr<ImageBuffer>&& buffer, const FloatRect& boundingBox, const AffineTransform& transform)
+            : objectBoundingBox(boundingBox)
+            , absoluteTransform(transform)
+            , imageBuffer(WTFMove(buffer))
+        {
+        }
+
+        bool isValidForGeometry(const FloatRect& boundingBox, const AffineTransform& transform) const
+        {
+            return imageBuffer && objectBoundingBox == boundingBox && absoluteTransform == transform;
+        }
+    };
+
     void element() const = delete;
 
     const char* renderName() const override { return "RenderSVGResourceClipper"; }
@@ -66,12 +83,12 @@
     bool isSVGResourceClipper() const override { return true; }
 
     bool pathOnlyClipping(GraphicsContext&, const AffineTransform&, const FloatRect&);
-    bool drawContentIntoMaskImage(const ClipperMaskImage&, const FloatRect& objectBoundingBox);
+    bool drawContentIntoMaskImage(ImageBuffer&, const FloatRect& objectBoundingBox);
     void calculateClipContentRepaintRect();
-    ClipperMaskImage& addRendererToClipper(const RenderObject&);
+    ClipperData& addRendererToClipper(const RenderObject&);
 
     FloatRect m_clipBoundaries;
-    HashMap<const RenderObject*, ClipperMaskImage> m_clipper;
+    HashMap<const RenderObject*, ClipperData> m_clipper;
 };
 
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to