Title: [285481] trunk
Revision
285481
Author
[email protected]
Date
2021-11-08 23:39:20 -0800 (Mon, 08 Nov 2021)

Log Message

[GPU Process] Remove non-platform code form the FEImage class
https://bugs.webkit.org/show_bug.cgi?id=232369
rdar://84966765

Reviewed by Simon Fraser.

Source/WebCore:

SVGFEImageElement should create the FEImage with either an Image or an
ImageBuffer based on whether the 'href' attribute points to a resource
image or an SVG element. For the SVG element, an ImageBuffer will be
created and the renderer of this element will be drawn to it.

Instead of holding a TreeScope and Image, FEImage can hold a variant of
Image and ImageBuffer.

Tests: svg/filters/feImage-element-primitive-subregion-expected.svg
       svg/filters/feImage-element-primitive-subregion.svg
       svg/filters/feImage-image-primitive-subregion-expected.svg
       svg/filters/feImage-image-primitive-subregion.svg

* svg/SVGFEImageElement.cpp:
(WebCore::SVGFEImageElement::imageBufferForEffect const):
(WebCore::SVGFEImageElement::build const):
* svg/SVGFEImageElement.h:
* svg/graphics/filters/SVGFEImage.cpp:
(WebCore::FEImage::create):
(WebCore::FEImage::FEImage):
(WebCore::FEImage::determineAbsolutePaintRect):
(WebCore::FEImage::platformApplySoftware):
(WebCore::FEImage::externalRepresentation const):
(WebCore::FEImage::createWithImage): Deleted.
(WebCore::FEImage::createWithIRIReference): Deleted.
(WebCore::FEImage::referencedRenderer const): Deleted.
* svg/graphics/filters/SVGFEImage.h:

LayoutTests:

* fast/shadow-dom/svg-feimage-href-in-shadow-tree.html:
The default primitive subregion of <feImage> is { -10%, -10%, 120%, 120% }
of the bounding box. So the filter result will be shifted (-10, -10) of
this test case if we do not specify the 'x' and then 'y' attributes.
Unlike the Image based feImage, the default behavior is to display the
ImageBuffer of the element with its logical size otherwise the drawing
will be pixelated if we try to fill the whole primitive subregion. To
make this test page matches its expected page, we need to specify the 'x'
and the 'y' attributes of the <feImage> to be zeros.

With and without specifying the 'x' and the 'y' attributes, the drawing
with this patch matches the drawing of this test page in other browsers.

* svg/filters/feImage-change-target-id-expected.txt:
* svg/filters/feImage-element-primitive-subregion-expected.svg: Added.
* svg/filters/feImage-element-primitive-subregion.svg: Added.
* svg/filters/feImage-image-primitive-subregion-expected.svg: Added.
* svg/filters/feImage-image-primitive-subregion.svg: Added.
* svg/filters/feImage-remove-target-expected.txt:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (285480 => 285481)


--- trunk/LayoutTests/ChangeLog	2021-11-09 04:35:03 UTC (rev 285480)
+++ trunk/LayoutTests/ChangeLog	2021-11-09 07:39:20 UTC (rev 285481)
@@ -1,3 +1,31 @@
+2021-11-08  Said Abou-Hallawa  <[email protected]>
+
+        [GPU Process] Remove non-platform code form the FEImage class
+        https://bugs.webkit.org/show_bug.cgi?id=232369
+        rdar://84966765
+
+        Reviewed by Simon Fraser.
+
+        * fast/shadow-dom/svg-feimage-href-in-shadow-tree.html:
+        The default primitive subregion of <feImage> is { -10%, -10%, 120%, 120% }
+        of the bounding box. So the filter result will be shifted (-10, -10) of
+        this test case if we do not specify the 'x' and then 'y' attributes.
+        Unlike the Image based feImage, the default behavior is to display the
+        ImageBuffer of the element with its logical size otherwise the drawing
+        will be pixelated if we try to fill the whole primitive subregion. To
+        make this test page matches its expected page, we need to specify the 'x'
+        and the 'y' attributes of the <feImage> to be zeros.
+
+        With and without specifying the 'x' and the 'y' attributes, the drawing
+        with this patch matches the drawing of this test page in other browsers.
+
+        * svg/filters/feImage-change-target-id-expected.txt:
+        * svg/filters/feImage-element-primitive-subregion-expected.svg: Added.
+        * svg/filters/feImage-element-primitive-subregion.svg: Added.
+        * svg/filters/feImage-image-primitive-subregion-expected.svg: Added.
+        * svg/filters/feImage-image-primitive-subregion.svg: Added.
+        * svg/filters/feImage-remove-target-expected.txt:
+
 2021-11-08  Patrick Griffis  <[email protected]>
 
         Implement nonce-hiding

