Title: [235644] trunk
Revision
235644
Author
simon.fra...@apple.com
Date
2018-09-04 15:51:47 -0700 (Tue, 04 Sep 2018)

Log Message

CSS reference filter that references a tiled feTurbulence is blank
https://bugs.webkit.org/show_bug.cgi?id=188950

Reviewed by Dean Jackson.
Source/WebCore:

We need to run the code that was in RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion()
for CSS reference filters, to set up the various rects in the filter effects.

Do this by moving the code to FilterEffect::determineFilterPrimitiveSubregion(), which makes sense
because it recurses on the FilterEffect input chain. To make it CSS/SVGFilter agnostic, we move filterRegionInUserSpace()
to the Filter base class (for CSSFilter, it just returns m_filterRegion).

Test: css3/filters/reference-filter-set-filter-regions.html

* platform/graphics/filters/Filter.h:
* platform/graphics/filters/FilterEffect.cpp:
(WebCore::FilterEffect::determineFilterPrimitiveSubregion):
* platform/graphics/filters/FilterEffect.h:
* rendering/CSSFilter.cpp:
(WebCore::CSSFilter::determineFilterPrimitiveSubregion):
* rendering/CSSFilter.h:
* rendering/RenderLayerFilters.cpp:
(WebCore::RenderLayerFilters::beginFilterEffect):
* rendering/svg/RenderSVGResourceFilter.cpp:
(WebCore::RenderSVGResourceFilter::applyResource):
* rendering/svg/RenderSVGResourceFilterPrimitive.cpp:
(WebCore::RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion): Deleted.
* rendering/svg/RenderSVGResourceFilterPrimitive.h:
* svg/graphics/filters/SVGFilter.h:

LayoutTests:

* css3/filters/reference-filter-set-filter-regions-expected.html: Added.
* css3/filters/reference-filter-set-filter-regions.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (235643 => 235644)


--- trunk/LayoutTests/ChangeLog	2018-09-04 22:16:44 UTC (rev 235643)
+++ trunk/LayoutTests/ChangeLog	2018-09-04 22:51:47 UTC (rev 235644)
@@ -1,3 +1,13 @@
+2018-09-04  Simon Fraser  <simon.fra...@apple.com>
+
+        CSS reference filter that references a tiled feTurbulence is blank
+        https://bugs.webkit.org/show_bug.cgi?id=188950
+
+        Reviewed by Dean Jackson.
+
+        * css3/filters/reference-filter-set-filter-regions-expected.html: Added.
+        * css3/filters/reference-filter-set-filter-regions.html: Added.
+
 2018-09-04  Rob Buis  <rb...@igalia.com>
 
         Adjust XMLHttpRequest username/password precedence rules

Added: trunk/LayoutTests/css3/filters/reference-filter-set-filter-regions-expected.html (0 => 235644)


--- trunk/LayoutTests/css3/filters/reference-filter-set-filter-regions-expected.html	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/reference-filter-set-filter-regions-expected.html	2018-09-04 22:51:47 UTC (rev 235644)
@@ -0,0 +1,12 @@
+<head>
+    <style>
+        .box {
+          width: 200px;
+          height: 200px;
+          background-color: green;
+        }
+    </style>
+</head>
+<body>
+  <div class="box"></div>
+</body>

Added: trunk/LayoutTests/css3/filters/reference-filter-set-filter-regions.html (0 => 235644)


