Title: [295517] trunk/Source/WebCore
Revision
295517
Author
[email protected]
Date
2022-06-13 23:33:01 -0700 (Mon, 13 Jun 2022)

Log Message

[GPU Process] [Filters] Remove SVGFilterBuilder
https://bugs.webkit.org/show_bug.cgi?id=241577
<rdar://problem/95074247>

Reviewed by Simon Fraser.

After r295498, all the methods of SVGFilterBuilder became static. So this patch
removes it and moves its methods to SVGFilter.

-- colorInterpolationForElement() will be moved to SVGElement::colorInterpolation().
-- effectGeometryFlagsForElement() will be moved to
   SVGFilterPrimitiveStandardAttributes::effectGeometryFlags().
-- FilterData::boundaries is removed. It is set in RenderSVGResourceFilter::
   applyResource() and used only in RenderSVGResourceFilter::postApplyResource()
   where we check '!isEmpty()'. This check can be replaced by checking if filter
   is not nullptr.
-- FilterData::scale is removed since it is not used.
-- FilterData::sourceGraphicBuffer and FilterData::drawingRegion are renamed
   sourceImage and sourceImageRect respectively to match the named of the inputs
   of GraphicsContext::drawFilteredImageBuffer().

* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/rendering/CSSFilter.cpp:
(WebCore::calculateReferenceFilterOutsets):
* Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp:
(WebCore::RenderSVGResourceFilter::applyResource):
(WebCore::RenderSVGResourceFilter::postApplyResource):
(WebCore::RenderSVGResourceFilter::drawingRegion const):
* Source/WebCore/rendering/svg/RenderSVGResourceFilter.h:
* Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp:
(WebCore::writeSVGResourceContainer):
* Source/WebCore/svg/SVGElement.cpp:
(WebCore::SVGElement::colorInterpolation const):
* Source/WebCore/svg/SVGElement.h:
* Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp:
(WebCore::SVGFilterPrimitiveStandardAttributes::effectGeometryFlags const):
* Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h:
* Source/WebCore/svg/graphics/filters/SVGFilter.cpp:
(WebCore::SVGFilter::create):
(WebCore::buildFilterEffectsGraph):
(WebCore::SVGFilter::buildExpression):
(WebCore::buildFilterPrimitivesGraph):
(WebCore::SVGFilter::calculateOutsets):
* Source/WebCore/svg/graphics/filters/SVGFilter.h:
* Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp: Removed.
* Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h: Removed.

Canonical link: https://commits.webkit.org/251522@main

Modified Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/Sources.txt (295516 => 295517)


--- trunk/Source/WebCore/Sources.txt	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/Sources.txt	2022-06-14 06:33:01 UTC (rev 295517)
@@ -2760,7 +2760,6 @@
 svg/graphics/SVGImageCache.cpp
 svg/graphics/SVGImageForContainer.cpp
 svg/graphics/filters/SVGFilter.cpp
-svg/graphics/filters/SVGFilterBuilder.cpp
 svg/properties/SVGAnimatedProperty.cpp
 svg/properties/SVGAnimationAdditiveValueFunctionImpl.cpp
 svg/properties/SVGAttributeAnimator.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (295516 => 295517)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2022-06-14 06:33:01 UTC (rev 295517)
@@ -239,7 +239,6 @@
 		081668D4125603BF006F25DE /* SVGTextChunkBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 081668D2125603BF006F25DE /* SVGTextChunkBuilder.h */; };
 		081668DA125603D5006F25DE /* SVGTextLayoutEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 081668D8125603D5006F25DE /* SVGTextLayoutEngine.h */; };
 		081AA8DA1111237E002AB06E /* SVGElementRareData.h in Headers */ = {isa = PBXBuildFile; fileRef = 081AA8D91111237E002AB06E /* SVGElementRareData.h */; };