Modified: trunk/LayoutTests/fast/shadow-dom/svg-feimage-href-in-shadow-tree.html (285480 => 285481)


--- trunk/LayoutTests/fast/shadow-dom/svg-feimage-href-in-shadow-tree.html	2021-11-09 04:35:03 UTC (rev 285480)
+++ trunk/LayoutTests/fast/shadow-dom/svg-feimage-href-in-shadow-tree.html	2021-11-09 07:39:20 UTC (rev 285481)
@@ -13,7 +13,7 @@
         <defs>
             <rect id="rect" width="100" height="100" fill="green" />
             <filter id="image">
-                <feImage href="" />
+                <feImage x="0" y="0" href="" />
             </filter>
         </defs>
         <rect id="rect" width="100" height="100" style="filter:url(#image)">

Modified: trunk/LayoutTests/svg/filters/feImage-change-target-id-expected.txt (285480 => 285481)


--- trunk/LayoutTests/svg/filters/feImage-change-target-id-expected.txt	2021-11-09 04:35:03 UTC (rev 285480)
+++ trunk/LayoutTests/svg/filters/feImage-change-target-id-expected.txt	2021-11-09 07:39:20 UTC (rev 285481)
@@ -5,6 +5,5 @@
     RenderSVGHiddenContainer {defs} at (0,0) size 0x0
       RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
       RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
