WebKit Bugzilla
Attachment 348848 Details for
Bug 188950
: CSS reference filter that references a tiled feTurbulence is blank
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-188950-20180904144412.patch (text/plain), 16.75 KB, created by
Simon Fraser (smfr)
on 2018-09-04 14:44:13 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Simon Fraser (smfr)
Created:
2018-09-04 14:44:13 PDT
Size:
16.75 KB
patch
obsolete
>Subversion Revision: 235632 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 742c09b5b2e5509a61082aaf7beb6e9181000fdb..b980615f94ebd1791ff1466de20f46e27610f70f 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,35 @@ >+2018-09-04 Simon Fraser <simon.fraser@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 Rob Buis <rbuis@igalia.com> > > Adjust XMLHttpRequest username/password precedence rules >diff --git a/Source/WebCore/platform/graphics/filters/Filter.h b/Source/WebCore/platform/graphics/filters/Filter.h >index 3bedea705b76d9bf1a1c519cb2e4375a8ae68281..49e8c5a26e771c424967819527a5627353df4496 100644 >--- a/Source/WebCore/platform/graphics/filters/Filter.h >+++ b/Source/WebCore/platform/graphics/filters/Filter.h >@@ -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 @@ public: > > virtual FloatRect sourceImageRect() const = 0; > virtual FloatRect filterRegion() const = 0; >+ virtual FloatRect filterRegionInUserSpace() const = 0; > > protected: > explicit Filter(const FloatSize& filterResolution) >diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp >index 7b071fc09161bbe23e620a8fe363f53cbd5c2c3c..66c30a98c28aed2fcff519602d2c47139f76aea8 100644 >--- a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp >+++ b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp >@@ -94,6 +94,50 @@ FloatRect FilterEffect::drawingRegionOfInputImage(const IntRect& srcRect) const > 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()); >diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.h b/Source/WebCore/platform/graphics/filters/FilterEffect.h >index 5dddf4f201422f14da44432a4ee4d7ce14a54230..abb7b0f8f9fb026c1ab73349a0068a832f11622b 100644 >--- a/Source/WebCore/platform/graphics/filters/FilterEffect.h >+++ b/Source/WebCore/platform/graphics/filters/FilterEffect.h >@@ -87,6 +87,9 @@ public: > > 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; } >diff --git a/Source/WebCore/rendering/CSSFilter.cpp b/Source/WebCore/rendering/CSSFilter.cpp >index 85b845ae4ae581c1ac7123d06e09c779cd27a0e0..e3b2e8c945712c150db682eb2d2dd5b494c11522 100644 >--- a/Source/WebCore/rendering/CSSFilter.cpp >+++ b/Source/WebCore/rendering/CSSFilter.cpp >@@ -340,6 +340,19 @@ void CSSFilter::allocateBackingStoreIfNeeded(const GraphicsContext& targetContex > 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(); >diff --git a/Source/WebCore/rendering/CSSFilter.h b/Source/WebCore/rendering/CSSFilter.h >index 493729f9491b911529f2e241a4b9206e22bc67f2..3303a1a35d0ec1314e4a3034f06ee94b8a31f633 100644 >--- a/Source/WebCore/rendering/CSSFilter.h >+++ b/Source/WebCore/rendering/CSSFilter.h >@@ -59,6 +59,8 @@ public: > bool hasFilterThatMovesPixels() const { return m_hasFilterThatMovesPixels; } > bool hasFilterThatShouldBeRestrictedBySecurityOrigin() const { return m_hasFilterThatShouldBeRestrictedBySecurityOrigin; } > >+ void determineFilterPrimitiveSubregion(); >+ > private: > CSSFilter(); > virtual ~CSSFilter(); >@@ -66,7 +68,9 @@ private: > 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&); > >diff --git a/Source/WebCore/rendering/RenderLayerFilters.cpp b/Source/WebCore/rendering/RenderLayerFilters.cpp >index 77d99c9a8aedc93b38f1ff417fe444eaabfbaa12..0a3ed06e83077f1f64e3c27279616526a4805bdb 100644 >--- a/Source/WebCore/rendering/RenderLayerFilters.cpp >+++ b/Source/WebCore/rendering/RenderLayerFilters.cpp >@@ -155,6 +155,8 @@ GraphicsContext* RenderLayerFilters::beginFilterEffect(GraphicsContext& destinat > m_paintOffset = filterSourceRect.location(); > resetDirtySourceRect(); > >+ filter.determineFilterPrimitiveSubregion(); >+ > filter.allocateBackingStoreIfNeeded(destinationContext); > auto* sourceGraphicsContext = filter.inputContext(); > if (!sourceGraphicsContext || filter.filterRegion().isEmpty() || ImageBuffer::sizeNeedsClamping(filter.filterRegion().size())) >diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp >index 26faf73f2b752334560b2f5e340546a5d1594083..afde38cfedc6ae04f59c02242a9df38866059c95 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp >+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp >@@ -178,13 +178,13 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende > > 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=".."/>. >diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp >index 2395f69df142c6cf058c05bb40a79e3e96dff3a9..2485617c50562fea398f0562bcd71a457feaab46 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp >+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp >@@ -73,48 +73,4 @@ void RenderSVGResourceFilterPrimitive::styleDidChange(StyleDifference diff, cons > } > } > >-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 >diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h >index e5f6b06997b84afadc31a9650ba24c16e034a330..16248377194ec242805e5d43cf9a3aa22200f40b 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h >+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h >@@ -43,9 +43,6 @@ public: > > 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(); >diff --git a/Source/WebCore/svg/graphics/filters/SVGFilter.h b/Source/WebCore/svg/graphics/filters/SVGFilter.h >index f780f5e5d8ef9c409b7036291a750e9b197e91b1..8093146d64af8885bc3da49302f5aea0fb1700cf 100644 >--- a/Source/WebCore/svg/graphics/filters/SVGFilter.h >+++ b/Source/WebCore/svg/graphics/filters/SVGFilter.h >@@ -33,7 +33,7 @@ class SVGFilter final : public Filter { > 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; >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 18520278958c122dcfa8467d84a8ff1df41959b5..5c016f52234481ed6eb42db46afb0876ac4dbcda 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,13 @@ >+2018-09-04 Simon Fraser <simon.fraser@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 <rbuis@igalia.com> > > Adjust XMLHttpRequest username/password precedence rules >diff --git a/LayoutTests/css3/filters/reference-filter-set-filter-regions-expected.html b/LayoutTests/css3/filters/reference-filter-set-filter-regions-expected.html >new file mode 100644 >index 0000000000000000000000000000000000000000..df94fe5cade361aced53bde865050ce7e2731f03 >--- /dev/null >+++ b/LayoutTests/css3/filters/reference-filter-set-filter-regions-expected.html >@@ -0,0 +1,12 @@ >+<head> >+ <style> >+ .box { >+ width: 200px; >+ height: 200px; >+ background-color: green; >+ } >+ </style> >+</head> >+<body> >+ <div class="box"></div> >+</body> >diff --git a/LayoutTests/css3/filters/reference-filter-set-filter-regions.html b/LayoutTests/css3/filters/reference-filter-set-filter-regions.html >new file mode 100644 >index 0000000000000000000000000000000000000000..82ac5970d715dc10140dd8d8ec2a1e0af3dbd8a5 >--- /dev/null >+++ b/LayoutTests/css3/filters/reference-filter-set-filter-regions.html >@@ -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>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188950
:
348704
|
348806
|
348844
| 348848