--- trunk/LayoutTests/css3/filters/reference-filter-set-filter-regions.html	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/reference-filter-set-filter-regions.html	2018-09-04 22:51:47 UTC (rev 235644)
@@ -0,0 +1,31 @@
+<head>
+    <style>
+        .box {
+          width: 200px;
+          height: 200px;
+          background-color: silver;
+          filter: url(#filter);
+        }
+        
+        svg {
+            display: none; 
+        }
+    </style>
+</head>
+<body>
+   <svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" version="1.1">
+    <defs>
+        <filter id="filter">
+            <feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1" seed="5" stitchTiles="stitch"/>
+            <feColorMatrix type="saturate" values="0"/>
+            <feComponentTransfer>
+                <feFuncR type="linear" slope="0" intercept="0"/>
+                <feFuncG type="linear" slope="0" intercept="0.5"/>
+                <feFuncB type="linear" slope="0" intercept="0"/>
+                <feFuncA type="linear" slope="0" intercept="1"/>
+            </feComponentTransfer>
+        </filter>
+    </defs>
+  </svg>
+  <div class="box"></div>
+</body>

Modified: trunk/Source/WebCore/ChangeLog (235643 => 235644)


--- trunk/Source/WebCore/ChangeLog	2018-09-04 22:16:44 UTC (rev 235643)
+++ trunk/Source/WebCore/ChangeLog	2018-09-04 22:51:47 UTC (rev 235644)
@@ -1,3 +1,35 @@
+2018-09-04  Simon Fraser  <simon.fra...@apple.com>
+
+        CSS reference filter that references a tiled feTurbulence is blank
+        https://bugs.webkit.org/show_bug.cgi?id=188950
+
+        Reviewed by Dean Jackson.
+        
+        We need to run the code that was in RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion()
+        for CSS reference filters, to set up the various rects in the filter effects.
+        
+        Do this by moving the code to FilterEffect::determineFilterPrimitiveSubregion(), which makes sense
+        because it recurses on the FilterEffect input chain. To make it CSS/SVGFilter agnostic, we move filterRegionInUserSpace()
+        to the Filter base class (for CSSFilter, it just returns m_filterRegion).
+
+        Test: css3/filters/reference-filter-set-filter-regions.html
+
+        * platform/graphics/filters/Filter.h:
+        * platform/graphics/filters/FilterEffect.cpp:
+        (WebCore::FilterEffect::determineFilterPrimitiveSubregion):
+        * platform/graphics/filters/FilterEffect.h:
+        * rendering/CSSFilter.cpp:
+        (WebCore::CSSFilter::determineFilterPrimitiveSubregion):
+        * rendering/CSSFilter.h:
+        * rendering/RenderLayerFilters.cpp:
+        (WebCore::RenderLayerFilters::beginFilterEffect):
+        * rendering/svg/RenderSVGResourceFilter.cpp:
+        (WebCore::RenderSVGResourceFilter::applyResource):
+        * rendering/svg/RenderSVGResourceFilterPrimitive.cpp:
+        (WebCore::RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion): Deleted.
+        * rendering/svg/RenderSVGResourceFilterPrimitive.h:
+        * svg/graphics/filters/SVGFilter.h:
+
 2018-09-04  Zalan Bujtas  <za...@apple.com>
 
         [LFC] Rename LayoutPair to BoxPair

Modified: trunk/Source/WebCore/platform/graphics/filters/Filter.h (235643 => 235644)


--- trunk/Source/WebCore/platform/graphics/filters/Filter.h	2018-09-04 22:16:44 UTC (rev 235643)
+++ trunk/Source/WebCore/platform/graphics/filters/Filter.h	2018-09-04 22:51:47 UTC (rev 235644)
@@ -20,11 +20,16 @@
 
 #pragma once
 
-#include "FloatSize.h"
+#include "AffineTransform.h"
+#include "FloatRect.h"
+#include "GraphicsTypes.h"
 #include "ImageBuffer.h"
+#include <wtf/RefCounted.h>
 
 namespace WebCore {
 
+class FilterEffect;
+
 class Filter : public RefCounted<Filter> {
 public:
     Filter(const AffineTransform& absoluteTransform, float filterScale = 1)
@@ -54,6 +59,7 @@
     
     virtual FloatRect sourceImageRect() const = 0;
     virtual FloatRect filterRegion() const = 0;
+    virtual FloatRect filterRegionInUserSpace() const = 0;
 
 protected:
     explicit Filter(const FloatSize& filterResolution)

Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp (235643 => 235644)


--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp	2018-09-04 22:16:44 UTC (rev 235643)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp	2018-09-04 22:51:47 UTC (rev 235644)
@@ -94,6 +94,50 @@
     return transform.mapRect(srcRect);
 }
 
+FloatRect FilterEffect::determineFilterPrimitiveSubregion()
+{
+    // FETile, FETurbulence, FEFlood don't have input effects, take the filter region as unite rect.
+    FloatRect subregion;
+    if (unsigned numberOfInputEffects = inputEffects().size()) {
+        subregion = inputEffect(0)->determineFilterPrimitiveSubregion();
+        for (unsigned i = 1; i < numberOfInputEffects; ++i) {
+            auto inputPrimitiveSubregion = inputEffect(i)->determineFilterPrimitiveSubregion();
+            subregion.unite(inputPrimitiveSubregion);
+        }
+    } else
+        subregion = m_filter.filterRegionInUserSpace();
+
+    // After calling determineFilterPrimitiveSubregion on the target effect, reset the subregion again for <feTile>.
+    if (filterEffectType() == FilterEffectTypeTile)
+        subregion = m_filter.filterRegionInUserSpace();
+
+    auto boundaries = effectBoundaries();
+    if (hasX())
+        subregion.setX(boundaries.x());
+    if (hasY())
+        subregion.setY(boundaries.y());
+    if (hasWidth())
+        subregion.setWidth(boundaries.width());
+    if (hasHeight())
+        subregion.setHeight(boundaries.height());
+
+    setFilterPrimitiveSubregion(subregion);
+
+    auto absoluteSubregion = m_filter.absoluteTransform().mapRect(subregion);
+    auto filterResolution = m_filter.filterResolution();
+    absoluteSubregion.scale(filterResolution);
+    // Save this before clipping so we can use it to map lighting points from user space to buffer coordinates.
+    setUnclippedAbsoluteSubregion(absoluteSubregion);
+
+    // Clip every filter effect to the filter region.
+    auto absoluteScaledFilterRegion = m_filter.filterRegion();
+    absoluteScaledFilterRegion.scale(filterResolution);
+    absoluteSubregion.intersect(absoluteScaledFilterRegion);
+
+    setMaxEffectRect(absoluteSubregion);
+    return subregion;
+}
+
 FilterEffect* FilterEffect::inputEffect(unsigned number) const
 {
     ASSERT_WITH_SECURITY_IMPLICATION(number < m_inputEffects.size());

Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h (235643 => 235644)


--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h	2018-09-04 22:16:44 UTC (rev 235643)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h	2018-09-04 22:51:47 UTC (rev 235644)
@@ -87,6 +87,9 @@
 
     FloatRect drawingRegionOfInputImage(const IntRect&) const;
     IntRect requestedRegionOfInputImageData(const IntRect&) const;
+    
+    // Recurses on inputs.
+    FloatRect determineFilterPrimitiveSubregion();
 
     // Solid black image with different alpha values.
     bool isAlphaImage() const { return m_alphaImage; }

Modified: trunk/Source/WebCore/rendering/CSSFilter.cpp (235643 => 235644)


--- trunk/Source/WebCore/rendering/CSSFilter.cpp	2018-09-04 22:16:44 UTC (rev 235643)
+++ trunk/Source/WebCore/rendering/CSSFilter.cpp	2018-09-04 22:51:47 UTC (rev 235644)
@@ -340,6 +340,19 @@
     m_graphicsBufferAttached = true;
 }
 
+void CSSFilter::determineFilterPrimitiveSubregion()
+{
+    auto& lastEffect = m_effects.last().get();
+    lastEffect.determineFilterPrimitiveSubregion();
+    FloatRect subRegion = lastEffect.maxEffectRect();
+    // At least one FilterEffect has a too big image size, recalculate the effect sizes with new scale factors.
+    FloatSize scale;
+    if (ImageBuffer::sizeNeedsClamping(subRegion.size(), scale)) {
+        setFilterResolution(scale);
+        lastEffect.determineFilterPrimitiveSubregion();
+    }
+}
+
 void CSSFilter::clearIntermediateResults()
 {
     m_sourceGraphic->clearResult();

Modified: trunk/Source/WebCore/rendering/CSSFilter.h (235643 => 235644)


--- trunk/Source/WebCore/rendering/CSSFilter.h	2018-09-04 22:16:44 UTC (rev 235643)
+++ trunk/Source/WebCore/rendering/CSSFilter.h	2018-09-04 22:51:47 UTC (rev 235644)
@@ -59,6 +59,8 @@
     bool hasFilterThatMovesPixels() const { return m_hasFilterThatMovesPixels; }
     bool hasFilterThatShouldBeRestrictedBySecurityOrigin() const { return m_hasFilterThatShouldBeRestrictedBySecurityOrigin; }
 
+    void determineFilterPrimitiveSubregion();
+
 private:
     CSSFilter();
     virtual ~CSSFilter();
@@ -66,7 +68,9 @@
     bool isCSSFilter() const final { return true; }
 
     FloatRect sourceImageRect() const final { return m_sourceDrawingRegion; }
+
     FloatRect filterRegion() const final { return m_filterRegion; }
+    FloatRect filterRegionInUserSpace() const final { return m_filterRegion; }
 
     RefPtr<FilterEffect> buildReferenceFilter(RenderElement&, FilterEffect& previousEffect, ReferenceFilterOperation&);
 

Modified: trunk/Source/WebCore/rendering/RenderLayerFilters.cpp (235643 => 235644)


--- trunk/Source/WebCore/rendering/RenderLayerFilters.cpp	2018-09-04 22:16:44 UTC (rev 235643)
+++ trunk/Source/WebCore/rendering/RenderLayerFilters.cpp	2018-09-04 22:51:47 UTC (rev 235644)
@@ -155,6 +155,8 @@
     m_paintOffset = filterSourceRect.location();
     resetDirtySourceRect();
 
+    filter.determineFilterPrimitiveSubregion();
+
     filter.allocateBackingStoreIfNeeded(destinationContext);
     auto* sourceGraphicsContext = filter.inputContext();
     if (!sourceGraphicsContext || filter.filterRegion().isEmpty() || ImageBuffer::sizeNeedsClamping(filter.filterRegion().size()))

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp (235643 => 235644)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2018-09-04 22:16:44 UTC (rev 235643)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2018-09-04 22:51:47 UTC (rev 235644)
@@ -178,13 +178,13 @@
 
     LOG_WITH_STREAM(Filters, stream << "RenderSVGResourceFilter::applyResource\n" << *filterData->builder->lastEffect());
 
-    RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(*lastEffect);
+    lastEffect->determineFilterPrimitiveSubregion();
     FloatRect subRegion = lastEffect->maxEffectRect();
     // At least one FilterEffect has a too big image size,
     // recalculate the effect sizes with new scale factors.
     if (ImageBuffer::sizeNeedsClamping(subRegion.size(), scale)) {
         filterData->filter->setFilterResolution(scale);
-        RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(*lastEffect);
+        lastEffect->determineFilterPrimitiveSubregion();
     }
 
     // If the drawingRegion is empty, we have something like <g filter=".."/>.

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp (235643 => 235644)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp	2018-09-04 22:16:44 UTC (rev 235643)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp	2018-09-04 22:51:47 UTC (rev 235644)
@@ -73,48 +73,4 @@
     }
 }
 
-FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect& effect)
-{
-    auto& filter = downcast<SVGFilter>(effect.filter());
-
-    // FETile, FETurbulence, FEFlood don't have input effects, take the filter region as unite rect.
-    FloatRect subregion;
-    if (unsigned numberOfInputEffects = effect.inputEffects().size()) {
-        subregion = determineFilterPrimitiveSubregion(*effect.inputEffect(0));
-        for (unsigned i = 1; i < numberOfInputEffects; ++i)
-            subregion.unite(determineFilterPrimitiveSubregion(*effect.inputEffect(i)));
-    } else
-        subregion = filter.filterRegionInUserSpace();
-
-    // After calling determineFilterPrimitiveSubregion on the target effect, reset the subregion again for <feTile>.
-    if (effect.filterEffectType() == FilterEffectTypeTile)
-        subregion = filter.filterRegionInUserSpace();
-
-    FloatRect effectBoundaries = effect.effectBoundaries();
-    if (effect.hasX())
-        subregion.setX(effectBoundaries.x());
-    if (effect.hasY())
-        subregion.setY(effectBoundaries.y());
-    if (effect.hasWidth())
-        subregion.setWidth(effectBoundaries.width());
-    if (effect.hasHeight())
-        subregion.setHeight(effectBoundaries.height());
-
-    effect.setFilterPrimitiveSubregion(subregion);
-
-    FloatRect absoluteSubregion = filter.absoluteTransform().mapRect(subregion);
-    FloatSize filterResolution = filter.filterResolution();
-    absoluteSubregion.scale(filterResolution);
-    // Save this before clipping so we can use it to map lighting points from user space to buffer coordinates.
-    effect.setUnclippedAbsoluteSubregion(absoluteSubregion);
-
-    // Clip every filter effect to the filter region.
-    FloatRect absoluteScaledFilterRegion = filter.filterRegion();
-    absoluteScaledFilterRegion.scale(filterResolution);
-    absoluteSubregion.intersect(absoluteScaledFilterRegion);
-
-    effect.setMaxEffectRect(absoluteSubregion);
-    return subregion;
-}
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h (235643 => 235644)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h	2018-09-04 22:16:44 UTC (rev 235643)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h	2018-09-04 22:51:47 UTC (rev 235644)
@@ -43,9 +43,6 @@
 
     const char* renderName() const override { return "RenderSVGResourceFilterPrimitive"; }
 
-    // They depend on the RenderObject argument of RenderSVGResourceFilter::applyResource.
-    static FloatRect determineFilterPrimitiveSubregion(FilterEffect&);
-
     inline void primitiveAttributeChanged(const QualifiedName& attribute)
     {
         RenderObject* filter = parent();

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h (235643 => 235644)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h	2018-09-04 22:16:44 UTC (rev 235643)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h	2018-09-04 22:51:47 UTC (rev 235644)
@@ -33,7 +33,7 @@
 public:
     static Ref<SVGFilter> create(const AffineTransform&, const FloatRect&, const FloatRect&, const FloatRect&, bool);
 
-    FloatRect filterRegionInUserSpace() const { return m_filterRegion; }
+    FloatRect filterRegionInUserSpace() const final { return m_filterRegion; }
     FloatRect filterRegion() const final { return m_absoluteFilterRegion; }
 
     FloatSize scaledByFilterResolution(FloatSize) const final;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to