-        [feImage image-size="0.00x0.00"]
     RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
       [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120

Added: trunk/LayoutTests/svg/filters/feImage-element-primitive-subregion-expected.svg (0 => 285481)


--- trunk/LayoutTests/svg/filters/feImage-element-primitive-subregion-expected.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/filters/feImage-element-primitive-subregion-expected.svg	2021-11-09 07:39:20 UTC (rev 285481)
@@ -0,0 +1,23 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+    <defs>
+        <rect id="red-rectangle" x="-100" y="-100" width="200" height="200" fill="red"/>
+        <path id="green-triangle" d="M 0 0 L 150 0 L 150 150 z" fill="green"/>
+        <path id="blue-triangle"  d="M 0 0 L 0 150 L 150 0 z" fill="blue"/>
+        <clipPath id="square-clip">
+            <rect width="100" height="100"/>
+        </clipPath>
+    </defs>
+    <g>
+        <g transform="translate(50, 50)">
+            <use clip-path="url(#square-clip)" href="" />
+        </g>
+
+        <g transform="translate(200, 50)">
+            <use clip-path="url(#square-clip)" href="" />
+        </g>
+
+        <g transform="translate(350, 50)">
+            <use clip-path="url(#square-clip)" href="" />
+        </g>
+    </g>
+</svg>

Added: trunk/LayoutTests/svg/filters/feImage-element-primitive-subregion.svg (0 => 285481)


--- trunk/LayoutTests/svg/filters/feImage-element-primitive-subregion.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/filters/feImage-element-primitive-subregion.svg	2021-11-09 07:39:20 UTC (rev 285481)
@@ -0,0 +1,31 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+    <defs>
+        <rect id="red-rectangle" x="-100" y="-100" width="200" height="200" fill="red"/>
+        <path id="green-triangle" d="M 0 0 L 150 0 L 150 150 z" fill="green"/>
+        <path id="blue-triangle"  d="M 0 0 L 0 150 L 150 0 z" fill="blue"/>
+
+        <filter id="red-rectangle-filter" x="0" y="0" width="1" height="1">
+            <feImage href=""
+        </filter>
+
+        <filter id="green-triangle-filter" x="0" y="0" width="1" height="1">
+            <feImage href=""
+        </filter>
+
+        <filter id="blue-triangle-filter" x="0" y="0" width="1" height="1">
+            <feImage href=""
+        </filter>
+    </defs>
+    <g>
+        <g transform="translate(50, 50)">
+            <rect width="100" height="100" style="filter:url(#red-rectangle-filter)"/>
+        </g>
+
+        <g transform="translate(200, 50)">
+            <rect width="100" height="100" style="filter:url(#green-triangle-filter)"/>
+        </g>
+        <g transform="translate(350, 50)">
+            <rect width="100" height="100" style="filter:url(#blue-triangle-filter)"/>
+        </g>
+    </g>
+</svg>

Added: trunk/LayoutTests/svg/filters/feImage-image-primitive-subregion-expected.svg (0 => 285481)


--- trunk/LayoutTests/svg/filters/feImage-image-primitive-subregion-expected.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/filters/feImage-image-primitive-subregion-expected.svg	2021-11-09 07:39:20 UTC (rev 285481)
@@ -0,0 +1,10 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+    <g>
+        <image x="40" y="65" width="120" height="120" href=""
+        <rect x="50" y="25" width="100" height="200" fill="none" stroke="green"/>
+        <image x="250" y="25" width="100" height="200" href="" preserveAspectRatio="none"/>
+        <rect x="250" y="25" width="100" height="200" fill="none" stroke="green"/>
+        <image x="500" y="65" width="60" height="120" href="" preserveAspectRatio="none"/>
+        <rect x="450" y="25" width="100" height="200" fill="none" stroke="green"/>
+    </g>
+</svg>

Added: trunk/LayoutTests/svg/filters/feImage-image-primitive-subregion.svg (0 => 285481)


--- trunk/LayoutTests/svg/filters/feImage-image-primitive-subregion.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/filters/feImage-image-primitive-subregion.svg	2021-11-09 07:39:20 UTC (rev 285481)
@@ -0,0 +1,21 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+    <defs>
+        <filter id="Default">
+            <feImage href="" />
+        </filter>
+        <filter id="Fitted" primitiveUnits="objectBoundingBox">
+            <feImage href="" x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"/>
+        </filter>
+        <filter id="Shifted">
+            <feImage href="" x="500" y="5"/>
+        </filter>
+    </defs>
+    <g>
+        <rect x="50"  y="25" width="100" height="200" filter="url(#Default)"/>
+        <rect x="50"  y="25" width="100" height="200" fill="none" stroke="green"/>
+        <rect x="250" y="25" width="100" height="200" filter="url(#Fitted)"/>
+        <rect x="250" y="25" width="100" height="200" fill="none" stroke="green"/>
+        <rect x="450" y="25" width="100" height="200" filter="url(#Shifted)"/>
+        <rect x="450" y="25" width="100" height="200" fill="none" stroke="green"/>
+    </g>
+</svg>

Modified: trunk/LayoutTests/svg/filters/feImage-remove-target-expected.txt (285480 => 285481)


--- trunk/LayoutTests/svg/filters/feImage-remove-target-expected.txt	2021-11-09 04:35:03 UTC (rev 285480)
+++ trunk/LayoutTests/svg/filters/feImage-remove-target-expected.txt	2021-11-09 07:39:20 UTC (rev 285481)
@@ -4,6 +4,5 @@
   RenderSVGRoot {svg} at (0,0) size 111x111
     RenderSVGHiddenContainer {defs} at (0,0) size 0x0
       RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
-        [feImage image-size="0.00x0.00"]
     RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
       [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120

Modified: trunk/Source/WebCore/ChangeLog (285480 => 285481)


--- trunk/Source/WebCore/ChangeLog	2021-11-09 04:35:03 UTC (rev 285480)
+++ trunk/Source/WebCore/ChangeLog	2021-11-09 07:39:20 UTC (rev 285481)
@@ -1,3 +1,39 @@
+2021-11-08  Said Abou-Hallawa  <[email protected]>
+
+        [GPU Process] Remove non-platform code form the FEImage class
+        https://bugs.webkit.org/show_bug.cgi?id=232369
+        rdar://84966765
+
+        Reviewed by Simon Fraser.
+
+        SVGFEImageElement should create the FEImage with either an Image or an 
+        ImageBuffer based on whether the 'href' attribute points to a resource
+        image or an SVG element. For the SVG element, an ImageBuffer will be 
+        created and the renderer of this element will be drawn to it.
+
+        Instead of holding a TreeScope and Image, FEImage can hold a variant of
+        Image and ImageBuffer.
+
+        Tests: svg/filters/feImage-element-primitive-subregion-expected.svg
+               svg/filters/feImage-element-primitive-subregion.svg
+               svg/filters/feImage-image-primitive-subregion-expected.svg
+               svg/filters/feImage-image-primitive-subregion.svg
+
+        * svg/SVGFEImageElement.cpp:
+        (WebCore::SVGFEImageElement::imageBufferForEffect const):
+        (WebCore::SVGFEImageElement::build const):
+        * svg/SVGFEImageElement.h:
+        * svg/graphics/filters/SVGFEImage.cpp:
+        (WebCore::FEImage::create):
+        (WebCore::FEImage::FEImage):
+        (WebCore::FEImage::determineAbsolutePaintRect):
+        (WebCore::FEImage::platformApplySoftware):
+        (WebCore::FEImage::externalRepresentation const):
+        (WebCore::FEImage::createWithImage): Deleted.
+        (WebCore::FEImage::createWithIRIReference): Deleted.
+        (WebCore::FEImage::referencedRenderer const): Deleted.
+        * svg/graphics/filters/SVGFEImage.h:
+
 2021-11-08  Patrick Griffis  <[email protected]>
 
         Implement nonce-hiding

Modified: trunk/Source/WebCore/svg/SVGFEImageElement.cpp (285480 => 285481)


--- trunk/Source/WebCore/svg/SVGFEImageElement.cpp	2021-11-09 04:35:03 UTC (rev 285480)
+++ trunk/Source/WebCore/svg/SVGFEImageElement.cpp	2021-11-09 07:39:20 UTC (rev 285481)
@@ -2,7 +2,7 @@
  * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <[email protected]>
  * Copyright (C) 2004, 2005 Rob Buis <[email protected]>
  * Copyright (C) 2010 Dirk Schulze <[email protected]>
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -33,6 +33,7 @@
 #include "SVGElementInlines.h"
 #include "SVGNames.h"
 #include "SVGPreserveAspectRatioValue.h"
+#include "SVGRenderingContext.h"
 #include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
@@ -175,16 +176,48 @@
     RenderSVGResource::markForLayoutAndParentResourceInvalidation(*parentRenderer);
 }
 
+std::tuple<RefPtr<ImageBuffer>, FloatRect> SVGFEImageElement::imageBufferForEffect() const
+{
+    auto target = SVGURIReference::targetElementFromIRIString(href(), treeScope());
+    if (!is<SVGElement>(target.element))
+        return { };
+
+    if (isDescendantOrShadowDescendantOf(target.element.get()))
+        return { };
+
+    auto contextNode = static_pointer_cast<SVGElement>(target.element);
+    auto renderer = contextNode->renderer();
+    if (!renderer)
+        return { };
+
+    auto absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(*renderer);
+    if (!absoluteTransform.isInvertible())
+        return { };
+
+    auto shearFreeAbsoluteTransform = AffineTransform(absoluteTransform.xScale(), 0, 0, absoluteTransform.yScale(), 0, 0);
+
+    auto imageRect = renderer->repaintRectInLocalCoordinates();
+
+    auto imageBuffer = SVGRenderingContext::createImageBuffer(imageRect, shearFreeAbsoluteTransform, DestinationColorSpace::SRGB(), RenderingMode::Unaccelerated);
+    if (!imageBuffer)
+        return { };
+
+    auto& context = imageBuffer->context();
+    SVGRenderingContext::renderSubtreeToContext(context, *renderer, AffineTransform());
+
+    return { imageBuffer, imageRect };
+}
+
 RefPtr<FilterEffect> SVGFEImageElement::build(SVGFilterBuilder*, Filter& filter) const
 {
     if (m_cachedImage)
-        return FEImage::createWithImage(filter, m_cachedImage->imageForRenderer(renderer()), preserveAspectRatio());
+        return FEImage::create(filter, Ref<Image> { *m_cachedImage->imageForRenderer(renderer()) }, preserveAspectRatio());
 
-    auto target = SVGURIReference::targetElementFromIRIString(href(), treeScope());
-    if (isDescendantOrShadowDescendantOf(target.element.get()))
+    auto [imageBuffer, imageRect] = imageBufferForEffect();
+    if (!imageBuffer)
         return nullptr;
 
-    return FEImage::createWithIRIReference(filter, treeScope(), href(), preserveAspectRatio());
+    return FEImage::create(filter, imageBuffer.releaseNonNull(), imageRect, preserveAspectRatio());
 }
 
 void SVGFEImageElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const

Modified: trunk/Source/WebCore/svg/SVGFEImageElement.h (285480 => 285481)


--- trunk/Source/WebCore/svg/SVGFEImageElement.h	2021-11-09 04:35:03 UTC (rev 285480)
+++ trunk/Source/WebCore/svg/SVGFEImageElement.h	2021-11-09 07:39:20 UTC (rev 285481)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <[email protected]>
  * Copyright (C) 2004, 2005 Rob Buis <[email protected]>
- * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -55,6 +55,8 @@
 
     void didFinishInsertingNode() override;
 
+    std::tuple<RefPtr<ImageBuffer>, FloatRect> imageBufferForEffect() const;
+
     RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) const override;
 
     void clearResourceReferences();

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp (285480 => 285481)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp	2021-11-09 04:35:03 UTC (rev 285480)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp	2021-11-09 07:39:20 UTC (rev 285481)
@@ -3,6 +3,7 @@
  * Copyright (C) 2004, 2005 Rob Buis <[email protected]>
  * Copyright (C) 2005 Eric Seidel <[email protected]>
  * Copyright (C) 2010 Dirk Schulze <[email protected]>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -23,76 +24,58 @@
 #include "config.h"
 #include "SVGFEImage.h"
 
