Changeset 286765 in webkit
- Timestamp:
- Dec 8, 2021, 10:39:26 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 27 edited
-
ChangeLog (modified) (1 diff)
-
platform/graphics/coreimage/SourceGraphicCoreImageApplier.mm (modified) (2 diffs)
-
platform/graphics/filters/FEBlend.h (modified) (1 diff)
-
platform/graphics/filters/FEComposite.h (modified) (1 diff)
-
platform/graphics/filters/FEDisplacementMap.cpp (modified) (2 diffs)
-
platform/graphics/filters/FEDisplacementMap.h (modified) (1 diff)
-
platform/graphics/filters/FEFlood.h (modified) (1 diff)
-
platform/graphics/filters/FEMerge.h (modified) (1 diff)
-
platform/graphics/filters/FETurbulence.h (modified) (1 diff)
-
platform/graphics/filters/Filter.cpp (modified) (1 diff)
-
platform/graphics/filters/Filter.h (modified) (3 diffs)
-
platform/graphics/filters/FilterEffect.cpp (modified) (4 diffs)
-
platform/graphics/filters/FilterEffect.h (modified) (4 diffs)
-
platform/graphics/filters/FilterFunction.h (modified) (2 diffs)
-
platform/graphics/filters/FilterImage.cpp (modified) (2 diffs)
-
platform/graphics/filters/FilterImage.h (modified) (3 diffs)
-
platform/graphics/filters/SourceAlpha.cpp (modified) (1 diff)
-
platform/graphics/filters/SourceAlpha.h (modified) (1 diff)
-
platform/graphics/filters/SourceGraphic.cpp (modified) (1 diff)
-
platform/graphics/filters/SourceGraphic.h (modified) (1 diff)
-
platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp (modified) (1 diff)
-
rendering/CSSFilter.cpp (modified) (1 diff)
-
rendering/CSSFilter.h (modified) (1 diff)
-
svg/graphics/filters/SVGFEImage.h (modified) (1 diff)
-
svg/graphics/filters/SVGFilter.cpp (modified) (1 diff)
-
svg/graphics/filters/SVGFilter.h (modified) (2 diffs)
-
svg/graphics/filters/SVGFilterBuilder.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r286763 r286765 1 2021-12-08 Said Abou-Hallawa <said@apple.com> 2 3 [GPU Process] [Filters] Make Filter::apply() and FilterEffect:apply() take FilterImageVector for the inputs 4 https://bugs.webkit.org/show_bug.cgi?id=233973 5 rdar://86248999 6 7 Reviewed by Cameron McCormack. 8 9 This is a step towards removing the dependency on the input effects. This 10 step is required to make encoding/decoding the FilterEffect just be 11 sending or receiving its primitive data. 12 13 In this patch: 14 15 -- The sourceImage and sourceImageRect arguments to Filter::apply() are 16 used to create a FilterImage. This will be the input to the SourceGraphic. 17 18 -- The members m_sourceImage and m_sourceImageRect of Filter are removed. 19 20 -- CSSFilter::apply() loops through its functions and uses the result 21 of every function as the input to the next one. The initial input is 22 the sourceImage. And the result of the last function is the returned 23 FilterImage. 24 25 -- SVGFilter::apply() loops through its expression. It uses a stack of 26 FilterImageVector to keep track of the inputs while applying each 27 FilterEffect. Every FilterEffect is asked to takeInputs() from this 28 stack. The result of applying the FilterEffect is pushed on this stack. 29 The stack should have a single FilterImage when finishing the loop. 30 This item is the result of applying the Filter. 31 32 -- FilterEffect::transformInputsColorSpace() was added to transform the 33 input FilterImageVector to the operating color space of FilterEffect. 34 It is overridden by FEDisplacementMap which does not transform the 35 color space of the first input FilterImage. 36 37 -- FilterEffect::correctPremultipliedInputs() was added to correct the 38 premultiplied pixels of the inputs FilterImageVector. We do not need 39 to do this correction if the FilterEffect we apply is arithmetic 40 composite filter. Otherwise we need to correct the FilterImage of any 41 arithmetic composite filter in the FilterImageVector. 42 43 -- No need for totalNumberFilterEffects(). This count is the size of the 44 SVGFilter expression. 45 46 * platform/graphics/coreimage/SourceGraphicCoreImageApplier.mm: 47 (WebCore::SourceGraphicCoreImageApplier::apply const): 48 * platform/graphics/filters/FEBlend.h: 49 * platform/graphics/filters/FEComposite.h: 50 * platform/graphics/filters/FEDisplacementMap.cpp: 51 (WebCore::FEDisplacementMap::calculateImageRect const): 52 (WebCore::FEDisplacementMap::transformInputsColorSpace const): 53 (WebCore::FEDisplacementMap::transformResultColorSpace): Deleted. 54 * platform/graphics/filters/FEDisplacementMap.h: 55 * platform/graphics/filters/FEFlood.h: 56 * platform/graphics/filters/FEMerge.h: 57 * platform/graphics/filters/FETurbulence.h: 58 * platform/graphics/filters/Filter.cpp: 59 (WebCore::Filter::apply): 60 * platform/graphics/filters/Filter.h: 61 (WebCore::Filter::sourceImageRect const): Deleted. 62 (WebCore::Filter::setSourceImageRect): Deleted. 63 (WebCore::Filter::sourceImage const): Deleted. 64 (WebCore::Filter::setSourceImage): Deleted. 65 * platform/graphics/filters/FilterEffect.cpp: 66 (WebCore::FilterEffect::takeImageInputs const): 67 (WebCore::FilterEffect::calculateImageRect const): 68 (WebCore::FilterEffect::transformInputsColorSpace const): 69 (WebCore::FilterEffect::correctPremultipliedInputs const): 70 (WebCore::FilterEffect::apply): 71 (WebCore::FilterEffect::inputEffect const): 72 (WebCore::FilterEffect::inputFilterImages const): Deleted. 73 (WebCore::FilterEffect::correctPremultipliedResultIfNeeded): Deleted. 74 (WebCore::FilterEffect::transformResultColorSpace): Deleted. 75 * platform/graphics/filters/FilterEffect.h: 76 (WebCore::FilterEffect::filterImage const): 77 (WebCore::FilterEffect::numberOfEffectInputs const): 78 (WebCore::FilterEffect::numberOfImageInputs const): 79 (WebCore::FilterEffect::resultIsValidPremultiplied const): 80 (WebCore::FilterEffect::mayProduceInvalidPremultipliedPixels const): Deleted. 81 (WebCore::FilterEffect::correctFilterResultIfNeeded): Deleted. 82 (WebCore::FilterEffect::transformResultColorSpace): Deleted. 83 * platform/graphics/filters/FilterFunction.h: 84 (WebCore::FilterFunction::apply): 85 * platform/graphics/filters/FilterImage.cpp: 86 (WebCore::FilterImage::create): 87 (WebCore::FilterImage::FilterImage): 88 (WebCore::FilterImage::correctPremultipliedPixelBuffer): 89 * platform/graphics/filters/FilterImage.h: 90 * platform/graphics/filters/SourceAlpha.cpp: 91 (WebCore::SourceAlpha::calculateImageRect const): Deleted. 92 * platform/graphics/filters/SourceAlpha.h: 93 * platform/graphics/filters/SourceGraphic.cpp: 94 (WebCore::SourceGraphic::calculateImageRect const): Deleted. 95 * platform/graphics/filters/SourceGraphic.h: 96 * platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp: 97 (WebCore::SourceGraphicSoftwareApplier::apply const): 98 * rendering/CSSFilter.cpp: 99 (WebCore::CSSFilter::apply): 100 * rendering/CSSFilter.h: 101 * svg/graphics/filters/SVGFEImage.h: 102 * svg/graphics/filters/SVGFilter.cpp: 103 (WebCore::SVGFilter::apply): 104 * svg/graphics/filters/SVGFilter.h: 105 * svg/graphics/filters/SVGFilterBuilder.cpp: 106 (WebCore::SVGFilterBuilder::buildFilterEffects): 107 (WebCore::SVGFilterBuilder::buildExpression const): 108 (WebCore::collectEffects): Deleted. 109 (WebCore::totalNumberFilterEffects): Deleted. 110 1 111 2021-12-08 Patrick Griffis <pgriffis@igalia.com> 2 112 -
trunk/Source/WebCore/platform/graphics/coreimage/SourceGraphicCoreImageApplier.mm
r286193 r286765 29 29 #if USE(CORE_IMAGE) 30 30 31 #import "Filter.h"32 31 #import "FilterImage.h" 33 32 #import "PlatformImageBuffer.h" … … 35 34 namespace WebCore { 36 35 37 bool SourceGraphicCoreImageApplier::apply(const Filter& filter, const FilterImageVector&, FilterImage& result) const36 bool SourceGraphicCoreImageApplier::apply(const Filter&, const FilterImageVector& inputs, FilterImage& result) const 38 37 { 39 auto sourceImage = filter.sourceImage(); 38 auto& input = inputs[0].get(); 39 40 auto sourceImage = input.imageBuffer(); 40 41 if (!sourceImage) 41 42 return false; -
trunk/Source/WebCore/platform/graphics/filters/FEBlend.h
r286589 r286765 42 42 FEBlend(BlendMode); 43 43 44 unsigned numberOfEffectInputs() const override { return 2; } 45 44 46 std::unique_ptr<FilterEffectApplier> createApplier(const Filter&) const override; 45 47 -
trunk/Source/WebCore/platform/graphics/filters/FEComposite.h
r286589 r286765 64 64 FEComposite(const CompositeOperationType&, float k1, float k2, float k3, float k4); 65 65 66 unsigned numberOfEffectInputs() const override { return 2; } 67 66 68 FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const override; 67 69 68 bool mayProduceInvalidPremultipliedPixels() const override { return m_type == FECOMPOSITE_OPERATOR_ARITHMETIC; }70 bool resultIsValidPremultiplied() const override { return m_type != FECOMPOSITE_OPERATOR_ARITHMETIC; } 69 71 70 72 std::unique_ptr<FilterEffectApplier> createApplier(const Filter&) const override; -
trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp
r286589 r286765 69 69 } 70 70 71 FloatRect FEDisplacementMap::calculateImageRect(const Filter& filter, const FilterImageVector&, const FloatRect& primitiveSubregion) const 72 { 73 return filter.maxEffectRect(primitiveSubregion); 74 } 75 71 76 const DestinationColorSpace& FEDisplacementMap::resultColorSpace(const FilterImageVector& inputs) const 72 77 { … … 78 83 } 79 84 80 void FEDisplacementMap::transform ResultColorSpace(FilterEffect* in, const int index)85 void FEDisplacementMap::transformInputsColorSpace(const FilterImageVector& inputs) const 81 86 { 82 87 // Do not transform the first primitive input, as per the spec. 83 if (index) 84 in->transformResultColorSpace(operatingColorSpace()); 85 } 86 87 FloatRect FEDisplacementMap::calculateImageRect(const Filter& filter, const FilterImageVector&, const FloatRect& primitiveSubregion) const 88 { 89 return filter.maxEffectRect(primitiveSubregion); 88 ASSERT(inputs.size() == 2); 89 inputs[1]->transformToColorSpace(operatingColorSpace()); 90 90 } 91 91 -
trunk/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h
r286589 r286765 55 55 FEDisplacementMap(ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, float); 56 56 57 const DestinationColorSpace& resultColorSpace(const FilterImageVector&) const override; 58 void transformResultColorSpace(FilterEffect*, const int) override; 57 unsigned numberOfEffectInputs() const override { return 2; } 59 58 60 59 FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const override; 60 61 const DestinationColorSpace& resultColorSpace(const FilterImageVector&) const override; 62 void transformInputsColorSpace(const FilterImageVector& inputs) const override; 61 63 62 64 std::unique_ptr<FilterEffectApplier> createApplier(const Filter&) const override; -
trunk/Source/WebCore/platform/graphics/filters/FEFlood.h
r286589 r286765 50 50 FEFlood(const Color& floodColor, float floodOpacity); 51 51 52 unsigned numberOfEffectInputs() const override { return 0; } 53 52 54 FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const override; 53 55 -
trunk/Source/WebCore/platform/graphics/filters/FEMerge.h
r286589 r286765 30 30 public: 31 31 WEBCORE_EXPORT static Ref<FEMerge> create(unsigned numberOfEffectInputs); 32 33 unsigned numberOfEffectInputs() const override { return m_numberOfEffectInputs; } 32 34 33 35 template<class Encoder> void encode(Encoder&) const; -
trunk/Source/WebCore/platform/graphics/filters/FETurbulence.h
r286589 r286765 63 63 private: 64 64 FETurbulence(TurbulenceType, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles); 65 66 unsigned numberOfEffectInputs() const override { return 0; } 65 67 66 68 FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const override; -
trunk/Source/WebCore/platform/graphics/filters/Filter.cpp
r286578 r286765 84 84 RefPtr<FilterImage> Filter::apply(ImageBuffer* sourceImage, const FloatRect& sourceImageRect) 85 85 { 86 setSourceImage(sourceImage); 87 setSourceImageRect(sourceImageRect); 86 RefPtr<FilterImage> input; 88 87 89 auto result = apply(); 88 if (sourceImage) { 89 auto absoluteSourceImageRect = enclosingIntRect(scaledByFilterScale(sourceImageRect)); 90 input = FilterImage::create(m_filterRegion, sourceImageRect, absoluteSourceImageRect, Ref { *sourceImage }); 91 if (!input) 92 return nullptr; 93 } 94 95 auto result = apply(input.get()); 90 96 if (!result) 91 return { };97 return nullptr; 92 98 99 result->correctPremultipliedPixelBuffer(); 93 100 result->transformToColorSpace(DestinationColorSpace::SRGB()); 94 101 return result; -
trunk/Source/WebCore/platform/graphics/filters/Filter.h
r286589 r286765 45 45 void setFilterScale(const FloatSize& filterScale) { m_filterScale = filterScale; } 46 46 47 FloatRect sourceImageRect() const { return m_sourceImageRect; }48 void setSourceImageRect(const FloatRect& sourceImageRect) { m_sourceImageRect = sourceImageRect; }49 50 47 FloatRect filterRegion() const { return m_filterRegion; } 51 48 void setFilterRegion(const FloatRect& filterRegion) { m_filterRegion = filterRegion; } 52 53 ImageBuffer* sourceImage() const { return m_sourceImage.get(); }54 void setSourceImage(RefPtr<ImageBuffer>&& sourceImage) { m_sourceImage = WTFMove(sourceImage); }55 49 56 50 ClipOperation clipOperation() const { return m_clipOperation; } … … 69 63 70 64 bool clampFilterRegionIfNeeded(); 71 72 virtual RefPtr<FilterImage> apply( ) = 0;65 66 virtual RefPtr<FilterImage> apply(FilterImage* sourceImage) = 0; 73 67 WEBCORE_EXPORT RefPtr<FilterImage> apply(ImageBuffer* sourceImage, const FloatRect& sourceImageRect); 74 68 … … 82 76 ClipOperation m_clipOperation; 83 77 FloatRect m_filterRegion; 84 85 // FIXME: these should not be members of Filter. They should be passed to Filter::apply().86 FloatRect m_sourceImageRect;87 RefPtr<ImageBuffer> m_sourceImage;88 78 }; 89 79 -
trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp
r286589 r286765 34 34 namespace WebCore { 35 35 36 F loatRect FilterEffect::calculateImageRect(const Filter& filter, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const36 FilterImageVector FilterEffect::takeImageInputs(FilterImageVector& stack) const 37 37 { 38 FloatRect imageRect; 39 for (auto& input : inputs) 40 imageRect.unite(input->imageRect()); 41 return filter.clipToMaxEffectRect(imageRect, primitiveSubregion); 38 unsigned inputsSize = numberOfImageInputs(); 39 ASSERT(stack.size() >= inputsSize); 40 if (!inputsSize) 41 return { }; 42 43 Vector<Ref<FilterImage>> inputs; 44 inputs.reserveInitialCapacity(inputsSize); 45 46 for (; inputsSize; --inputsSize) 47 inputs.uncheckedAppend(stack.takeLast()); 48 49 return inputs; 42 50 } 43 51 … … 69 77 } 70 78 71 F ilterEffect* FilterEffect::inputEffect(unsigned number) const79 FloatRect FilterEffect::calculateImageRect(const Filter& filter, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const 72 80 { 73 ASSERT_WITH_SECURITY_IMPLICATION(number < m_inputEffects.size()); 74 return m_inputEffects.at(number).get(); 81 FloatRect imageRect; 82 for (auto& input : inputs) 83 imageRect.unite(input->imageRect()); 84 return filter.clipToMaxEffectRect(imageRect, primitiveSubregion); 75 85 } 76 86 77 bool FilterEffect::apply(const Filter& filter, const std::optional<FilterEffectGeometry>& geometry) 87 void FilterEffect::transformInputsColorSpace(const FilterImageVector& inputs) const 78 88 { 79 if (hasResult()) 80 return true; 89 for (auto& input : inputs) 90 input->transformToColorSpace(operatingColorSpace()); 91 } 81 92 82 unsigned size = m_inputEffects.size(); 83 for (unsigned i = 0; i < size; ++i) { 84 FilterEffect* in = m_inputEffects.at(i).get(); 93 void FilterEffect::correctPremultipliedInputs(const FilterImageVector& inputs) const 94 { 95 // Correct any invalid pixels, if necessary, in the result of a filter operation. 96 // This method is used to ensure valid pixel values on filter inputs and the final result. 97 // Only the arithmetic composite filter ever needs to perform correction. 98 for (auto& input : inputs) 99 input->correctPremultipliedPixelBuffer(); 100 } 85 101 86 // Convert input results to the current effect's color space. 87 ASSERT(in->hasResult()); 88 transformResultColorSpace(in, i);89 }102 RefPtr<FilterImage> FilterEffect::apply(const Filter& filter, FilterImage& input) 103 { 104 return apply(filter, FilterImageVector { Ref { input } }); 105 } 90 106 91 if (!mayProduceInvalidPremultipliedPixels()) { 92 for (auto& in : m_inputEffects) 93 in->correctPremultipliedResultIfNeeded(); 94 } 107 RefPtr<FilterImage> FilterEffect::apply(const Filter& filter, const FilterImageVector& inputs, const std::optional<FilterEffectGeometry>& geometry) 108 { 109 ASSERT(inputs.size() == numberOfImageInputs()); 95 110 96 auto inputFilterImages = this->inputFilterImages(); 111 if (m_filterImage) 112 return m_filterImage; 97 113 98 auto primitiveSubregion = calculatePrimitiveSubregion(filter, input FilterImages, geometry);99 auto imageRect = calculateImageRect(filter, input FilterImages, primitiveSubregion);114 auto primitiveSubregion = calculatePrimitiveSubregion(filter, inputs, geometry); 115 auto imageRect = calculateImageRect(filter, inputs, primitiveSubregion); 100 116 auto absoluteImageRect = enclosingIntRect(filter.scaledByFilterScale(imageRect)); 101 117 102 118 if (absoluteImageRect.isEmpty() || ImageBuffer::sizeNeedsClamping(absoluteImageRect.size())) 103 return false;119 return nullptr; 104 120 105 auto isAlphaImage = resultIsAlphaImage(inputFilterImages); 106 auto imageColorSpace = resultColorSpace(inputFilterImages); 107 108 m_filterImage = FilterImage::create(primitiveSubregion, imageRect, absoluteImageRect, isAlphaImage, filter.renderingMode(), imageColorSpace); 109 if (!m_filterImage) 110 return false; 121 auto isAlphaImage = resultIsAlphaImage(inputs); 122 auto isValidPremultiplied = resultIsValidPremultiplied(); 123 auto imageColorSpace = resultColorSpace(inputs); 111 124 112 125 auto applier = createApplier(filter); 113 126 if (!applier) 114 return false; 127 return nullptr; 128 129 m_filterImage = FilterImage::create(primitiveSubregion, imageRect, absoluteImageRect, isAlphaImage, isValidPremultiplied, filter.renderingMode(), imageColorSpace); 130 if (!m_filterImage) 131 return nullptr; 115 132 116 133 LOG_WITH_STREAM(Filters, stream … … 121 138 << "\n filter scale " << filter.filterScale()); 122 139 123 return applier->apply(filter, inputFilterImages, *m_filterImage); 140 transformInputsColorSpace(inputs); 141 if (isValidPremultiplied) 142 correctPremultipliedInputs(inputs); 143 144 if (!applier->apply(filter, inputs, *m_filterImage)) 145 m_filterImage = nullptr; 146 147 return m_filterImage; 148 } 149 150 FilterEffect* FilterEffect::inputEffect(unsigned number) const 151 { 152 ASSERT_WITH_SECURITY_IMPLICATION(number < m_inputEffects.size()); 153 return m_inputEffects.at(number).get(); 124 154 } 125 155 … … 136 166 for (auto& effect : m_inputEffects) 137 167 effect->clearResultsRecursive(); 138 }139 140 FilterImageVector FilterEffect::inputFilterImages() const141 {142 FilterImageVector filterImages;143 144 for (auto& inputEffect : m_inputEffects)145 filterImages.append(*inputEffect->filterImage());146 147 return filterImages;148 }149 150 void FilterEffect::correctPremultipliedResultIfNeeded()151 {152 if (!hasResult() || !mayProduceInvalidPremultipliedPixels())153 return;154 m_filterImage->correctPremultipliedPixelBuffer();155 }156 157 void FilterEffect::transformResultColorSpace(const DestinationColorSpace& destinationColorSpace)158 {159 if (!hasResult())160 return;161 m_filterImage->transformToColorSpace(destinationColorSpace);162 168 } 163 169 -
trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h
r286589 r286765 41 41 42 42 class FilterEffect : public FilterFunction { 43 using FilterFunction::apply; 44 43 45 public: 44 46 void clearResult() override; … … 46 48 bool hasResult() const { return m_filterImage; } 47 49 48 FilterImage* filterImage() const { return m_filterImage.get(); } 50 RefPtr<FilterImage> filterImage() const { return m_filterImage; } 51 FilterImageVector takeImageInputs(FilterImageVector& stack) const; 49 52 50 53 FilterEffectVector& inputEffects() { return m_inputEffects; } 51 54 FilterEffect* inputEffect(unsigned) const; 52 unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }53 55 54 void transformResultColorSpace(const DestinationColorSpace&); 55 56 bool apply(const Filter&, const std::optional<FilterEffectGeometry>& = std::nullopt) override; 56 RefPtr<FilterImage> apply(const Filter&, const FilterImageVector& inputs, const std::optional<FilterEffectGeometry>& = std::nullopt); 57 57 58 58 const DestinationColorSpace& operatingColorSpace() const { return m_operatingColorSpace; } … … 64 64 using FilterFunction::FilterFunction; 65 65 66 virtual bool mayProduceInvalidPremultipliedPixels() const { return false; } 66 virtual unsigned numberOfEffectInputs() const { return 1; } 67 unsigned numberOfImageInputs() const { return filterType() == FilterEffect::Type::SourceGraphic ? 1 : numberOfEffectInputs(); } 67 68 68 void correctPremultipliedResultIfNeeded(); 69 70 // Correct any invalid pixels, if necessary, in the result of a filter operation. 71 // This method is used to ensure valid pixel values on filter inputs and the final result. 72 // Only the arithmetic composite filter ever needs to perform correction. 73 virtual void correctFilterResultIfNeeded() { } 74 75 virtual void transformResultColorSpace(FilterEffect* in, const int) { in->transformResultColorSpace(m_operatingColorSpace); } 76 77 FilterImageVector inputFilterImages() const; 78 79 FloatRect calculatePrimitiveSubregion(const Filter&, const FilterImageVector&, const std::optional<FilterEffectGeometry>&) const; 69 FloatRect calculatePrimitiveSubregion(const Filter&, const FilterImageVector& inputs, const std::optional<FilterEffectGeometry>&) const; 80 70 81 71 virtual FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const; … … 83 73 // Solid black image with different alpha values. 84 74 virtual bool resultIsAlphaImage(const FilterImageVector&) const { return false; } 75 76 virtual bool resultIsValidPremultiplied() const { return true; } 77 85 78 virtual const DestinationColorSpace& resultColorSpace(const FilterImageVector&) const { return m_operatingColorSpace; } 86 79 80 virtual void transformInputsColorSpace(const FilterImageVector& inputs) const; 81 82 void correctPremultipliedInputs(const FilterImageVector& inputs) const; 83 87 84 virtual std::unique_ptr<FilterEffectApplier> createApplier(const Filter&) const = 0; 85 86 RefPtr<FilterImage> apply(const Filter&, FilterImage& input) override; 88 87 89 88 FilterEffectVector m_inputEffects; -
trunk/Source/WebCore/platform/graphics/filters/FilterFunction.h
r286589 r286765 27 27 28 28 #include "FilterEffectGeometry.h" 29 #include "FilterImage.h" 30 #include "FilterImageVector.h" 29 31 #include "FloatRect.h" 30 32 #include "IntRectExtent.h" … … 95 97 #endif 96 98 97 virtual bool apply(const Filter&, const std::optional<FilterEffectGeometry>& = std::nullopt) { return false; }99 virtual RefPtr<FilterImage> apply(const Filter&, FilterImage&) { return nullptr; } 98 100 virtual IntOutsets outsets() const { return { }; } 99 101 virtual void clearResult() { } -
trunk/Source/WebCore/platform/graphics/filters/FilterImage.cpp
r286287 r286765 39 39 namespace WebCore { 40 40 41 RefPtr<FilterImage> FilterImage::create(const FloatRect& primitiveSubregion, const FloatRect& imageRect, const IntRect& absoluteImageRect, bool isAlphaImage, RenderingMode renderingMode, const DestinationColorSpace& colorSpace)41 RefPtr<FilterImage> FilterImage::create(const FloatRect& primitiveSubregion, const FloatRect& imageRect, const IntRect& absoluteImageRect, bool isAlphaImage, bool isValidPremultiplied, RenderingMode renderingMode, const DestinationColorSpace& colorSpace) 42 42 { 43 43 ASSERT(!ImageBuffer::sizeNeedsClamping(absoluteImageRect.size())); 44 return adoptRef(new FilterImage(primitiveSubregion, imageRect, absoluteImageRect, isAlphaImage, renderingMode, colorSpace)); 45 } 46 47 FilterImage::FilterImage(const FloatRect& primitiveSubregion, const FloatRect& imageRect, const IntRect& absoluteImageRect, bool isAlphaImage, RenderingMode renderingMode, const DestinationColorSpace& colorSpace) 44 return adoptRef(new FilterImage(primitiveSubregion, imageRect, absoluteImageRect, isAlphaImage, isValidPremultiplied, renderingMode, colorSpace)); 45 } 46 47 RefPtr<FilterImage> FilterImage::create(const FloatRect& primitiveSubregion, const FloatRect& imageRect, const IntRect& absoluteImageRect, Ref<ImageBuffer>&& imageBuffer) 48 { 49 return adoptRef(*new FilterImage(primitiveSubregion, imageRect, absoluteImageRect, WTFMove(imageBuffer))); 50 } 51 52 FilterImage::FilterImage(const FloatRect& primitiveSubregion, const FloatRect& imageRect, const IntRect& absoluteImageRect, bool isAlphaImage, bool isValidPremultiplied, RenderingMode renderingMode, const DestinationColorSpace& colorSpace) 48 53 : m_primitiveSubregion(primitiveSubregion) 49 54 , m_imageRect(imageRect) 50 55 , m_absoluteImageRect(absoluteImageRect) 51 56 , m_isAlphaImage(isAlphaImage) 57 , m_isValidPremultiplied(isValidPremultiplied) 52 58 , m_renderingMode(renderingMode) 53 59 , m_colorSpace(colorSpace) 60 { 61 } 62 63 FilterImage::FilterImage(const FloatRect& primitiveSubregion, const FloatRect& imageRect, const IntRect& absoluteImageRect, Ref<ImageBuffer>&& imageBuffer) 64 : m_primitiveSubregion(primitiveSubregion) 65 , m_imageRect(imageRect) 66 , m_absoluteImageRect(absoluteImageRect) 67 , m_renderingMode(imageBuffer->renderingMode()) 68 , m_colorSpace(imageBuffer->colorSpace()) 69 , m_imageBuffer(WTFMove(imageBuffer)) 54 70 { 55 71 } … … 282 298 { 283 299 // Must operate on pre-multiplied results; other formats cannot have invalid pixels. 284 if (!m_premultipliedPixelBuffer )300 if (!m_premultipliedPixelBuffer || m_isValidPremultiplied) 285 301 return; 286 302 -
trunk/Source/WebCore/platform/graphics/filters/FilterImage.h
r286391 r286765 46 46 class FilterImage : public RefCounted<FilterImage> { 47 47 public: 48 static RefPtr<FilterImage> create(const FloatRect& primitiveSubregion, const FloatRect& imageRect, const IntRect& absoluteImageRect, bool isAlphaImage, RenderingMode, const DestinationColorSpace&); 48 static RefPtr<FilterImage> create(const FloatRect& primitiveSubregion, const FloatRect& imageRect, const IntRect& absoluteImageRect, bool isAlphaImage, bool isValidPremultiplied, RenderingMode, const DestinationColorSpace&); 49 static RefPtr<FilterImage> create(const FloatRect& primitiveSubregion, const FloatRect& imageRect, const IntRect& absoluteImageRect, Ref<ImageBuffer>&&); 49 50 50 51 // The return values are in filter coordinates. … … 77 78 78 79 private: 79 FilterImage(const FloatRect& primitiveSubregion, const FloatRect& imageRect, const IntRect& absoluteImageRect, bool isAlphaImage, RenderingMode, const DestinationColorSpace&); 80 FilterImage(const FloatRect& primitiveSubregion, const FloatRect& imageRect, const IntRect& absoluteImageRect, bool isAlphaImage, bool isValidPremultiplied, RenderingMode, const DestinationColorSpace&); 81 FilterImage(const FloatRect& primitiveSubregion, const FloatRect& imageRect, const IntRect& absoluteImageRect, Ref<ImageBuffer>&&); 80 82 81 83 std::optional<PixelBuffer>& pixelBufferSlot(AlphaPremultiplication); … … 94 96 95 97 bool m_isAlphaImage { false }; 98 bool m_isValidPremultiplied { true }; 96 99 RenderingMode m_renderingMode; 97 100 DestinationColorSpace m_colorSpace; -
trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp
r286753 r286765 49 49 } 50 50 51 FloatRect SourceAlpha::calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect&) const52 {53 return inputs[0]->imageRect();54 }55 56 51 std::unique_ptr<FilterEffectApplier> SourceAlpha::createApplier(const Filter&) const 57 52 { -
trunk/Source/WebCore/platform/graphics/filters/SourceAlpha.h
r286753 r286765 36 36 explicit SourceAlpha(FilterEffect&); 37 37 38 FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const override;39 40 38 std::unique_ptr<FilterEffectApplier> createApplier(const Filter&) const override; 41 39 -
trunk/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp
r286589 r286765 42 42 } 43 43 44 FloatRect SourceGraphic::calculateImageRect(const Filter& filter, const FilterImageVector&, const FloatRect&) const45 {46 return filter.sourceImageRect();47 }48 49 44 std::unique_ptr<FilterEffectApplier> SourceGraphic::createApplier(const Filter& filter) const 50 45 { -
trunk/Source/WebCore/platform/graphics/filters/SourceGraphic.h
r286589 r286765 39 39 #endif 40 40 41 FloatRect calculateImageRect(const Filter&, const FilterImageVector& inputs, const FloatRect& primitiveSubregion) const override;41 unsigned numberOfEffectInputs() const override { return 0; } 42 42 43 43 std::unique_ptr<FilterEffectApplier> createApplier(const Filter&) const override; -
trunk/Source/WebCore/platform/graphics/filters/software/SourceGraphicSoftwareApplier.cpp
r286203 r286765 22 22 #include "SourceGraphicSoftwareApplier.h" 23 23 24 #include "Filter.h"25 24 #include "GraphicsContext.h" 26 25 #include "ImageBuffer.h" 27 #include "SourceGraphic.h"28 26 29 27 namespace WebCore { 30 28 31 bool SourceGraphicSoftwareApplier::apply(const Filter& filter, const FilterImageVector&, FilterImage& result) const29 bool SourceGraphicSoftwareApplier::apply(const Filter&, const FilterImageVector& inputs, FilterImage& result) const 32 30 { 31 auto& input = inputs[0].get(); 32 33 33 auto resultImage = result.imageBuffer(); 34 auto sourceImage = filter.sourceImage();34 auto sourceImage = input.imageBuffer(); 35 35 if (!resultImage || !sourceImage) 36 36 return false; -
trunk/Source/WebCore/rendering/CSSFilter.cpp
r286589 r286765 369 369 } 370 370 371 RefPtr<FilterImage> CSSFilter::apply() 372 { 371 RefPtr<FilterImage> CSSFilter::apply(FilterImage* sourceImage) 372 { 373 if (!sourceImage) 374 return nullptr; 375 376 RefPtr<FilterImage> result = sourceImage; 377 373 378 for (auto& function : m_functions) { 374 if (function->isSVGFilter()) 375 downcast<SVGFilter>(function.ptr())->setSourceImageRect(sourceImageRect()); 376 if (!function->apply(*this)) 379 result = function->apply(*this, *result); 380 if (!result) 377 381 return nullptr; 378 382 } 379 return lastEffect()->filterImage(); 383 384 return result; 380 385 } 381 386 -
trunk/Source/WebCore/rendering/CSSFilter.h
r286589 r286765 57 57 58 58 void clearIntermediateResults(); 59 RefPtr<FilterImage> apply( ) final;59 RefPtr<FilterImage> apply(FilterImage* sourceImage) final; 60 60 61 61 private: -
trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h
r286589 r286765 48 48 FEImage(SourceImage&&, const FloatRect& sourceImageRect, const SVGPreserveAspectRatioValue&); 49 49 50 unsigned numberOfEffectInputs() const override { return 0; } 51 50 52 // FEImage results are always in DestinationColorSpace::SRGB() 51 53 void setOperatingColorSpace(const DestinationColorSpace&) override { } -
trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp
r286753 r286765 118 118 } 119 119 120 bool SVGFilter::apply(const Filter& filter, const std::optional<FilterEffectGeometry>&)120 RefPtr<FilterImage> SVGFilter::apply(const Filter&, FilterImage& sourceImage) 121 121 { 122 setSourceImage({ filter.sourceImage() }); 123 return apply(); 122 return apply(&sourceImage); 124 123 } 125 124 126 RefPtr<FilterImage> SVGFilter::apply( )125 RefPtr<FilterImage> SVGFilter::apply(FilterImage* sourceImage) 127 126 { 128 127 ASSERT(!m_expression.isEmpty()); 128 129 FilterImageVector stack; 130 129 131 for (auto& term : m_expression) { 130 if (!term.effect->apply(*this, term.geometry)) 132 auto& effect = term.effect; 133 auto geometry = term.geometry; 134 135 if (effect->filterType() == FilterEffect::Type::SourceGraphic) { 136 if (auto result = effect->filterImage()) { 137 stack.append(result.releaseNonNull()); 138 continue; 139 } 140 141 if (!sourceImage) 142 return nullptr; 143 144 // Add sourceImage as an input to the SourceGraphic. 145 stack.append(Ref { *sourceImage }); 146 } 147 148 // Need to remove the inputs here in case the effect already has a result. 149 auto inputs = effect->takeImageInputs(stack); 150 151 if (auto result = effect->filterImage()) { 152 stack.append(result.releaseNonNull()); 153 continue; 154 } 155 156 auto result = term.effect->apply(*this, inputs, geometry); 157 if (!result) 131 158 return nullptr; 159 160 stack.append(result.releaseNonNull()); 132 161 } 133 return lastEffect()->filterImage(); 162 163 ASSERT(stack.size() == 1); 164 return stack.takeLast(); 134 165 } 135 166 -
trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h
r286753 r286765 49 49 RefPtr<FilterEffect> lastEffect() const final; 50 50 51 RefPtr<FilterImage> apply( ) final;51 RefPtr<FilterImage> apply(FilterImage* sourceImage) final; 52 52 53 53 WTF::TextStream& externalRepresentation(WTF::TextStream&, FilterRepresentation) const final; … … 64 64 FloatSize resolvedSize(const FloatSize&) const final; 65 65 66 bool apply(const Filter&, const std::optional<FilterEffectGeometry>& = std::nullopt) final;66 RefPtr<FilterImage> apply(const Filter&, FilterImage& sourceImage) final; 67 67 IntOutsets outsets() const final; 68 68 void clearResult() final; -
trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp
r286589 r286765 35 35 namespace WebCore { 36 36 37 static constexpr unsigned maxTotalNumberFilterEffects = 100; 38 static constexpr unsigned maxCountChildNodes = 200; 39 37 40 void SVGFilterBuilder::setupBuiltinEffects(Ref<FilterEffect> sourceGraphic) 38 41 { … … 77 80 #endif 78 81 79 static unsigned collectEffects(const FilterEffect* effect, HashSet<const FilterEffect*>& allEffects)80 {81 allEffects.add(effect);82 unsigned size = effect->numberOfEffectInputs();83 for (unsigned i = 0; i < size; ++i) {84 FilterEffect* in = effect->inputEffect(i);85 collectEffects(in, allEffects);86 }87 return allEffects.size();88 }89 90 static unsigned totalNumberFilterEffects(const FilterEffect& lastEffect)91 {92 HashSet<const FilterEffect*> allEffects;93 return collectEffects(&lastEffect, allEffects);94 }95 96 82 RefPtr<FilterEffect> SVGFilterBuilder::buildFilterEffects(SVGFilterElement& filterElement) 97 83 { 98 static constexpr unsigned maxCountChildNodes = 200;99 static constexpr unsigned maxTotalNumberFilterEffects = 100;100 101 84 if (filterElement.countChildNodes() > maxCountChildNodes) 102 85 return nullptr; … … 125 108 } 126 109 127 if (!effect || totalNumberFilterEffects(*effect) > maxTotalNumberFilterEffects) {110 if (!effect) 128 111 clearEffects(); 129 return nullptr;130 }131 112 132 113 return effect; … … 241 222 return false; 242 223 224 if (expression.size() > maxTotalNumberFilterEffects) 225 return false; 226 243 227 expression.reverse(); 244 228 expression.shrinkToFit();
Note:
See TracChangeset
for help on using the changeset viewer.