Diff
Modified: trunk/Source/WebCore/ChangeLog (286577 => 286578)
--- trunk/Source/WebCore/ChangeLog 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/ChangeLog 2021-12-07 00:36:58 UTC (rev 286578)
@@ -1,3 +1,70 @@
+2021-12-06 Said Abou-Hallawa <s...@apple.com>
+
+ [GPU Process] Make FilterEffect calculate the primitive subregion only when needed
+ https://bugs.webkit.org/show_bug.cgi?id=232705
+ rdar://85290142
+
+ Reviewed by Cameron McCormack.
+
+ In this patch:
+
+ 1. resultColorSpace() will return colorSpace() from a FilterImageVector
+ instead of returning the resultColorSpace() of the FilterEffect.
+
+ 2. Filter::clampFilterRegionIfNeeded() will clamp the filterRegion()
+ instead of clamping the maxEffectRect of the lastEffect() since all
+ the primitiveSubregions and the imageRects have to clipped to the
+ filterRegion().
+
+ 3. determineFilterPrimitiveSubregion() is replaced by calculatePrimitiveSubregion()
+ which will calculate the primitiveSubregion from a FilterImageVector
+ and an optional FilterEffectGeometry.
+
+ 4. Many of FilterEffects are made protected instead of having them public.
+
+ 5. SVGFilterExpression will be defined as a Vector of SVGFilterExpressionTerm
+ which is a struct of FilterEffect and optional FilterEffectGeometry.
+
+ 6. SVGFilter will replace the members whose types are FilterEffectVector
+ and FilterEffectGeometryMap with a single member of type SVGFilterExpression.
+
+ * Headers.cmake:
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/graphics/filters/FEDisplacementMap.cpp:
+ (WebCore::FEDisplacementMap::resultColorSpace const):
+ * platform/graphics/filters/FEDisplacementMap.h:
+ * platform/graphics/filters/Filter.cpp:
+ (WebCore::Filter::clampFilterRegionIfNeeded):
+ * platform/graphics/filters/Filter.h:
+ (WebCore::Filter::effectGeometry const): Deleted.
+ * platform/graphics/filters/FilterEffect.cpp:
+ (WebCore::FilterEffect::calculatePrimitiveSubregion const):
+ (WebCore::FilterEffect::apply):
+ (WebCore::FilterEffect::externalRepresentation const):
+ (WebCore::FilterEffect::determineFilterPrimitiveSubregion): Deleted.
+ * platform/graphics/filters/FilterEffect.h:
+ (WebCore::FilterEffect::resultColorSpace const):
+ (WebCore::FilterEffect::filterPrimitiveSubregion const): Deleted.
+ (WebCore::FilterEffect::setFilterPrimitiveSubregion): Deleted.
+ * platform/graphics/filters/FilterFunction.h:
+ (WebCore::FilterFunction::apply):
+ * svg/graphics/filters/SVGFilter.cpp:
+ (WebCore::SVGFilter::create):
+ (WebCore::SVGFilter::supportsCoreImageRendering const):
+ (WebCore::SVGFilter::lastEffect const):
+ (WebCore::SVGFilter::apply):
+ (WebCore::SVGFilter::clearResult):
+ (WebCore::SVGFilter::effectGeometry const): Deleted.
+ * svg/graphics/filters/SVGFilter.h:
+ * svg/graphics/filters/SVGFilterBuilder.cpp:
+ (WebCore::SVGFilterBuilder::effectGeometry const):
+ (WebCore::SVGFilterBuilder::buildEffectExpression const):
+ (WebCore::SVGFilterBuilder::buildExpression const):
+ (WebCore::buildEffectExpression): Deleted.
+ * svg/graphics/filters/SVGFilterBuilder.h:
+ (WebCore::SVGFilterBuilder::takeEffectGeometryMap): Deleted.
+ * svg/graphics/filters/SVGFilterExpression.h: Added.
+
2021-12-06 Ryan Haddad <ryanhad...@apple.com>
REGRESSION (r286507): [macOS] Many file system access layout tests became flaky failures
Modified: trunk/Source/WebCore/Headers.cmake (286577 => 286578)
--- trunk/Source/WebCore/Headers.cmake 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/Headers.cmake 2021-12-07 00:36:58 UTC (rev 286578)
@@ -1910,6 +1910,7 @@
svg/graphics/SVGImageCache.h
svg/graphics/filters/SVGFilter.h
+ svg/graphics/filters/SVGFilterExpression.h
svg/properties/SVGList.h
svg/properties/SVGPrimitiveList.h
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (286577 => 286578)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-12-07 00:36:58 UTC (rev 286578)
@@ -2318,6 +2318,7 @@
7299BC6723D6A53200CC6883 /* AlphaPremultiplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 7299BC6423D686A600CC6883 /* AlphaPremultiplication.h */; settings = {ATTRIBUTES = (Private, ); }; };
7299BC6823D6A53E00CC6883 /* RenderingMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7299BC6623D686C600CC6883 /* RenderingMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
729D05302531424300422098 /* RenderingResourceIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 729D052E25313E2600422098 /* RenderingResourceIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 72A5D192275E8FFE0065833E /* SVGFilterExpression.h in Headers */ = {isa = PBXBuildFile; fileRef = 726CDE25275B489700A445B2 /* SVGFilterExpression.h */; settings = {ATTRIBUTES = (Private, ); }; };
72A73BEF245A3F90001C9D03 /* AnimationFrameRate.h in Headers */ = {isa = PBXBuildFile; fileRef = 722A815C238FD50500C00583 /* AnimationFrameRate.h */; settings = {ATTRIBUTES = (Private, ); }; };
72B8B0352753438600F752AA /* FilterFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 7262D756272A174100C56A09 /* FilterFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
72B8B0362753441400F752AA /* FilterImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 72435EF4273D07670005E7EE /* FilterImage.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -11200,6 +11201,7 @@
7266F0282243120300833975 /* SVGAnimationAdditiveListFunctionImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAnimationAdditiveListFunctionImpl.h; sourceTree = "<group>"; };
7266F029224312B100833975 /* SVGAnimationAdditiveListFunction.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAnimationAdditiveListFunction.h; sourceTree = "<group>"; };
7266F02A2243149B00833975 /* SVGAnimatedPropertyList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedPropertyList.h; sourceTree = "<group>"; };
+ 726CDE25275B489700A445B2 /* SVGFilterExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGFilterExpression.h; sourceTree = "<group>"; };
726D56E1253AE0430002EF90 /* PlatformImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformImage.h; sourceTree = "<group>"; };
727AFED11A2EA6A0000442E8 /* EXTsRGB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EXTsRGB.cpp; sourceTree = "<group>"; };
727AFED21A2EA6A0000442E8 /* EXTsRGB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTsRGB.h; sourceTree = "<group>"; };
@@ -28447,6 +28449,7 @@
845E72FA0FD2623900A87D79 /* SVGFilter.h */,
081EBF380FD34F4100DA7559 /* SVGFilterBuilder.cpp */,
081EBF390FD34F4100DA7559 /* SVGFilterBuilder.h */,
+ 726CDE25275B489700A445B2 /* SVGFilterExpression.h */,
);
path = filters;
sourceTree = "<group>";
@@ -37149,6 +37152,7 @@
845E72FC0FD2623900A87D79 /* SVGFilter.h in Headers */,
081EBF3B0FD34F4100DA7559 /* SVGFilterBuilder.h in Headers */,
B2227A0C0D00BF220071B782 /* SVGFilterElement.h in Headers */,
+ 72A5D192275E8FFE0065833E /* SVGFilterExpression.h in Headers */,
B2227A0F0D00BF220071B782 /* SVGFilterPrimitiveStandardAttributes.h in Headers */,
B2227A120D00BF220071B782 /* SVGFitToViewBox.h in Headers */,
B2A1F2AB0CEF0ABF00442F6A /* SVGFontElement.h in Headers */,
Modified: trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp (286577 => 286578)
--- trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp 2021-12-07 00:36:58 UTC (rev 286578)
@@ -68,13 +68,13 @@
return true;
}
-const DestinationColorSpace& FEDisplacementMap::resultColorSpace() const
+const DestinationColorSpace& FEDisplacementMap::resultColorSpace(const FilterImageVector& inputs) const
{
// Spec: The 'color-interpolation-filters' property only applies to the 'in2' source image
// and does not apply to the 'in' source image. The 'in' source image must remain in its
// current color space.
// The result is in that same color space because it is a displacement of the 'in' image.
- return inputEffect(0)->resultColorSpace();
+ return inputs[0]->colorSpace();
}
void FEDisplacementMap::transformResultColorSpace(FilterEffect* in, const int index)
Modified: trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h (286577 => 286578)
--- trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h 2021-12-07 00:36:58 UTC (rev 286578)
@@ -54,7 +54,7 @@
private:
FEDisplacementMap(ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, float);
- const DestinationColorSpace& resultColorSpace() const override;
+ const DestinationColorSpace& resultColorSpace(const FilterImageVector&) const override;
void transformResultColorSpace(FilterEffect*, const int) override;
FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const override;
Modified: trunk/Source/WebCore/platform/graphics/filters/Filter.cpp (286577 => 286578)
--- trunk/Source/WebCore/platform/graphics/filters/Filter.cpp 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/platform/graphics/filters/Filter.cpp 2021-12-07 00:36:58 UTC (rev 286578)
@@ -71,21 +71,13 @@
bool Filter::clampFilterRegionIfNeeded()
{
- auto lastEffect = this->lastEffect();
- lastEffect->determineFilterPrimitiveSubregion(*this);
-
- auto maxEffectRect = this->maxEffectRect(lastEffect->filterPrimitiveSubregion());
- auto scaledMaxEffectRect = scaledByFilterScale(maxEffectRect);
+ auto scaledFilterRegion = scaledByFilterScale(m_filterRegion);
FloatSize clampingScale(1, 1);
- if (!ImageBuffer::sizeNeedsClamping(scaledMaxEffectRect.size(), clampingScale))
+ if (!ImageBuffer::sizeNeedsClamping(scaledFilterRegion.size(), clampingScale))
return false;
m_filterScale = m_filterScale * clampingScale;
-
- // At least one FilterEffect has a too big image size,
- // recalculate the effect sizes with new scale factors.
- lastEffect->determineFilterPrimitiveSubregion(*this);
return true;
}
Modified: trunk/Source/WebCore/platform/graphics/filters/Filter.h (286577 => 286578)
--- trunk/Source/WebCore/platform/graphics/filters/Filter.h 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/platform/graphics/filters/Filter.h 2021-12-07 00:36:58 UTC (rev 286578)
@@ -63,8 +63,6 @@
FloatSize scaledByFilterScale(const FloatSize&) const;
FloatRect scaledByFilterScale(const FloatRect&) const;
- virtual std::optional<FilterEffectGeometry> effectGeometry(FilterEffect&) const { return std::nullopt; }
-
FloatRect maxEffectRect(const FloatRect& primitiveSubregion) const;
FloatRect clipToMaxEffectRect(const FloatRect& imageRect, const FloatRect& primitiveSubregion) const;
Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp (286577 => 286578)
--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp 2021-12-07 00:36:58 UTC (rev 286578)
@@ -26,6 +26,7 @@
#include "Filter.h"
#include "FilterEffectApplier.h"
+#include "FilterEffectGeometry.h"
#include "ImageBuffer.h"
#include "Logging.h"
#include <wtf/text/TextStream.h>
@@ -40,26 +41,20 @@
return filter.clipToMaxEffectRect(imageRect, primitiveSubregion);
}
-FloatRect FilterEffect::determineFilterPrimitiveSubregion(const Filter& filter)
+FloatRect FilterEffect::calculatePrimitiveSubregion(const Filter& filter, const FilterImageVector& inputs, const std::optional<FilterEffectGeometry>& geometry) const
{
// This function implements https://www.w3.org/TR/filter-effects-1/#FilterPrimitiveSubRegion.
FloatRect primitiveSubregion;
- // If there is no input effects, take the effect boundaries as unite rect.
- if (!m_inputEffects.isEmpty()) {
- for (auto& effect : m_inputEffects) {
- auto inputPrimitiveSubregion = effect->determineFilterPrimitiveSubregion(filter);
- primitiveSubregion.unite(inputPrimitiveSubregion);
- }
+ // If there is no input effects, take the effect boundaries as unite rect. Don't use the input's subregion for FETile.
+ if (!inputs.isEmpty() && filterType() != FilterEffect::Type::FETile) {
+ for (auto& input : inputs)
+ primitiveSubregion.unite(input->primitiveSubregion());
} else
primitiveSubregion = filter.filterRegion();
- // Don't use the input's subregion for FETile.
- if (filterType() == FilterEffect::Type::FETile)
- primitiveSubregion = filter.filterRegion();
-
// Clip the primitive subregion to the effect geometry.
- if (auto geometry = filter.effectGeometry(*this)) {
+ if (geometry) {
if (auto x = geometry->x())
primitiveSubregion.setX(*x);
if (auto y = geometry->y())
@@ -70,7 +65,6 @@
primitiveSubregion.setHeight(*height);
}
- setFilterPrimitiveSubregion(primitiveSubregion);
return primitiveSubregion;
}
@@ -80,7 +74,7 @@
return m_inputEffects.at(number).get();
}
-bool FilterEffect::apply(const Filter& filter)
+bool FilterEffect::apply(const Filter& filter, const std::optional<FilterEffectGeometry>& geometry)
{
if (hasResult())
return true;
@@ -100,7 +94,9 @@
}
auto inputFilterImages = this->inputFilterImages();
- auto imageRect = calculateImageRect(filter, inputFilterImages, m_filterPrimitiveSubregion);
+
+ auto primitiveSubregion = calculatePrimitiveSubregion(filter, inputFilterImages, geometry);
+ auto imageRect = calculateImageRect(filter, inputFilterImages, primitiveSubregion);
auto absoluteImageRect = enclosingIntRect(filter.scaledByFilterScale(imageRect));
if (absoluteImageRect.isEmpty() || ImageBuffer::sizeNeedsClamping(absoluteImageRect.size()))
@@ -107,9 +103,9 @@
return false;
auto isAlphaImage = resultIsAlphaImage(inputFilterImages);
- auto imageColorSpace = resultColorSpace();
+ auto imageColorSpace = resultColorSpace(inputFilterImages);
- m_filterImage = FilterImage::create(m_filterPrimitiveSubregion, imageRect, absoluteImageRect, isAlphaImage, filter.renderingMode(), imageColorSpace);
+ m_filterImage = FilterImage::create(primitiveSubregion, imageRect, absoluteImageRect, isAlphaImage, filter.renderingMode(), imageColorSpace);
if (!m_filterImage)
return false;
@@ -119,9 +115,9 @@
LOG_WITH_STREAM(Filters, stream
<< "FilterEffect " << filterName() << " " << this << " apply():"
- << "\n filterPrimitiveSubregion " << m_filterPrimitiveSubregion
+ << "\n filterPrimitiveSubregion " << primitiveSubregion
<< "\n absolutePaintRect " << absoluteImageRect
- << "\n maxEffectRect " << filter.scaledByFilterScale(filter.maxEffectRect(m_filterPrimitiveSubregion))
+ << "\n maxEffectRect " << filter.maxEffectRect(primitiveSubregion)
<< "\n filter scale " << filter.filterScale());
return applier->apply(filter, inputFilterImages, *m_filterImage);
@@ -173,7 +169,6 @@
if (representationType == RepresentationType::Debugging) {
TextStream::IndentScope indentScope(ts);
ts.dumpProperty("operating colorspace", operatingColorSpace());
- ts.dumpProperty("result colorspace", resultColorSpace());
ts << "\n" << indent;
}
return ts;
Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h (286577 => 286578)
--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h 2021-12-07 00:36:58 UTC (rev 286578)
@@ -37,6 +37,7 @@
class Filter;
class FilterEffectApplier;
+class FilterEffectGeometry;
class FilterEffect : public FilterFunction {
public:
@@ -45,58 +46,51 @@
bool hasResult() const { return m_filterImage; }
FilterImage* filterImage() const { return m_filterImage.get(); }
- FilterImageVector inputFilterImages() const;
- void correctPremultipliedResultIfNeeded();
-
FilterEffectVector& inputEffects() { return m_inputEffects; }
FilterEffect* inputEffect(unsigned) const;
unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
- // Recurses on inputs.
- FloatRect determineFilterPrimitiveSubregion(const Filter&);
+ void transformResultColorSpace(const DestinationColorSpace&);
- bool apply(const Filter&) override;
+ bool apply(const Filter&, const std::optional<FilterEffectGeometry>& = std::nullopt) override;
+ const DestinationColorSpace& operatingColorSpace() const { return m_operatingColorSpace; }
+ virtual void setOperatingColorSpace(const DestinationColorSpace& colorSpace) { m_operatingColorSpace = colorSpace; }
+
+ enum class RepresentationType { TestOutput, Debugging };
+ virtual WTF::TextStream& externalRepresentation(WTF::TextStream&, RepresentationType = RepresentationType::TestOutput) const;
+
+protected:
+ using FilterFunction::FilterFunction;
+
+ virtual bool mayProduceInvalidPremultipliedPixels() const { return false; }
+
+ void correctPremultipliedResultIfNeeded();
+
// Correct any invalid pixels, if necessary, in the result of a filter operation.
// This method is used to ensure valid pixel values on filter inputs and the final result.
// Only the arithmetic composite filter ever needs to perform correction.
virtual void correctFilterResultIfNeeded() { }
- enum class RepresentationType { TestOutput, Debugging };
- virtual WTF::TextStream& externalRepresentation(WTF::TextStream&, RepresentationType = RepresentationType::TestOutput) const;
+ virtual void transformResultColorSpace(FilterEffect* in, const int) { in->transformResultColorSpace(m_operatingColorSpace); }
- FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; }
- void setFilterPrimitiveSubregion(const FloatRect& filterPrimitiveSubregion) { m_filterPrimitiveSubregion = filterPrimitiveSubregion; }
+ FilterImageVector inputFilterImages() const;
+
+ FloatRect calculatePrimitiveSubregion(const Filter&, const FilterImageVector&, const std::optional<FilterEffectGeometry>&) const;
virtual FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const;
- const DestinationColorSpace& operatingColorSpace() const { return m_operatingColorSpace; }
- virtual void setOperatingColorSpace(const DestinationColorSpace& colorSpace) { m_operatingColorSpace = colorSpace; }
-
// Solid black image with different alpha values.
virtual bool resultIsAlphaImage(const FilterImageVector&) const { return false; }
- virtual const DestinationColorSpace& resultColorSpace() const { return m_operatingColorSpace; }
+ virtual const DestinationColorSpace& resultColorSpace(const FilterImageVector&) const { return m_operatingColorSpace; }
- virtual void transformResultColorSpace(FilterEffect* in, const int) { in->transformResultColorSpace(m_operatingColorSpace); }
- void transformResultColorSpace(const DestinationColorSpace&);
-
-protected:
- using FilterFunction::FilterFunction;
-
- virtual bool mayProduceInvalidPremultipliedPixels() const { return false; }
-
virtual std::unique_ptr<FilterEffectApplier> createApplier(const Filter&) const = 0;
-private:
FilterEffectVector m_inputEffects;
RefPtr<FilterImage> m_filterImage;
- // The subregion of a filter primitive according to the SVG Filter specification in local coordinates.
- // This is SVG specific and needs to move to RenderSVGResourceFilterPrimitive.
- FloatRect m_filterPrimitiveSubregion;
-
DestinationColorSpace m_operatingColorSpace { DestinationColorSpace::SRGB() };
};
Modified: trunk/Source/WebCore/platform/graphics/filters/FilterFunction.h (286577 => 286578)
--- trunk/Source/WebCore/platform/graphics/filters/FilterFunction.h 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterFunction.h 2021-12-07 00:36:58 UTC (rev 286578)
@@ -25,6 +25,7 @@
#pragma once
+#include "FilterEffectGeometry.h"
#include "FloatRect.h"
#include "IntRectExtent.h"
#include <wtf/RefCounted.h>
@@ -88,7 +89,7 @@
virtual bool supportsCoreImageRendering() const { return false; }
#endif
- virtual bool apply(const Filter&) { return false; }
+ virtual bool apply(const Filter&, const std::optional<FilterEffectGeometry>& = std::nullopt) { return false; }
virtual IntOutsets outsets() const { return { }; }
virtual void clearResult() { }
Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp (286577 => 286578)
--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp 2021-12-07 00:36:58 UTC (rev 286578)
@@ -54,7 +54,7 @@
if (!builder.buildFilterEffects(filterElement))
return nullptr;
- FilterEffectVector _expression_;
+ SVGFilterExpression _expression_;
if (!builder.buildExpression(_expression_))
return nullptr;
@@ -61,8 +61,6 @@
ASSERT(!_expression_.isEmpty());
filter->setExpression(WTFMove(_expression_));
- filter->setEffectGeometryMap(builder.takeEffectGeometryMap());
-
#if USE(CORE_IMAGE)
if (!filter->supportsCoreImageRendering())
filter->setRenderingMode(RenderingMode::Unaccelerated);
@@ -90,8 +88,8 @@
return false;
ASSERT(!m_expression.isEmpty());
- for (auto& effect : m_expression) {
- if (!effect->supportsCoreImageRendering())
+ for (auto& term : m_expression) {
+ if (!term.effect->supportsCoreImageRendering())
return false;
}
@@ -99,15 +97,14 @@
}
#endif
-std::optional<FilterEffectGeometry> SVGFilter::effectGeometry(FilterEffect& effect) const
+RefPtr<FilterEffect> SVGFilter::lastEffect() const
{
- auto it = m_effectGeometryMap.find(effect);
- if (it != m_effectGeometryMap.end())
- return it->value;
- return std::nullopt;
+ if (m_expression.isEmpty())
+ return nullptr;
+ return m_expression.last().effect.ptr();
}
-bool SVGFilter::apply(const Filter& filter)
+bool SVGFilter::apply(const Filter& filter, const std::optional<FilterEffectGeometry>&)
{
setSourceImage({ filter.sourceImage() });
return apply();
@@ -116,8 +113,8 @@
RefPtr<FilterImage> SVGFilter::apply()
{
ASSERT(!m_expression.isEmpty());
- for (auto& effect : m_expression) {
- if (!effect->apply(*this))
+ for (auto& term : m_expression) {
+ if (!term.effect->apply(*this, term.geometry))
return nullptr;
}
return lastEffect()->filterImage();
@@ -132,8 +129,8 @@
void SVGFilter::clearResult()
{
ASSERT(!m_expression.isEmpty());
- for (auto& effect : m_expression)
- effect->clearResult();
+ for (auto& term : m_expression)
+ term.effect->clearResult();
}
} // namespace WebCore
Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h (286577 => 286578)
--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h 2021-12-07 00:36:58 UTC (rev 286578)
@@ -22,8 +22,8 @@
#pragma once
#include "Filter.h"
-#include "FilterEffectVector.h"
#include "FloatRect.h"
+#include "SVGFilterExpression.h"
#include "SVGUnitTypes.h"
#include <wtf/Ref.h>
#include <wtf/TypeCasts.h>
@@ -42,7 +42,7 @@
FloatRect targetBoundingBox() const { return m_targetBoundingBox; }
- RefPtr<FilterEffect> lastEffect() const final { return !m_expression.isEmpty() ? m_expression.last() : nullptr; }
+ RefPtr<FilterEffect> lastEffect() const final;
RefPtr<FilterImage> apply() final;
@@ -49,17 +49,14 @@
private:
SVGFilter(RenderingMode, const FloatSize& filterScale, ClipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits);
- // FIXME: Merge the effectBoundaries in the _expression_ node.
- void setExpression(FilterEffectVector&& _expression_) { m_expression = WTFMove(_expression_); }
- void setEffectGeometryMap(FilterEffectGeometryMap&& effectGeometryMap) { m_effectGeometryMap = WTFMove(effectGeometryMap); }
+ void setExpression(SVGFilterExpression&& _expression_) { m_expression = WTFMove(_expression_); }
#if USE(CORE_IMAGE)
bool supportsCoreImageRendering() const final;
#endif
- std::optional<FilterEffectGeometry> effectGeometry(FilterEffect&) const final;
FloatSize resolvedSize(const FloatSize&) const final;
- bool apply(const Filter&) final;
+ bool apply(const Filter&, const std::optional<FilterEffectGeometry>& = std::nullopt) final;
IntOutsets outsets() const final;
void clearResult() final;
@@ -66,9 +63,7 @@
FloatRect m_targetBoundingBox;
SVGUnitTypes::SVGUnitType m_primitiveUnits;
- // FIXME: Make m_expression a Vector of the FilterEffect and the effectBoundaries.
- FilterEffectVector m_expression;
- FilterEffectGeometryMap m_effectGeometryMap;
+ SVGFilterExpression m_expression;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp (286577 => 286578)
--- trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp 2021-12-07 00:36:58 UTC (rev 286578)
@@ -201,8 +201,16 @@
clearResultsRecursive(reference);
}
-static bool buildEffectExpression(const RefPtr<FilterEffect>& effect, FilterEffectVector& stack, FilterEffectVector& _expression_)
+std::optional<FilterEffectGeometry> SVGFilterBuilder::effectGeometry(FilterEffect& effect) const
{
+ auto it = m_effectGeometryMap.find(effect);
+ if (it != m_effectGeometryMap.end())
+ return it->value;
+ return std::nullopt;
+}
+
+bool SVGFilterBuilder::buildEffectExpression(const RefPtr<FilterEffect>& effect, FilterEffectVector& stack, SVGFilterExpression& _expression_) const
+{
// A cycle is detected.
if (stack.contains(effect))
return false;
@@ -209,7 +217,7 @@
stack.append(effect);
- _expression_.append(effect);
+ _expression_.append({ *effect, effectGeometry(*effect) });
for (auto& inputEffect : effect->inputEffects()) {
if (!buildEffectExpression(inputEffect, stack, _expression_))
@@ -223,7 +231,7 @@
return true;
}
-bool SVGFilterBuilder::buildExpression(FilterEffectVector& _expression_) const
+bool SVGFilterBuilder::buildExpression(SVGFilterExpression& _expression_) const
{
if (!m_lastEffect)
return false;
Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h (286577 => 286578)
--- trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h 2021-12-07 00:36:31 UTC (rev 286577)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h 2021-12-07 00:36:58 UTC (rev 286578)
@@ -22,6 +22,7 @@
#pragma once
#include "FilterEffect.h"
+#include "SVGFilterExpression.h"
#include "SVGUnitTypes.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
@@ -68,10 +69,8 @@
void setupBuiltinEffects(Ref<FilterEffect> sourceGraphic);
RefPtr<FilterEffect> buildFilterEffects(SVGFilterElement&);
- bool buildExpression(FilterEffectVector& _expression_) const;
+ bool buildExpression(SVGFilterExpression&) const;
- FilterEffectGeometryMap takeEffectGeometryMap() { return WTFMove(m_effectGeometryMap); }
-
private:
inline void addBuiltinEffects()
{
@@ -79,6 +78,9 @@
m_effectReferences.add(effect, FilterEffectSet());
}
+ std::optional<FilterEffectGeometry> effectGeometry(FilterEffect&) const;
+ bool buildEffectExpression(const RefPtr<FilterEffect>&, FilterEffectVector& stack, SVGFilterExpression&) const;
+
HashMap<AtomString, RefPtr<FilterEffect>> m_builtinEffects;
HashMap<AtomString, RefPtr<FilterEffect>> m_namedEffects;
// The value is a list, which contains those filter effects,
Added: trunk/Source/WebCore/svg/graphics/filters/SVGFilterExpression.h (0 => 286578)
--- trunk/Source/WebCore/svg/graphics/filters/SVGFilterExpression.h (rev 0)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilterExpression.h 2021-12-07 00:36:58 UTC (rev 286578)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "FloatRect.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class FilterEffect;
+
+struct SVGFilterExpressionTerm {
+ Ref<FilterEffect> effect;
+ std::optional<FilterEffectGeometry> geometry;
+};
+
+using SVGFilterExpression = Vector<SVGFilterExpressionTerm>;
+
+} // namespace WebCore