-		081EBF3B0FD34F4100DA7559 /* SVGFilterBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 081EBF390FD34F4100DA7559 /* SVGFilterBuilder.h */; };
 		083DAEA70F01A7FB00342754 /* RenderTextControlMultiLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 083DAEA30F01A7FB00342754 /* RenderTextControlMultiLine.h */; };
 		083DAEA90F01A7FB00342754 /* RenderTextControlSingleLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 083DAEA50F01A7FB00342754 /* RenderTextControlSingleLine.h */; };
 		0844B01D1255B4E600B9CDD0 /* SVGBoundingBoxComputation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0844B01D1255E4E600B9CDD0 /* SVGBoundingBoxComputation.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -6252,8 +6251,6 @@
 		081668D7125603D5006F25DE /* SVGTextLayoutEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGTextLayoutEngine.cpp; sourceTree = "<group>"; };
 		081668D8125603D5006F25DE /* SVGTextLayoutEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGTextLayoutEngine.h; sourceTree = "<group>"; };
 		081AA8D91111237E002AB06E /* SVGElementRareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGElementRareData.h; sourceTree = "<group>"; };
-		081EBF380FD34F4100DA7559 /* SVGFilterBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGFilterBuilder.cpp; sourceTree = "<group>"; };
-		081EBF390FD34F4100DA7559 /* SVGFilterBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGFilterBuilder.h; sourceTree = "<group>"; };
 		0834B00C1244E4E600B9CDD0 /* SVGBoundingBoxComputation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGBoundingBoxComputation.cpp; sourceTree = "<group>"; };
 		0834B00C1244E5A610B8AFD1 /* SVGContainerLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGContainerLayout.cpp; sourceTree = "<group>"; };
 		083DAEA20F01A7FB00342754 /* RenderTextControlMultiLine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTextControlMultiLine.cpp; sourceTree = "<group>"; };
@@ -29069,8 +29066,6 @@
 			children = (
 				845E72F90FD2623900A87D79 /* SVGFilter.cpp */,
 				845E72FA0FD2623900A87D79 /* SVGFilter.h */,
-				081EBF380FD34F4100DA7559 /* SVGFilterBuilder.cpp */,
-				081EBF390FD34F4100DA7559 /* SVGFilterBuilder.h */,
 				726CDE25275B489700A445B2 /* SVGFilterExpression.h */,
 				72F7A08027F171BF0008EEE8 /* SVGFilterGraph.h */,
 			);
@@ -37940,7 +37935,6 @@
 				B2227A060D00BF220071B782 /* SVGFETileElement.h in Headers */,
 				B2227A090D00BF220071B782 /* SVGFETurbulenceElement.h in Headers */,
 				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 */,

Modified: trunk/Source/WebCore/rendering/CSSFilter.cpp (295516 => 295517)


--- trunk/Source/WebCore/rendering/CSSFilter.cpp	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/rendering/CSSFilter.cpp	2022-06-14 06:33:01 UTC (rev 295517)
@@ -36,7 +36,6 @@
 #include "ReferencedSVGResources.h"
 #include "RenderElement.h"
 #include "SVGFilter.h"
-#include "SVGFilterBuilder.h"
 #include "SVGFilterElement.h"
 #include "SourceGraphic.h"
 
@@ -253,7 +252,7 @@
     if (!filterElement)
         return { };
 
-    return SVGFilterBuilder::calculateFilterOutsets(*filterElement, targetBoundingBox);
+    return SVGFilter::calculateOutsets(*filterElement, targetBoundingBox);
 }
 
 static RefPtr<SVGFilter> createReferenceFilter(CSSFilter& filter, const ReferenceFilterOperation& filterOperation, RenderElement& renderer, const FloatRect& targetBoundingBox, const GraphicsContext& destinationContext)

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp (295516 => 295517)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2022-06-14 06:33:01 UTC (rev 295517)
@@ -90,10 +90,9 @@
     auto addResult = m_rendererFilterDataMap.set(&renderer, makeUnique<FilterData>());
     auto filterData = addResult.iterator->value.get();
     