-#include "AffineTransform.h"
 #include "Filter.h"
 #include "GraphicsContext.h"
-#include "RenderElement.h"
-#include "RenderTreeAsText.h"
-#include "SVGElement.h"
-#include "SVGRenderingContext.h"
-#include "SVGURIReference.h"
 #include <wtf/text/TextStream.h>
 
 namespace WebCore {
 
-FEImage::FEImage(Filter& filter, RefPtr<Image> image, const SVGPreserveAspectRatioValue& preserveAspectRatio)
-    : FilterEffect(filter, Type::Image)
-    , m_image(image)
-    , m_preserveAspectRatio(preserveAspectRatio)
+Ref<FEImage> FEImage::create(Filter& filter, Ref<Image>&& image, const SVGPreserveAspectRatioValue& preserveAspectRatio)
 {
+    auto imageRect = FloatRect { { }, image->size() };
+    return create(filter, WTFMove(image), imageRect, preserveAspectRatio);
 }
 
-FEImage::FEImage(Filter& filter, TreeScope& treeScope, const String& href, const SVGPreserveAspectRatioValue& preserveAspectRatio)
-    : FilterEffect(filter, Type::Image)
-    , m_treeScope(&treeScope)
-    , m_href(href)
-    , m_preserveAspectRatio(preserveAspectRatio)
+Ref<FEImage> FEImage::create(Filter& filter, SourceImage&& sourceImage, const FloatRect& sourceImageRect, const SVGPreserveAspectRatioValue& preserveAspectRatio)
 {
+    return adoptRef(*new FEImage(filter, WTFMove(sourceImage), sourceImageRect, preserveAspectRatio));
 }
 
-Ref<FEImage> FEImage::createWithImage(Filter& filter, RefPtr<Image> image, const SVGPreserveAspectRatioValue& preserveAspectRatio)
+FEImage::FEImage(Filter& filter, SourceImage&& sourceImage, const FloatRect& sourceImageRect, const SVGPreserveAspectRatioValue& preserveAspectRatio)
+    : FilterEffect(filter, Type::Image)
+    , m_sourceImage(WTFMove(sourceImage))
+    , m_sourceImageRect(sourceImageRect)
+    , m_preserveAspectRatio(preserveAspectRatio)
 {
-    return adoptRef(*new FEImage(filter, image, preserveAspectRatio));
 }
 
-Ref<FEImage> FEImage::createWithIRIReference(Filter& filter, TreeScope& treeScope, const String& href, const SVGPreserveAspectRatioValue& preserveAspectRatio)
-{
-    return adoptRef(*new FEImage(filter, treeScope, href, preserveAspectRatio));
-}
-
 void FEImage::determineAbsolutePaintRect()
 {
-    FloatRect paintRect = filter().absoluteTransform().mapRect(filterPrimitiveSubregion());
-    FloatRect srcRect;
-    if (m_image) {
-        srcRect.setSize(m_image->size());
-        m_preserveAspectRatio.transformRect(paintRect, srcRect);
-    } else if (RenderElement* renderer = referencedRenderer())
-        srcRect = filter().absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates());
+    auto primitiveSubregion = filterPrimitiveSubregion();
 
+    auto imageRect = WTF::switchOn(m_sourceImage,
+        [&] (const Ref<Image>&) {
+            auto imageRect = primitiveSubregion;
+            auto srcRect = m_sourceImageRect;
+            m_preserveAspectRatio.transformRect(imageRect, srcRect);
+            return imageRect;
+        },
+        [&] (const Ref<ImageBuffer>&) {
+            return primitiveSubregion;
+        }
+    );
+
+    imageRect = filter().absoluteTransform().mapRect(imageRect);
+
     if (clipsToBounds())
-        paintRect.intersect(maxEffectRect());
+        imageRect.intersect(maxEffectRect());
     else
-        paintRect.unite(maxEffectRect());
-    setAbsolutePaintRect(enclosingIntRect(paintRect));
+        imageRect.unite(maxEffectRect());
+    setAbsolutePaintRect(enclosingIntRect(imageRect));
 }
 