-    FloatRect targetBoundingBox = renderer.objectBoundingBox();
-
-    filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement>(&filterElement(), filterElement().filterUnits(), targetBoundingBox);
-    if (filterData->boundaries.isEmpty()) {
+    auto targetBoundingBox = renderer.objectBoundingBox();
+    auto filterRegion = SVGLengthContext::resolveRectangle<SVGFilterElement>(&filterElement(), filterElement().filterUnits(), targetBoundingBox);
+    if (filterRegion.isEmpty()) {
         m_rendererFilterDataMap.remove(&renderer);
         return false;
     }
@@ -109,17 +108,17 @@
     FloatSize filterScale(absoluteTransform.xScale(), absoluteTransform.yScale());
 
     // Determine absolute boundaries of the filter and the drawing region.
-    filterData->drawingRegion = renderer.strokeBoundingBox();
-    filterData->drawingRegion.intersect(filterData->boundaries);
+    filterData->sourceImageRect = renderer.strokeBoundingBox();
+    filterData->sourceImageRect.intersect(filterRegion);
 
     // Determine scale factor for filter. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
-    ImageBuffer::sizeNeedsClamping(filterData->drawingRegion.size(), filterScale);
+    ImageBuffer::sizeNeedsClamping(filterData->sourceImageRect.size(), filterScale);
 
     // Set the rendering mode from the page's settings.
     auto renderingMode = renderer.page().acceleratedFiltersEnabled() ? RenderingMode::Accelerated : RenderingMode::Unaccelerated;
 
     // Create the SVGFilter object.
-    filterData->filter = SVGFilter::create(filterElement(), renderingMode, filterScale, Filter::ClipOperation::Intersect, filterData->boundaries, targetBoundingBox, *context);
+    filterData->filter = SVGFilter::create(filterElement(), renderingMode, filterScale, Filter::ClipOperation::Intersect, filterRegion, targetBoundingBox, *context);
     if (!filterData->filter) {
         m_rendererFilterDataMap.remove(&renderer);
         return false;
@@ -128,9 +127,9 @@
     if (filterData->filter->clampFilterRegionIfNeeded())
         filterScale = filterData->filter->filterScale();
     
-    // If the drawingRegion is empty, we have something like <g filter=".."/>.
+    // If the sourceImageRect is empty, we have something like <g filter=".."/>.
     // Even if the target objectBoundingBox() is empty, we still have to draw the last effect result image in postApplyResource.
-    if (filterData->drawingRegion.isEmpty()) {
+    if (filterData->sourceImageRect.isEmpty()) {
         ASSERT(m_rendererFilterDataMap.contains(&renderer));
         filterData->savedContext = context;
         return false;
@@ -142,20 +141,16 @@
     auto colorSpace = DestinationColorSpace::SRGB();
 #endif
 
-    auto sourceGraphic = context->createScaledImageBuffer(filterData->drawingRegion, filterScale, colorSpace, filterData->filter->renderingMode());
-    if (!sourceGraphic) {
+    filterData->sourceImage = context->createScaledImageBuffer(filterData->sourceImageRect, filterScale, colorSpace, filterData->filter->renderingMode());
+    if (!filterData->sourceImage) {
         ASSERT(m_rendererFilterDataMap.contains(&renderer));
         filterData->savedContext = context;
         return false;
     }
 
-    auto& sourceGraphicContext = sourceGraphic->context();
-
-    filterData->sourceGraphicBuffer = WTFMove(sourceGraphic);
     filterData->savedContext = context;
+    context = &filterData->sourceImage->context();
 
-    context = &sourceGraphicContext;
-
     ASSERT(m_rendererFilterDataMap.contains(&renderer));
     return true;
 }
@@ -201,9 +196,9 @@
         break;
     }
 
-    if (!filterData.boundaries.isEmpty()) {
+    if (filterData.filter) {
         filterData.state = FilterData::Built;
-        context->drawFilteredImageBuffer(filterData.sourceGraphicBuffer.get(), filterData.drawingRegion, *filterData.filter, filterData.results);
+        context->drawFilteredImageBuffer(filterData.sourceImage.get(), filterData.sourceImageRect, *filterData.filter, filterData.results);
     }
 
     LOG_WITH_STREAM(Filters, stream << "RenderSVGResourceFilter " << this << " postApplyResource done\n");
@@ -240,7 +235,7 @@
 FloatRect RenderSVGResourceFilter::drawingRegion(RenderObject* object) const
 {
     FilterData* filterData = m_rendererFilterDataMap.get(object);
-    return filterData ? filterData->drawingRegion : FloatRect();
+    return filterData ? filterData->sourceImageRect : FloatRect();
 }
 
 TextStream& operator<<(TextStream& ts, FilterData::FilterDataState state)

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h (295516 => 295517)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h	2022-06-14 06:33:01 UTC (rev 295517)
@@ -27,7 +27,6 @@
 #include "ImageBuffer.h"
 #include "RenderSVGResourceContainer.h"
 #include "SVGFilter.h"
-#include "SVGFilterBuilder.h"
 #include "SVGUnitTypes.h"
 #include <wtf/IsoMalloc.h>
 #include <wtf/RefPtr.h>
@@ -34,6 +33,7 @@
 
 namespace WebCore {
 
+class GraphicsContext;
 class SVGFilterElement;
 
 struct FilterData {
@@ -45,17 +45,15 @@
     FilterData() = default;
 
     RefPtr<SVGFilter> filter;
-    RefPtr<ImageBuffer> sourceGraphicBuffer;
+    FilterResults results;
+
+    RefPtr<ImageBuffer> sourceImage;
+    FloatRect sourceImageRect;
+
     GraphicsContext* savedContext { nullptr };
-    FloatRect boundaries;
-    FloatRect drawingRegion;
-    FloatSize scale;
     FilterDataState state { PaintingSource };
-    FilterResults results;
 };
 
-class GraphicsContext;
-
 class RenderSVGResourceFilter final : public RenderSVGResourceContainer {
     WTF_MAKE_ISO_ALLOCATED(RenderSVGResourceFilter);
 public:

Modified: trunk/Source/WebCore/svg/SVGElement.cpp (295516 => 295517)


--- trunk/Source/WebCore/svg/SVGElement.cpp	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/svg/SVGElement.cpp	2022-06-14 06:33:01 UTC (rev 295517)
@@ -26,6 +26,8 @@
 #include "config.h"
 #include "SVGElement.h"
 
+#include "CSSComputedStyleDeclaration.h"
+#include "CSSPrimitiveValueMappings.h"
 #include "CSSPropertyParser.h"
 #include "Document.h"
 #include "ElementChildIterator.h"
@@ -712,6 +714,20 @@
     return m_svgRareData->overrideComputedStyle(*this, parentStyle);
 }
 
+ColorInterpolation SVGElement::colorInterpolation() const
+{
+    if (auto renderer = this->renderer())
+        return renderer->style().svgStyle().colorInterpolationFilters();
+
+    // Try to determine the property value from the computed style.
+    if (auto value = ComputedStyleExtractor(const_cast<SVGElement*>(this)).propertyValue(CSSPropertyColorInterpolationFilters, DoNotUpdateLayout)) {
+        if (is<CSSPrimitiveValue>(value))
+            return downcast<CSSPrimitiveValue>(*value);
+    }
+
+    return ColorInterpolation::Auto;
+}
+
 QualifiedName SVGElement::animatableAttributeForName(const AtomString& localName)
 {
     static NeverDestroyed animatableAttributes = [] {

Modified: trunk/Source/WebCore/svg/SVGElement.h (295516 => 295517)


--- trunk/Source/WebCore/svg/SVGElement.h	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/svg/SVGElement.h	2022-06-14 06:33:01 UTC (rev 295517)
@@ -27,6 +27,7 @@
 #include "SVGNames.h"
 #include "SVGParsingError.h"
 #include "SVGPropertyOwnerRegistry.h"
+#include "SVGRenderStyleDefs.h"
 #include "StyledElement.h"
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
@@ -149,6 +150,8 @@
     void animatorWillBeDeleted(const QualifiedName&);
 
     const RenderStyle* computedStyle(PseudoId = PseudoId::None) final;
+    
+    ColorInterpolation colorInterpolation() const;
 
     // These are needed for the RenderTree, animation and DOM.
     AtomString className() const { return AtomString { m_className->currentValue() }; }

Modified: trunk/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp (295516 => 295517)


--- trunk/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp	2022-06-14 06:33:01 UTC (rev 295517)
@@ -66,6 +66,22 @@
     SVGElement::parseAttribute(name, value);
 }
 
+OptionSet<FilterEffectGeometry::Flags> SVGFilterPrimitiveStandardAttributes::effectGeometryFlags() const
+{
+    OptionSet<FilterEffectGeometry::Flags> flags;
+
+    if (hasAttribute(SVGNames::xAttr))
+        flags.add(FilterEffectGeometry::Flags::HasX);
+    if (hasAttribute(SVGNames::yAttr))
+        flags.add(FilterEffectGeometry::Flags::HasY);
+    if (hasAttribute(SVGNames::widthAttr))
+        flags.add(FilterEffectGeometry::Flags::HasWidth);
+    if (hasAttribute(SVGNames::heightAttr))
+        flags.add(FilterEffectGeometry::Flags::HasHeight);
+
+    return flags;
+}
+
 RefPtr<FilterEffect> SVGFilterPrimitiveStandardAttributes::filterEffect(const FilterEffectVector& inputs, const GraphicsContext& destinationContext)
 {
     if (!m_effect)

Modified: trunk/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h (295516 => 295517)


--- trunk/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h	2022-06-14 06:33:01 UTC (rev 295517)
@@ -21,6 +21,7 @@
 
 #pragma once
 
+#include "FilterEffectGeometry.h"
 #include "RenderSVGResourceFilter.h"
 #include "RenderSVGResourceFilterPrimitive.h"
 #include "SVGElement.h"
@@ -50,13 +51,15 @@
     SVGAnimatedLength& heightAnimated() { return m_height; }
     SVGAnimatedString& resultAnimated() { return m_result; }
 
-    void primitiveAttributeChanged(const QualifiedName&);
-    void markFilterEffectForRebuild();
+    OptionSet<FilterEffectGeometry::Flags> effectGeometryFlags() const;
 
     virtual Vector<AtomString> filterEffectInputsNames() const { return { }; }
     virtual IntOutsets outsets(const FloatRect&, SVGUnitTypes::SVGUnitType) const { return { }; }
     RefPtr<FilterEffect> filterEffect(const FilterEffectVector&, const GraphicsContext& destinationContext);
 
+    void primitiveAttributeChanged(const QualifiedName&);
+    void markFilterEffectForRebuild();
+
     static void invalidateFilterPrimitiveParent(SVGElement*);
 
 protected:

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp (295516 => 295517)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp	2022-06-14 06:33:01 UTC (rev 295517)
@@ -23,19 +23,24 @@
 #include "config.h"
 #include "SVGFilter.h"
 
+#include "ElementIterator.h"
 #include "FilterResults.h"
 #include "GeometryUtilities.h"
-#include "SVGFilterBuilder.h"
 #include "SVGFilterElement.h"
+#include "SVGFilterGraph.h"
+#include "SVGFilterPrimitiveStandardAttributes.h"
 #include "SourceGraphic.h"
 
 namespace WebCore {
 
+static constexpr unsigned maxTotalNumberFilterEffects = 100;
+static constexpr unsigned maxCountChildNodes = 200;
+
 RefPtr<SVGFilter> SVGFilter::create(SVGFilterElement& filterElement, RenderingMode renderingMode, const FloatSize& filterScale, ClipOperation clipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, const GraphicsContext& destinationContext)
 {
     auto filter = adoptRef(*new SVGFilter(renderingMode, filterScale, clipOperation, filterRegion, targetBoundingBox, filterElement.primitiveUnits()));
 
-    auto _expression_ = SVGFilterBuilder::buildFilterExpression(filterElement, filter, destinationContext);
+    auto _expression_ = buildExpression(filterElement, filter, destinationContext);
     if (!_expression_)
         return nullptr;
 
@@ -68,6 +73,100 @@
 {
 }
 
+static std::optional<std::tuple<SVGFilterEffectsGraph, FilterEffectGeometryMap>> buildFilterEffectsGraph(SVGFilterElement& filterElement, const SVGFilter& filter, const GraphicsContext& destinationContext)
+{
+    if (filterElement.countChildNodes() > maxCountChildNodes)
+        return std::nullopt;
+
+    SVGFilterEffectsGraph graph(SourceGraphic::create(), SourceAlpha::create());
+    FilterEffectGeometryMap effectGeometryMap;
+
+    for (auto& effectElement : childrenOfType<SVGFilterPrimitiveStandardAttributes>(filterElement)) {
+        auto inputs = graph.getNamedNodes(effectElement.filterEffectInputsNames());
+        if (!inputs)
+            return std::nullopt;
+
+        auto effect = effectElement.filterEffect(*inputs, destinationContext);
+        if (!effect)
+            return std::nullopt;
+
+        if (auto flags = effectElement.effectGeometryFlags()) {
+            auto effectBoundaries = SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(&effectElement, filter.primitiveUnits(), filter.targetBoundingBox());
+            effectGeometryMap.add(*effect, FilterEffectGeometry(effectBoundaries, flags));
+        }
+
+#if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB)
+        if (effectElement.colorInterpolation() == ColorInterpolation::LinearRGB)
+            effect->setOperatingColorSpace(DestinationColorSpace::LinearSRGB());
+#endif
+
+        graph.addNamedNode(AtomString { effectElement.result() }, { *effect });
+        graph.setNodeInputs(*effect, WTFMove(*inputs));
+    }
+
+    return { { WTFMove(graph), WTFMove(effectGeometryMap) } };
+}
+
+std::optional<SVGFilterExpression> SVGFilter::buildExpression(SVGFilterElement& filterElement, const SVGFilter& filter, const GraphicsContext& destinationContext)
+{
+    auto result = buildFilterEffectsGraph(filterElement, filter, destinationContext);
+    if (!result)
+        return std::nullopt;
+
+    auto& graph = std::get<SVGFilterEffectsGraph>(*result);
+    auto& effectGeometryMap = std::get<FilterEffectGeometryMap>(*result);
+
+    auto effectGeometry = [&](FilterEffect& effect) -> std::optional<FilterEffectGeometry> {
+        auto it = effectGeometryMap.find(effect);
+        if (it != effectGeometryMap.end())
+            return it->value;
+        return std::nullopt;
+    };
+    
+    SVGFilterExpression _expression_;
+    bool success = graph.visit([&](FilterEffect& effect, unsigned level) {
+        _expression_.append({ effect, effectGeometry(effect), level });
+    });
+    
+    if (!success || _expression_.size() > maxTotalNumberFilterEffects)
+        return std::nullopt;
+    
+    _expression_.reverse();
+    _expression_.shrinkToFit();
+    return _expression_;
+}
+
+static std::optional<SVGFilterPrimitivesGraph> buildFilterPrimitivesGraph(SVGFilterElement& filterElement)
+{
+    if (filterElement.countChildNodes() > maxCountChildNodes)
+        return std::nullopt;
+
+    SVGFilterPrimitivesGraph graph;
+
+    for (auto& effectElement : childrenOfType<SVGFilterPrimitiveStandardAttributes>(filterElement)) {
+        // We should not be strict about not finding the input primitives here because SourceGraphic and SourceAlpha do not have primitives.
+        auto inputs = graph.getNamedNodes(effectElement.filterEffectInputsNames()).value_or(SVGFilterPrimitivesGraph::NodeVector());
+        graph.addNamedNode(AtomString { effectElement.result() }, { effectElement });
+        graph.setNodeInputs(effectElement, WTFMove(inputs));
+    }
+
+    return graph;
+}
+
+IntOutsets SVGFilter::calculateOutsets(SVGFilterElement& filterElement, const FloatRect& targetBoundingBox)
+{
+    auto graph = buildFilterPrimitivesGraph(filterElement);
+    if (!graph)
+        return { };
+
+    IntOutsets outsets;
+    bool result = graph->visit([&](SVGFilterPrimitiveStandardAttributes& primitive, unsigned) {
+        outsets += primitive.outsets(targetBoundingBox, filterElement.primitiveUnits());
+    });
+
+    return result ? outsets : IntOutsets();
+}
+
 FloatSize SVGFilter::calculateResolvedSize(const FloatSize& size, const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits)
 {
     return primitiveUnits == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX ? size * targetBoundingBox.size() : size;

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


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h	2022-06-14 06:33:01 UTC (rev 295517)
@@ -39,6 +39,8 @@
     static RefPtr<SVGFilter> create(SVGFilterElement&, RenderingMode, const FloatSize& filterScale, ClipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, const GraphicsContext& destinationContext);
     WEBCORE_EXPORT static RefPtr<SVGFilter> create(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits, SVGFilterExpression&&);
 
+    static IntOutsets calculateOutsets(SVGFilterElement&, const FloatRect& targetBoundingBox);
+
     FloatRect targetBoundingBox() const { return m_targetBoundingBox; }
     SVGUnitTypes::SVGUnitType primitiveUnits() const { return m_primitiveUnits; }
 
@@ -56,6 +58,7 @@
     SVGFilter(RenderingMode, const FloatSize& filterScale, ClipOperation, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits);
     SVGFilter(const FloatRect& targetBoundingBox, SVGUnitTypes::SVGUnitType primitiveUnits, SVGFilterExpression&&);
 
+    static std::optional<SVGFilterExpression> buildExpression(SVGFilterElement&, const SVGFilter&, const GraphicsContext& destinationContext);
     void setExpression(SVGFilterExpression&& _expression_) { m_expression = WTFMove(_expression_); }
 
     FloatSize resolvedSize(const FloatSize&) const final;

Deleted: trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp (295516 => 295517)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp	2022-06-14 06:33:01 UTC (rev 295517)
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2009 Dirk Schulze <[email protected]>
- * Copyright (C) 2021-2022 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
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "SVGFilterBuilder.h"
-
-#include "ElementIterator.h"
-#include "SVGFilterElement.h"
-#include "SVGFilterGraph.h"
-#include "SVGFilterPrimitiveStandardAttributes.h"
-
-#if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB)
-#include "CSSComputedStyleDeclaration.h"
-#include "CSSPrimitiveValueMappings.h"
-#endif
-
-namespace WebCore {
-
-static constexpr unsigned maxTotalNumberFilterEffects = 100;
-static constexpr unsigned maxCountChildNodes = 200;
-
-static OptionSet<FilterEffectGeometry::Flags> effectGeometryFlagsForElement(SVGElement& element)
-{
-    OptionSet<FilterEffectGeometry::Flags> flags;
-
-    if (element.hasAttribute(SVGNames::xAttr))
-        flags.add(FilterEffectGeometry::Flags::HasX);
-
-    if (element.hasAttribute(SVGNames::yAttr))
-        flags.add(FilterEffectGeometry::Flags::HasY);
-
-    if (element.hasAttribute(SVGNames::widthAttr))
-        flags.add(FilterEffectGeometry::Flags::HasWidth);
-
-    if (element.hasAttribute(SVGNames::heightAttr))
-        flags.add(FilterEffectGeometry::Flags::HasHeight);
-
-    return flags;
-}
-
-#if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB)
-static ColorInterpolation colorInterpolationForElement(SVGElement& element)
-{
-    if (auto renderer = element.renderer())
-        return renderer->style().svgStyle().colorInterpolationFilters();
-
-    // Try to determine the property value from the computed style.
-    if (auto value = ComputedStyleExtractor(&element).propertyValue(CSSPropertyColorInterpolationFilters, DoNotUpdateLayout)) {
-        if (is<CSSPrimitiveValue>(value))
-            return downcast<CSSPrimitiveValue>(*value);
-    }
-
-    return ColorInterpolation::Auto;
-}
-#endif
-
-std::optional<SVGFilterExpression> SVGFilterBuilder::buildFilterExpression(SVGFilterElement& filterElement, const SVGFilter& filter, const GraphicsContext& destinationContext)
-{
-    if (filterElement.countChildNodes() > maxCountChildNodes)
-        return std::nullopt;
-
-    SVGFilterEffectsGraph graph(SourceGraphic::create(), SourceAlpha::create());
-    FilterEffectGeometryMap effectGeometryMap;
-
-    for (auto& effectElement : childrenOfType<SVGFilterPrimitiveStandardAttributes>(filterElement)) {
-        auto inputs = graph.getNamedNodes(effectElement.filterEffectInputsNames());
-        if (!inputs)
-            return std::nullopt;
-
-        auto effect = effectElement.filterEffect(*inputs, destinationContext);
-        if (!effect)
-            return std::nullopt;
-
-        if (auto flags = effectGeometryFlagsForElement(effectElement)) {
-            auto effectBoundaries = SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(&effectElement, filter.primitiveUnits(), filter.targetBoundingBox());
-            effectGeometryMap.add(*effect, FilterEffectGeometry(effectBoundaries, flags));
-        }
-
-#if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB)
-        if (colorInterpolationForElement(effectElement) == ColorInterpolation::LinearRGB)
-            effect->setOperatingColorSpace(DestinationColorSpace::LinearSRGB());
-#endif
-
-        graph.addNamedNode(AtomString { effectElement.result() }, { *effect });
-        graph.setNodeInputs(*effect, WTFMove(*inputs));
-    }
-
-    auto effectGeometry = [&](FilterEffect& effect) -> std::optional<FilterEffectGeometry> {
-        auto it = effectGeometryMap.find(effect);
-        if (it != effectGeometryMap.end())
-            return it->value;
-        return std::nullopt;
-    };
-
-    SVGFilterExpression _expression_;
-    bool result = graph.visit([&](FilterEffect& effect, unsigned level) {
-        _expression_.append({ effect, effectGeometry(effect), level });
-    });
-
-    if (!result || _expression_.size() > maxTotalNumberFilterEffects)
-        return std::nullopt;
-
-    _expression_.reverse();
-    _expression_.shrinkToFit();
-    return _expression_;
-}
-
-static std::optional<SVGFilterPrimitivesGraph> buildFilterPrimitivesGraph(SVGFilterElement& filterElement)
-{
-    if (filterElement.countChildNodes() > maxCountChildNodes)
-        return std::nullopt;
-
-    SVGFilterPrimitivesGraph graph;
-
-    for (auto& effectElement : childrenOfType<SVGFilterPrimitiveStandardAttributes>(filterElement)) {
-        // We should not be strict about not finding the input primitives here because SourceGraphic and SourceAlpha do not have primitives.
-        auto inputs = graph.getNamedNodes(effectElement.filterEffectInputsNames()).value_or(SVGFilterPrimitivesGraph::NodeVector());
-        graph.addNamedNode(AtomString { effectElement.result() }, { effectElement });
-        graph.setNodeInputs(effectElement, WTFMove(inputs));
-    }
-
-    return graph;
-}
-
-IntOutsets SVGFilterBuilder::calculateFilterOutsets(SVGFilterElement& filterElement, const FloatRect& targetBoundingBox)
-{
-    auto graph = buildFilterPrimitivesGraph(filterElement);
-    if (!graph)
-        return { };
-
-    IntOutsets outsets;
-    bool result = graph->visit([&](SVGFilterPrimitiveStandardAttributes& primitive, unsigned) {
-        outsets += primitive.outsets(targetBoundingBox, filterElement.primitiveUnits());
-    });
-
-    return result ? outsets : IntOutsets();
-}
-
-} // namespace WebCore

Deleted: trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h (295516 => 295517)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h	2022-06-14 06:30:59 UTC (rev 295516)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h	2022-06-14 06:33:01 UTC (rev 295517)
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2008 Alex Mathews <[email protected]>
- * Copyright (C) 2009 Dirk Schulze <[email protected]>
- * Copyright (C) 2021-2022 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
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#pragma once
-
-#include "SVGFilterExpression.h"
-#include "SVGUnitTypes.h"
-
-namespace WebCore {
-
-class FilterEffect;
-class GraphicsContext;
-class RenderObject;
-class SVGFilter;
-class SVGFilterElement;
-
-class SVGFilterBuilder {
-public:
-    static std::optional<SVGFilterExpression> buildFilterExpression(SVGFilterElement&, const SVGFilter&, const GraphicsContext& destinationContext);
-    static IntOutsets calculateFilterOutsets(SVGFilterElement&, const FloatRect& targetBoundingBox);
-};
-    
-} // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to