-RenderElement* FEImage::referencedRenderer() const
-{
-    if (!m_treeScope)
-        return nullptr;
-    auto target = SVGURIReference::targetElementFromIRIString(m_href, *m_treeScope);
-    if (!is<SVGElement>(target.element))
-        return nullptr;
-    return target.element->renderer();
-}
-
 void FEImage::platformApplySoftware()
 {
-    RenderElement* renderer = referencedRenderer();
-    if (!m_image && !renderer)
-        return;
-
     // FEImage results are always in DestinationColorSpace::SRGB()
     setResultColorSpace(DestinationColorSpace::SRGB());
 
@@ -100,54 +83,33 @@
     if (!resultImage)
         return;
 
-    FloatRect destRect = filter().absoluteTransform().mapRect(filterPrimitiveSubregion());
-
-    FloatRect srcRect;
-    if (renderer)
-        srcRect = filter().absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates());
-    else {
-        srcRect = FloatRect(FloatPoint(), m_image->size());
-        m_preserveAspectRatio.transformRect(destRect, srcRect);
-    }
-
-    IntPoint paintLocation = absolutePaintRect().location();
-    destRect.move(-paintLocation.x(), -paintLocation.y());
-
+    auto primitiveSubregion = filterPrimitiveSubregion();
     auto& context = resultImage->context();
 
-    if (renderer) {
-        const AffineTransform& absoluteTransform = filter().absoluteTransform();
-        context.concatCTM(absoluteTransform);
-
-        RefPtr contextNode = downcast<SVGElement>(renderer->element());
-        if (contextNode->hasRelativeLengths()) {
-            SVGLengthContext lengthContext(contextNode.get());
-            FloatSize viewportSize;
-
-            // If we're referencing an element with percentage units, eg. <rect with="30%"> those values were resolved against the viewport.
-            // Build up a transformation that maps from the viewport space to the filter primitive subregion.
-            if (lengthContext.determineViewport(viewportSize))
-                context.concatCTM(makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect));
+    WTF::switchOn(m_sourceImage,
+        [&] (const Ref<Image>& image) {
+            auto imageRect = primitiveSubregion;
+            auto srcRect = m_sourceImageRect;
+            m_preserveAspectRatio.transformRect(imageRect, srcRect);
+            imageRect = filter().absoluteTransform().mapRect(imageRect);
+            imageRect = drawingRegionOfInputImage(IntRect(imageRect));
+            context.drawImage(image, imageRect, srcRect);
+        },
+        [&] (const Ref<ImageBuffer>& imageBuffer) {
+            auto imageRect = primitiveSubregion;
+            imageRect.moveBy(m_sourceImageRect.location());
+            imageRect = filter().absoluteTransform().mapRect(imageRect);
+            imageRect = drawingRegionOfInputImage(IntRect(imageRect));
+            context.drawImageBuffer(imageBuffer, imageRect.location());
         }
-
-        AffineTransform contentTransformation;
-        SVGRenderingContext::renderSubtreeToContext(context, *renderer, contentTransformation);
-        return;
-    }
-
-    context.drawImage(*m_image, destRect, srcRect);
+    );
 }
 
 TextStream& FEImage::externalRepresentation(TextStream& ts, RepresentationType representation) const
 {
-    FloatSize imageSize;
-    if (m_image)
-        imageSize = m_image->size();
-    else if (RenderObject* renderer = referencedRenderer())
-        imageSize = enclosingIntRect(renderer->repaintRectInLocalCoordinates()).size();
     ts << indent << "[feImage";
     FilterEffect::externalRepresentation(ts, representation);
-    ts << " image-size=\"" << imageSize.width() << "x" << imageSize.height() << "\"]\n";
+    ts << " image-size=\"" << m_sourceImageRect.width() << "x" << m_sourceImageRect.height() << "\"]\n";
     // FIXME: should this dump also object returned by SVGFEImage::image() ?
     return ts;
 }

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h (285480 => 285481)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h	2021-11-09 04:35:03 UTC (rev 285480)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h	2021-11-09 07:39:20 UTC (rev 285481)
@@ -3,6 +3,7 @@
  * Copyright (C) 2004, 2005 Rob Buis <[email protected]>
  * Copyright (C) 2005 Eric Seidel <[email protected]>
  * Copyright (C) 2010 Dirk Schulze <[email protected]>
+ * Copyright (C) 2021 Apple Inc.  All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -23,40 +24,38 @@
 #pragma once
 
 #include "FilterEffect.h"
+#include "RenderingResourceIdentifier.h"
 #include "SVGPreserveAspectRatioValue.h"
 
 namespace WebCore {
 
-class Document;
 class Image;
-class RenderElement;
-class TreeScope;
+class ImageBuffer;
 
 class FEImage final : public FilterEffect {
 public:
-    static Ref<FEImage> createWithImage(Filter&, RefPtr<Image>, const SVGPreserveAspectRatioValue&);
-    static Ref<FEImage> createWithIRIReference(Filter&, TreeScope&, const String&, const SVGPreserveAspectRatioValue&);
+    using SourceImage = std::variant<
+        Ref<Image>,
+        Ref<ImageBuffer>
+    >;
 
+    static Ref<FEImage> create(Filter&, Ref<Image>&&, const SVGPreserveAspectRatioValue&);
+    static Ref<FEImage> create(Filter&, SourceImage&&, const FloatRect& sourceImageRect, const SVGPreserveAspectRatioValue&);
+
+    SourceImage& sourceImage() { return m_sourceImage; }
+    void setImageSource(SourceImage&& sourceImage) { m_sourceImage = WTFMove(sourceImage); }
+
 private:
-    virtual ~FEImage() = default;
-    FEImage(Filter&, RefPtr<Image>, const SVGPreserveAspectRatioValue&);
-    FEImage(Filter&, TreeScope&, const String&, const SVGPreserveAspectRatioValue&);
+    FEImage(Filter&, SourceImage&&, const FloatRect& sourceImageRect, const SVGPreserveAspectRatioValue&);
 
     const char* filterName() const final { return "FEImage"; }
 
-    FilterEffectType filterEffectType() const final { return FilterEffectTypeImage; }
-
-    RenderElement* referencedRenderer() const;
-
     void platformApplySoftware() final;
     void determineAbsolutePaintRect() final;
     WTF::TextStream& externalRepresentation(WTF::TextStream&, RepresentationType) const final;
 
-    RefPtr<Image> m_image;
-
-    // m_treeScope will never be a dangling reference. See https://bugs.webkit.org/show_bug.cgi?id=99243
-    TreeScope* m_treeScope { nullptr };
-    String m_href;
+    SourceImage m_sourceImage;
+    FloatRect m_sourceImageRect;
     SVGPreserveAspectRatioValue m_preserveAspectRatio;
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to