Changeset 285618 in webkit
- Timestamp:
- Nov 10, 2021, 8:31:07 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 19 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/TestExpectations (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/css/CSSFilterImageValue.cpp (modified) (1 diff)
-
Source/WebCore/platform/graphics/filters/Filter.h (modified) (1 diff)
-
Source/WebCore/platform/graphics/filters/FilterEffect.cpp (modified) (1 diff)
-
Source/WebCore/platform/graphics/filters/FilterEffect.h (modified) (4 diffs)
-
Source/WebCore/platform/graphics/filters/FilterFunction.h (modified) (2 diffs)
-
Source/WebCore/rendering/CSSFilter.cpp (modified) (8 diffs)
-
Source/WebCore/rendering/CSSFilter.h (modified) (1 diff)
-
Source/WebCore/rendering/RenderLayer.cpp (modified) (1 diff)
-
Source/WebCore/rendering/RenderLayerFilters.cpp (modified) (3 diffs)
-
Source/WebCore/rendering/RenderLayerFilters.h (modified) (1 diff)
-
Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp (modified) (2 diffs)
-
Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp (modified) (1 diff)
-
Source/WebCore/svg/graphics/filters/SVGFilter.cpp (modified) (2 diffs)
-
Source/WebCore/svg/graphics/filters/SVGFilter.h (modified) (2 diffs)
-
Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp (modified) (1 diff)
-
Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r285615 r285618 1 2021-11-10 Said Abou-Hallawa <said@apple.com> 2 3 [GPU Process] Make CSSFilter be a composite of FilterFunctions 4 https://bugs.webkit.org/show_bug.cgi?id=232469 5 rdar://85047148 6 7 Reviewed by Simon Fraser. 8 9 Unskip filter hidpi layout tests. 10 11 * TestExpectations: 12 1 13 2021-11-10 Tim Nguyen <ntim@apple.com> 2 14 -
trunk/LayoutTests/TestExpectations
r285615 r285618 5174 5174 5175 5175 # These filter related failures should be fixed once webkit.org/b/232705 is resolved 5176 webkit.org/b/232705 compositing/filters/drop-shadow.html [ Skip ] 5177 webkit.org/b/232705 compositing/filters/simple-image-with-svg-filter.html [ Skip ] 5178 webkit.org/b/232705 css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-remove.html [ Skip ] 5179 webkit.org/b/232705 css3/filters/color-interpolation-filters.html [ Skip ] 5180 webkit.org/b/232705 css3/filters/css-opacity-with-drop-shadow.html [ Skip ] 5181 webkit.org/b/232705 css3/filters/drop-shadow.html [ Skip ] 5182 webkit.org/b/232705 css3/filters/effect-brightness-square.html [ Skip ] 5183 webkit.org/b/232705 css3/filters/effect-contrast-square.html [ Skip ] 5184 webkit.org/b/232705 css3/filters/effect-grayscale-square.html [ Skip ] 5185 webkit.org/b/232705 css3/filters/effect-hue-rotate-square.html [ Skip ] 5186 webkit.org/b/232705 css3/filters/effect-invert-square.html [ Skip ] 5187 webkit.org/b/232705 css3/filters/effect-reference-local-url-with-base.html [ Skip ] 5188 webkit.org/b/232705 css3/filters/effect-saturate-square.html [ Skip ] 5189 webkit.org/b/232705 css3/filters/effect-sepia-square.html [ Skip ] 5190 webkit.org/b/232705 css3/filters/filter-is-on-subpixel-position.html [ Skip ] 5191 webkit.org/b/232705 css3/filters/filter-on-overflow-hidden.html [ Skip ] 5192 webkit.org/b/232705 css3/filters/filters-on-svg-root.html [ Skip ] 5193 webkit.org/b/232705 css3/filters/hidpi-feConvolveMatrix.html [ Skip ] 5194 webkit.org/b/232705 css3/filters/hidpi-filter-is-on-subpixel-position.html [ Skip ] 5195 webkit.org/b/232705 css3/filters/invalidate-sourceAlpha.html [ Skip ] 5196 webkit.org/b/232705 css3/filters/null-effect-check.html [ Skip ] 5197 webkit.org/b/232705 css3/filters/reference-filter-set-filter-regions.html [ Skip ] 5198 webkit.org/b/232705 css3/masking/clip-path-filter.html [ Skip ] 5176 webkit.org/b/232705 compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow.html [ Skip ] 5177 webkit.org/b/232705 compositing/filters/sw-shadow-overlaps-hw-layer.html [ Skip ] 5178 webkit.org/b/232705 compositing/filters/sw-shadow-overlaps-hw-shadow.html [ Skip ] 5179 webkit.org/b/232705 css3/filters/effect-reference-delete.html [ Skip ] 5180 webkit.org/b/232705 css3/filters/svg-blur-filter-clipped.html [ Skip ] 5181 webkit.org/b/232705 fast/filter-image/background-filter-image.html [ Skip ] 5182 webkit.org/b/232705 fast/filter-image/filter-image-blur.html [ Skip ] 5183 webkit.org/b/232705 fast/filter-image/filter-image-svg.html [ Skip ] 5199 5184 webkit.org/b/232705 fast/filter-image/filter-image.html [ Skip ] 5200 webkit.org/b/232705 fast/gradients/conic-gradient-alpha.html [ Skip ]5201 webkit.org/b/232705 fast/gradients/conic-gradient-extended-stops.html [ Skip ]5202 webkit.org/b/232705 fast/gradients/conic-gradient.html [ Skip ]5203 webkit.org/b/232705 fast/hidpi/filters-and-image-buffer-resolution.html [ Skip ]5204 webkit.org/b/232705 fast/hidpi/filters-blur.html [ Skip ]5205 webkit.org/b/232705 fast/hidpi/filters-component-transfer.html [ Skip ]5206 webkit.org/b/232705 fast/hidpi/filters-hue-rotate.html [ Skip ]5207 webkit.org/b/232705 fast/hidpi/filters-invert.html [ Skip ]5208 webkit.org/b/232705 fast/hidpi/filters-morphology.html [ Skip ]5209 webkit.org/b/232705 fast/hidpi/filters-multiple.html [ Skip ]5210 webkit.org/b/232705 fast/hidpi/filters-reference.html [ Skip ]5211 webkit.org/b/232705 fast/hidpi/filters-shadow.html [ Skip ]5212 webkit.org/b/232705 fast/hidpi/filters-turbulence.html [ Skip ]5213 webkit.org/b/232705 fast/multicol/filter-in-columns.html [ Skip ]5214 webkit.org/b/232705 http/tests/css/filters-on-iframes.html [ Skip ]5215 webkit.org/b/232705 imported/blink/css3/filters/effect-reference-add-hw.html [ Skip ]5216 webkit.org/b/232705 imported/blink/css3/filters/effect-reference-on-transparent-element.html [ Skip ]5217 webkit.org/b/232705 imported/blink/css3/filters/effect-reference-source-alpha-hw.html [ Skip ]5218 5185 webkit.org/b/232705 imported/blink/svg/filters/filter-huge-clamping.svg [ Skip ] 5219 webkit.org/b/232705 imported/mozilla/svg/svg-effects-area-unzoomed.xhtml [ Skip ] 5220 webkit.org/b/232705 imported/mozilla/svg/svg-effects-area-zoomed-in.xhtml [ Skip ] 5221 webkit.org/b/232705 imported/mozilla/svg/svg-effects-area-zoomed-out.xhtml [ Skip ] 5222 webkit.org/b/232705 imported/w3c/web-platform-tests/css/css-overflow/overflow-scroll-resize-visibility-hidden.html [ Skip ] 5223 webkit.org/b/232705 svg/custom/feColorMatrix-values-leading-spaces.html [ Skip ] 5186 webkit.org/b/232705 imported/mozilla/svg/dynamic-filter-contents-01a.svg [ Skip ] 5187 webkit.org/b/232705 imported/mozilla/svg/filters/feComposite-2.svg [ Skip ] 5188 webkit.org/b/232705 imported/mozilla/svg/filters/feSpecularLighting-1.svg [ Skip ] 5224 5189 webkit.org/b/232705 svg/custom/resources-css-scaled.html [ Skip ] 5190 webkit.org/b/232705 svg/filters/feLighting-clipped.svg [ Skip ] 5225 5191 webkit.org/b/232705 svg/filters/big-sized-off-viewport-filter.svg [ Skip ] -
trunk/Source/WebCore/ChangeLog
r285617 r285618 1 2021-11-10 Said Abou-Hallawa <said@apple.com> 2 3 [GPU Process] Make CSSFilter be a composite of FilterFunctions 4 https://bugs.webkit.org/show_bug.cgi?id=232469 5 rdar://85047148 6 7 Reviewed by Simon Fraser. 8 9 In this patch, the CSS reference filter is built as an SVGFilter and it 10 is kept as a FilterFunction in the CSSFilter functions' list. The Filter 11 associated with the FilterEffects of the referenced filter will be an 12 SVGFilter instead of the root CSSFilter. This will allow having color 13 spacing for the referenced filters different from the color spacing of 14 CSSFilter. 15 16 Also this patch makes a single function for building the primitives of 17 the SVGFilter instead of having two functions. 18 19 To allow operating through the SVGFilter as a FilterFunction owned by 20 CSSFilter, the SVGFilter will have a pointer to its lastEffect. 21 22 * css/CSSFilterImageValue.cpp: 23 (WebCore::CSSFilterImageValue::image): 24 * platform/graphics/filters/Filter.h: 25 * platform/graphics/filters/FilterEffect.cpp: 26 (WebCore::collectEffects): Deleted. 27 (WebCore::FilterEffect::totalNumberOfEffectInputs const): Deleted. 28 * platform/graphics/filters/FilterEffect.h: 29 (WebCore::FilterEffect::numberOfEffectInputs const): 30 (WebCore::FilterEffect::setMaxEffectRect): 31 (WebCore::FilterEffect::outsets const): Deleted. 32 * platform/graphics/filters/FilterFunction.h: 33 (WebCore::FilterFunction::outsets const): 34 (WebCore::FilterFunction::clearResult): 35 * rendering/CSSFilter.cpp: 36 (WebCore::CSSFilter::create): 37 (WebCore::CSSFilter::CSSFilter): 38 (WebCore::m_hasFilterThatShouldBeRestrictedBySecurityOrigin): 39 (WebCore::createBlurEffect): 40 (WebCore::createBrightnessEffect): 41 (WebCore::createContrastEffect): 42 (WebCore::createDropShadowEffect): 43 (WebCore::createGrayScaleEffect): 44 (WebCore::createHueRotateEffect): 45 (WebCore::createInvertEffect): 46 (WebCore::createOpacityEffect): 47 (WebCore::createSaturateEffect): 48 (WebCore::createSepiaEffect): 49 (WebCore::createSVGFilter): 50 (WebCore::setupLastEffectProperties): 51 (WebCore::CSSFilter::buildFilterFunctions): 52 (WebCore::CSSFilter::inputContext): 53 (WebCore::CSSFilter::allocateBackingStoreIfNeeded): 54 (WebCore::CSSFilter::lastEffect): 55 (WebCore::CSSFilter::determineFilterPrimitiveSubregion): 56 (WebCore::CSSFilter::clearIntermediateResults): 57 (WebCore::CSSFilter::apply): 58 (WebCore::CSSFilter::output): 59 (WebCore::CSSFilter::setSourceImageRect): 60 (WebCore::CSSFilter::outputRect): 61 (WebCore::CSSFilter::outsets const): 62 (WebCore::m_sourceGraphic): Deleted. 63 (WebCore::CSSFilter::buildReferenceFilter): Deleted. 64 (WebCore::CSSFilter::build): Deleted. 65 (WebCore::CSSFilter::output const): Deleted. 66 (WebCore::CSSFilter::setMaxEffectRects): Deleted. 67 (WebCore::CSSFilter::outputRect const): Deleted. 68 * rendering/CSSFilter.h: 69 * rendering/RenderLayer.cpp: 70 (WebCore::RenderLayer::setupFilters): 71 * rendering/RenderLayerFilters.cpp: 72 (WebCore::RenderLayerFilters::buildFilter): 73 (WebCore::RenderLayerFilters::beginFilterEffect): 74 (WebCore::RenderLayerFilters::applyFilterEffect): 75 * rendering/RenderLayerFilters.h: 76 * rendering/svg/RenderSVGResourceFilter.cpp: 77 (WebCore::RenderSVGResourceFilter::applyResource): 78 (WebCore::RenderSVGResourceFilter::buildPrimitives const): Deleted. 79 * rendering/svg/SVGRenderTreeAsText.cpp: 80 (WebCore::writeSVGResourceContainer): 81 * svg/graphics/filters/SVGFilter.cpp: 82 (WebCore::SVGFilter::create): 83 (WebCore::SVGFilter::outsets const): 84 (WebCore::SVGFilter::clearResult): 85 * svg/graphics/filters/SVGFilter.h: 86 * svg/graphics/filters/SVGFilterBuilder.cpp: 87 (WebCore::SVGFilterBuilder::setupBuiltinEffects): 88 (WebCore::colorInterpolationForElement): 89 (WebCore::collectEffects): 90 (WebCore::totalNumberFilterEffects): 91 (WebCore::SVGFilterBuilder::buildFilterEffects): 92 (WebCore::SVGFilterBuilder::SVGFilterBuilder): Deleted. 93 * svg/graphics/filters/SVGFilterBuilder.h: 94 1 95 2021-11-10 J Pascoe <j_pascoe@apple.com> 2 96 -
trunk/Source/WebCore/css/CSSFilterImageValue.cpp
r285597 r285618 117 117 // Transform Image into ImageBuffer. 118 118 // FIXME (149424): This buffer should not be unconditionally unaccelerated. 119 auto texture = ImageBuffer::create(size, RenderingMode::Unaccelerated, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8); 120 if (!texture) 119 auto renderingMode = RenderingMode::Unaccelerated; 120 auto sourceImage = ImageBuffer::create(size, renderingMode, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8); 121 if (!sourceImage) 121 122 return &Image::nullImage(); 122 123 123 auto imageRect = FloatRect { { }, size };124 texture->context().drawImage(*image, imageRect);124 auto sourceImageRect = FloatRect { { }, size }; 125 sourceImage->context().drawImage(*image, sourceImageRect); 125 126 126 auto cssFilter = CSSFilter::create( );127 cssFilter->setSourceImage(WTFMove(texture)); 128 cssFilter->setSourceImageRect( imageRect);129 if (!cssFilter->build (renderer, m_filterOperations, FilterConsumer::FilterFunction))127 auto cssFilter = CSSFilter::create(m_filterOperations, renderingMode); 128 129 cssFilter->setSourceImageRect(sourceImageRect); 130 if (!cssFilter->buildFilterFunctions(renderer, m_filterOperations, FilterConsumer::FilterFunction)) 130 131 return &Image::nullImage(); 132 133 cssFilter->setSourceImage(WTFMove(sourceImage)); 131 134 cssFilter->apply(); 132 135 -
trunk/Source/WebCore/platform/graphics/filters/Filter.h
r285597 r285618 22 22 #pragma once 23 23 24 #include "AffineTransform.h"25 24 #include "FilterFunction.h" 26 25 #include "FloatRect.h" 27 26 #include "GraphicsTypes.h" 28 27 #include "ImageBuffer.h" 28 #include "RenderingMode.h" 29 29 30 30 namespace WebCore { -
trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp
r285597 r285618 144 144 } 145 145 146 static unsigned collectEffects(const FilterEffect*effect, HashSet<const FilterEffect*>& allEffects)147 {148 allEffects.add(effect);149 unsigned size = effect->numberOfEffectInputs();150 for (unsigned i = 0; i < size; ++i) {151 FilterEffect* in = effect->inputEffect(i);152 collectEffects(in, allEffects);153 }154 return allEffects.size();155 }156 157 unsigned FilterEffect::totalNumberOfEffectInputs() const158 {159 HashSet<const FilterEffect*> allEffects;160 return collectEffects(this, allEffects);161 }162 163 146 void FilterEffect::apply() 164 147 { -
trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h
r285543 r285618 49 49 class FilterEffect : public FilterFunction { 50 50 public: 51 void clearResult() ;51 void clearResult() override; 52 52 void clearResultsRecursive(); 53 53 … … 60 60 FilterEffect* inputEffect(unsigned) const; 61 61 unsigned numberOfEffectInputs() const { return m_inputEffects.size(); } 62 unsigned totalNumberOfEffectInputs() const;63 62 64 63 inline bool hasResult() const … … 84 83 85 84 FloatRect maxEffectRect() const { return m_maxEffectRect; } 86 void setMaxEffectRect(const FloatRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; } 85 void setMaxEffectRect(const FloatRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; } 87 86 88 87 void apply(); … … 94 93 95 94 virtual void determineAbsolutePaintRect(); 96 97 virtual IntOutsets outsets() const { return IntOutsets(); }98 95 99 96 enum class RepresentationType { TestOutput, Debugging }; -
trunk/Source/WebCore/platform/graphics/filters/FilterFunction.h
r285543 r285618 26 26 #pragma once 27 27 28 #include "FloatRect.h" 29 #include "IntRectExtent.h" 28 30 #include <wtf/RefCounted.h> 29 31 #include <wtf/text/AtomString.h> … … 81 83 AtomString filterName() const { return filterName(m_filterType); } 82 84 85 virtual IntOutsets outsets() const { return { }; } 86 virtual void clearResult() { } 87 83 88 private: 84 89 Type m_filterType; -
trunk/Source/WebCore/rendering/CSSFilter.cpp
r285597 r285618 28 28 #include "CSSFilter.h" 29 29 30 #include "CachedSVGDocument.h"31 #include "CachedSVGDocumentReference.h"32 #include "ElementIterator.h"33 30 #include "FEColorMatrix.h" 34 31 #include "FEComponentTransfer.h" … … 39 36 #include "Logging.h" 40 37 #include "ReferencedSVGResources.h" 41 #include "RenderLayer.h" 42 #include "SVGElement.h" 38 #include "SVGFilter.h" 43 39 #include "SVGFilterBuilder.h" 44 40 #include "SVGFilterElement.h" 45 #include "SVGFilterPrimitiveStandardAttributes.h"46 #include "SourceAlpha.h"47 41 #include "SourceGraphic.h" 48 #include <algorithm>49 #include <wtf/MathExtras.h>50 42 51 43 #if USE(DIRECT2D) … … 55 47 namespace WebCore { 56 48 57 Ref<CSSFilter> CSSFilter::create(float scaleFactor) 58 { 59 return adoptRef(*new CSSFilter(scaleFactor)); 60 } 61 62 CSSFilter::CSSFilter(float scaleFactor) 49 RefPtr<CSSFilter> CSSFilter::create(const FilterOperations& operations, RenderingMode renderingMode, float scaleFactor) 50 { 51 bool hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels(); 52 bool hasFilterThatShouldBeRestrictedBySecurityOrigin = operations.hasFilterThatShouldBeRestrictedBySecurityOrigin(); 53 54 auto filter = adoptRef(*new CSSFilter(hasFilterThatMovesPixels, hasFilterThatShouldBeRestrictedBySecurityOrigin, scaleFactor)); 55 56 filter->setRenderingMode(renderingMode); 57 return filter; 58 } 59 60 CSSFilter::CSSFilter(bool hasFilterThatMovesPixels, bool hasFilterThatShouldBeRestrictedBySecurityOrigin, float scaleFactor) 63 61 : Filter(Filter::Type::CSSFilter, FloatSize { scaleFactor, scaleFactor }) 64 , m_sourceGraphic(SourceGraphic::create(*this)) 65 { 66 } 67 68 GraphicsContext* CSSFilter::inputContext() 69 { 70 return sourceImage() ? &sourceImage()->context() : nullptr; 71 } 72 73 RefPtr<FilterEffect> CSSFilter::buildReferenceFilter(RenderElement& renderer, FilterEffect& previousEffect, ReferenceFilterOperation& filterOperation) 74 { 75 auto* filterElement = renderer.ensureReferencedSVGResources().referencedFilterElement(renderer.document(), filterOperation); 62 , m_hasFilterThatMovesPixels(hasFilterThatMovesPixels) 63 , m_hasFilterThatShouldBeRestrictedBySecurityOrigin(hasFilterThatShouldBeRestrictedBySecurityOrigin) 64 { 65 } 66 67 static RefPtr<FilterEffect> createBlurEffect(CSSFilter& filter, const BlurFilterOperation& blurOperation, FilterConsumer consumer) 68 { 69 float stdDeviation = floatValueForLength(blurOperation.stdDeviation(), 0); 70 return FEGaussianBlur::create(filter, stdDeviation, stdDeviation, consumer == FilterConsumer::FilterProperty ? EDGEMODE_NONE : EDGEMODE_DUPLICATE); 71 } 72 73 static RefPtr<FilterEffect> createBrightnessEffect(CSSFilter& filter, const BasicComponentTransferFilterOperation& componentTransferOperation) 74 { 75 ComponentTransferFunction transferFunction; 76 transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR; 77 transferFunction.slope = narrowPrecisionToFloat(componentTransferOperation.amount()); 78 transferFunction.intercept = 0; 79 80 ComponentTransferFunction nullFunction; 81 return FEComponentTransfer::create(filter, transferFunction, transferFunction, transferFunction, nullFunction); 82 } 83 84 static RefPtr<FilterEffect> createContrastEffect(CSSFilter& filter, const BasicComponentTransferFilterOperation& componentTransferOperation) 85 { 86 ComponentTransferFunction transferFunction; 87 transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR; 88 float amount = narrowPrecisionToFloat(componentTransferOperation.amount()); 89 transferFunction.slope = amount; 90 transferFunction.intercept = -0.5 * amount + 0.5; 91 92 ComponentTransferFunction nullFunction; 93 return FEComponentTransfer::create(filter, transferFunction, transferFunction, transferFunction, nullFunction); 94 } 95 96 static RefPtr<FilterEffect> createDropShadowEffect(CSSFilter& filter, const DropShadowFilterOperation& dropShadowOperation) 97 { 98 float std = dropShadowOperation.stdDeviation(); 99 return FEDropShadow::create(filter, std, std, dropShadowOperation.x(), dropShadowOperation.y(), dropShadowOperation.color(), 1); 100 } 101 102 static RefPtr<FilterEffect> createGrayScaleEffect(CSSFilter& filter, const BasicColorMatrixFilterOperation& colorMatrixOperation) 103 { 104 double oneMinusAmount = clampTo(1 - colorMatrixOperation.amount(), 0.0, 1.0); 105 106 // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#grayscaleEquivalent 107 // for information on parameters. 108 109 Vector<float> inputParameters { 110 narrowPrecisionToFloat(0.2126 + 0.7874 * oneMinusAmount), 111 narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount), 112 narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount), 113 0, 114 0, 115 116 narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount), 117 narrowPrecisionToFloat(0.7152 + 0.2848 * oneMinusAmount), 118 narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount), 119 0, 120 0, 121 122 narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount), 123 narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount), 124 narrowPrecisionToFloat(0.0722 + 0.9278 * oneMinusAmount), 125 0, 126 0, 127 128 0, 129 0, 130 0, 131 1, 132 0, 133 }; 134 135 return FEColorMatrix::create(filter, FECOLORMATRIX_TYPE_MATRIX, WTFMove(inputParameters)); 136 } 137 138 static RefPtr<FilterEffect> createHueRotateEffect(CSSFilter& filter, const BasicColorMatrixFilterOperation& colorMatrixOperation) 139 { 140 Vector<float> inputParameters { narrowPrecisionToFloat(colorMatrixOperation.amount()) }; 141 return FEColorMatrix::create(filter, FECOLORMATRIX_TYPE_HUEROTATE, WTFMove(inputParameters)); 142 } 143 144 static RefPtr<FilterEffect> createInvertEffect(CSSFilter& filter, const BasicComponentTransferFilterOperation& componentTransferOperation) 145 { 146 ComponentTransferFunction transferFunction; 147 transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR; 148 float amount = narrowPrecisionToFloat(componentTransferOperation.amount()); 149 transferFunction.slope = 1 - 2 * amount; 150 transferFunction.intercept = amount; 151 152 ComponentTransferFunction nullFunction; 153 return FEComponentTransfer::create(filter, transferFunction, transferFunction, transferFunction, nullFunction); 154 } 155 156 static RefPtr<FilterEffect> createOpacityEffect(CSSFilter& filter, const BasicComponentTransferFilterOperation& componentTransferOperation) 157 { 158 ComponentTransferFunction transferFunction; 159 transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR; 160 float amount = narrowPrecisionToFloat(componentTransferOperation.amount()); 161 transferFunction.slope = amount; 162 transferFunction.intercept = 0; 163 164 ComponentTransferFunction nullFunction; 165 return FEComponentTransfer::create(filter, nullFunction, nullFunction, nullFunction, transferFunction); 166 } 167 168 static RefPtr<FilterEffect> createSaturateEffect(CSSFilter& filter, const BasicColorMatrixFilterOperation& colorMatrixOperation) 169 { 170 Vector<float> inputParameters { narrowPrecisionToFloat(colorMatrixOperation.amount()) }; 171 return FEColorMatrix::create(filter, FECOLORMATRIX_TYPE_SATURATE, WTFMove(inputParameters)); 172 } 173 174 static RefPtr<FilterEffect> createSepiaEffect(CSSFilter& filter, const BasicColorMatrixFilterOperation& colorMatrixOperation) 175 { 176 double oneMinusAmount = clampTo(1 - colorMatrixOperation.amount(), 0.0, 1.0); 177 178 // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#sepiaEquivalent 179 // for information on parameters. 180 181 Vector<float> inputParameters { 182 narrowPrecisionToFloat(0.393 + 0.607 * oneMinusAmount), 183 narrowPrecisionToFloat(0.769 - 0.769 * oneMinusAmount), 184 narrowPrecisionToFloat(0.189 - 0.189 * oneMinusAmount), 185 0, 186 0, 187 188 narrowPrecisionToFloat(0.349 - 0.349 * oneMinusAmount), 189 narrowPrecisionToFloat(0.686 + 0.314 * oneMinusAmount), 190 narrowPrecisionToFloat(0.168 - 0.168 * oneMinusAmount), 191 0, 192 0, 193 194 narrowPrecisionToFloat(0.272 - 0.272 * oneMinusAmount), 195 narrowPrecisionToFloat(0.534 - 0.534 * oneMinusAmount), 196 narrowPrecisionToFloat(0.131 + 0.869 * oneMinusAmount), 197 0, 198 0, 199 200 0, 201 0, 202 0, 203 1, 204 0, 205 }; 206 207 return FEColorMatrix::create(filter, FECOLORMATRIX_TYPE_MATRIX, WTFMove(inputParameters)); 208 } 209 210 static RefPtr<SVGFilter> createSVGFilter(CSSFilter& filter, const ReferenceFilterOperation& filterOperation, RenderElement& renderer, FilterEffect& previousEffect) 211 { 212 auto& referencedSVGResources = renderer.ensureReferencedSVGResources(); 213 auto* filterElement = referencedSVGResources.referencedFilterElement(renderer.document(), filterOperation); 214 76 215 if (!filterElement) { 77 LOG_WITH_STREAM(Filters, stream << " CSSFilter " << this << "buildReferenceFilter: failed to find filter renderer, adding pending resource " << filterOperation.fragment());216 LOG_WITH_STREAM(Filters, stream << " buildReferenceFilter: failed to find filter renderer, adding pending resource " << filterOperation.fragment()); 78 217 // Although we did not find the referenced filter, it might exist later in the document. 79 218 // FIXME: This skips anonymous RenderObjects. <https://webkit.org/b/131085> 80 219 // FIXME: Unclear if this does anything. 81 if (auto* element = renderer.element())82 renderer.document().accessSVGExtensions().addPendingResource(filterOperation.fragment(), *element);83 220 return nullptr; 84 221 } 85 222 86 auto builder = makeUnique<SVGFilterBuilder>(&previousEffect); 87 88 RefPtr<FilterEffect> effect; 89 Vector<Ref<FilterEffect>> referenceEffects; 90 91 for (auto& effectElement : childrenOfType<SVGFilterPrimitiveStandardAttributes>(*filterElement)) { 92 effect = effectElement.build(builder.get(), *this); 93 if (!effect) { 94 LOG_WITH_STREAM(Filters, stream << "CSSFilter " << this << " buildReferenceFilter: failed to build effect from " << effectElement); 95 return nullptr; 96 } 97 98 effectElement.setStandardAttributes(effect.get()); 99 if (effectElement.renderer()) { 100 #if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB) 101 effect->setOperatingColorSpace(effectElement.renderer()->style().svgStyle().colorInterpolationFilters() == ColorInterpolation::LinearRGB ? DestinationColorSpace::LinearSRGB() : DestinationColorSpace::SRGB()); 102 #else 103 effect->setOperatingColorSpace(DestinationColorSpace::SRGB()); 104 #endif 105 } 106 builder->add(effectElement.result(), effect); 107 referenceEffects.append(*effect); 108 } 223 SVGFilterBuilder builder; 224 return SVGFilter::create(*filterElement, builder, filter.filterScale(), filter.sourceImageRect(), filter.filterRegion(), previousEffect); 225 } 226 227 static void setupLastEffectProperties(FilterEffect& effect, FilterConsumer consumer) 228 { 229 // Unlike SVG Filters and CSSFilterImages, filter functions on the filter 230 // property applied here should not clip to their primitive subregions. 231 effect.setClipsToBounds(consumer == FilterConsumer::FilterFunction); 232 effect.setOperatingColorSpace(DestinationColorSpace::SRGB()); 233 } 234 235 bool CSSFilter::buildFilterFunctions(RenderElement& renderer, const FilterOperations& operations, FilterConsumer consumer) 236 { 237 m_functions.clear(); 238 m_outsets = { }; 239 240 RefPtr<FilterEffect> previousEffect = SourceGraphic::create(*this); 241 m_functions.append({ *previousEffect }); 242 243 RefPtr<SVGFilter> filter; 109 244 110 m_effects.appendVector(WTFMove(referenceEffects));111 return effect;112 }113 114 bool CSSFilter::build(RenderElement& renderer, const FilterOperations& operations, FilterConsumer consumer)115 {116 m_hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels();117 m_hasFilterThatShouldBeRestrictedBySecurityOrigin = operations.hasFilterThatShouldBeRestrictedBySecurityOrigin();118 119 m_effects.clear();120 m_outsets = { };121 122 RefPtr<FilterEffect> previousEffect = m_sourceGraphic.ptr();123 245 for (auto& operation : operations.operations()) { 124 246 RefPtr<FilterEffect> effect; 125 auto& filterOperation = *operation; 126 switch (filterOperation.type()) { 127 case FilterOperation::REFERENCE: { 128 auto& referenceOperation = downcast<ReferenceFilterOperation>(filterOperation); 129 effect = buildReferenceFilter(renderer, *previousEffect, referenceOperation); 130 break; 131 } 132 case FilterOperation::GRAYSCALE: { 133 auto& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation); 134 double oneMinusAmount = clampTo(1 - colorMatrixOperation.amount(), 0.0, 1.0); 135 136 // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#grayscaleEquivalent 137 // for information on parameters. 138 139 Vector<float> inputParameters { 140 narrowPrecisionToFloat(0.2126 + 0.7874 * oneMinusAmount), 141 narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount), 142 narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount), 143 0, 144 0, 145 146 narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount), 147 narrowPrecisionToFloat(0.7152 + 0.2848 * oneMinusAmount), 148 narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount), 149 0, 150 0, 151 152 narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount), 153 narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount), 154 narrowPrecisionToFloat(0.0722 + 0.9278 * oneMinusAmount), 155 0, 156 0, 157 158 0, 159 0, 160 0, 161 1, 162 0, 163 }; 164 165 effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_MATRIX, WTFMove(inputParameters)); 166 break; 167 } 168 case FilterOperation::SEPIA: { 169 auto& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation); 170 double oneMinusAmount = clampTo(1 - colorMatrixOperation.amount(), 0.0, 1.0); 171 172 // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#sepiaEquivalent 173 // for information on parameters. 174 175 Vector<float> inputParameters { 176 narrowPrecisionToFloat(0.393 + 0.607 * oneMinusAmount), 177 narrowPrecisionToFloat(0.769 - 0.769 * oneMinusAmount), 178 narrowPrecisionToFloat(0.189 - 0.189 * oneMinusAmount), 179 0, 180 0, 181 182 narrowPrecisionToFloat(0.349 - 0.349 * oneMinusAmount), 183 narrowPrecisionToFloat(0.686 + 0.314 * oneMinusAmount), 184 narrowPrecisionToFloat(0.168 - 0.168 * oneMinusAmount), 185 0, 186 0, 187 188 narrowPrecisionToFloat(0.272 - 0.272 * oneMinusAmount), 189 narrowPrecisionToFloat(0.534 - 0.534 * oneMinusAmount), 190 narrowPrecisionToFloat(0.131 + 0.869 * oneMinusAmount), 191 0, 192 0, 193 194 0, 195 0, 196 0, 197 1, 198 0, 199 }; 200 201 effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_MATRIX, WTFMove(inputParameters)); 202 break; 203 } 204 case FilterOperation::SATURATE: { 205 auto& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation); 206 Vector<float> inputParameters { narrowPrecisionToFloat(colorMatrixOperation.amount()) }; 207 effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_SATURATE, WTFMove(inputParameters)); 208 break; 209 } 210 case FilterOperation::HUE_ROTATE: { 211 auto& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation); 212 Vector<float> inputParameters { narrowPrecisionToFloat(colorMatrixOperation.amount()) }; 213 effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_HUEROTATE, WTFMove(inputParameters)); 214 break; 215 } 216 case FilterOperation::INVERT: { 217 auto& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation); 218 ComponentTransferFunction transferFunction; 219 transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR; 220 float amount = narrowPrecisionToFloat(componentTransferOperation.amount()); 221 transferFunction.slope = 1 - 2 * amount; 222 transferFunction.intercept = amount; 223 224 ComponentTransferFunction nullFunction; 225 effect = FEComponentTransfer::create(*this, transferFunction, transferFunction, transferFunction, nullFunction); 226 break; 227 } 247 248 switch (operation->type()) { 228 249 case FilterOperation::APPLE_INVERT_LIGHTNESS: 229 250 ASSERT_NOT_REACHED(); // APPLE_INVERT_LIGHTNESS is only used in -apple-color-filter. 230 251 break; 231 case FilterOperation::OPACITY: { 232 auto& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation); 233 ComponentTransferFunction transferFunction; 234 transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR; 235 float amount = narrowPrecisionToFloat(componentTransferOperation.amount()); 236 transferFunction.slope = amount; 237 transferFunction.intercept = 0; 238 239 ComponentTransferFunction nullFunction; 240 effect = FEComponentTransfer::create(*this, nullFunction, nullFunction, nullFunction, transferFunction); 252 253 case FilterOperation::BLUR: 254 effect = createBlurEffect(*this, downcast<BlurFilterOperation>(*operation), consumer); 255 break; 256 257 case FilterOperation::BRIGHTNESS: 258 effect = createBrightnessEffect(*this, downcast<BasicComponentTransferFilterOperation>(*operation)); 259 break; 260 261 case FilterOperation::CONTRAST: 262 effect = createContrastEffect(*this, downcast<BasicComponentTransferFilterOperation>(*operation)); 263 break; 264 265 case FilterOperation::DROP_SHADOW: 266 effect = createDropShadowEffect(*this, downcast<DropShadowFilterOperation>(*operation)); 267 break; 268 269 case FilterOperation::GRAYSCALE: 270 effect = createGrayScaleEffect(*this, downcast<BasicColorMatrixFilterOperation>(*operation)); 271 break; 272 273 case FilterOperation::HUE_ROTATE: 274 effect = createHueRotateEffect(*this, downcast<BasicColorMatrixFilterOperation>(*operation)); 275 break; 276 277 case FilterOperation::INVERT: 278 effect = createInvertEffect(*this, downcast<BasicComponentTransferFilterOperation>(*operation)); 279 break; 280 281 case FilterOperation::OPACITY: 282 effect = createOpacityEffect(*this, downcast<BasicComponentTransferFilterOperation>(*operation)); 283 break; 284 285 case FilterOperation::SATURATE: 286 effect = createSaturateEffect(*this, downcast<BasicColorMatrixFilterOperation>(*operation)); 287 break; 288 289 case FilterOperation::SEPIA: 290 effect = createSepiaEffect(*this, downcast<BasicColorMatrixFilterOperation>(*operation)); 291 break; 292 293 case FilterOperation::REFERENCE: 294 filter = createSVGFilter(*this, downcast<ReferenceFilterOperation>(*operation), renderer, *previousEffect); 295 effect = nullptr; 296 break; 297 298 default: 241 299 break; 242 300 } 243 case FilterOperation::BRIGHTNESS: { 244 auto& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation); 245 ComponentTransferFunction transferFunction; 246 transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR; 247 transferFunction.slope = narrowPrecisionToFloat(componentTransferOperation.amount()); 248 transferFunction.intercept = 0; 249 250 ComponentTransferFunction nullFunction; 251 effect = FEComponentTransfer::create(*this, transferFunction, transferFunction, transferFunction, nullFunction); 252 break; 301 302 if (filter) { 303 effect = filter->lastEffect(); 304 setupLastEffectProperties(*effect, consumer); 305 m_functions.append(filter.releaseNonNull()); 306 previousEffect = WTFMove(effect); 307 continue; 253 308 } 254 case FilterOperation::CONTRAST: {255 auto& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);256 ComponentTransferFunction transferFunction;257 transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;258 float amount = narrowPrecisionToFloat(componentTransferOperation.amount());259 transferFunction.slope = amount;260 transferFunction.intercept = -0.5 * amount + 0.5;261 262 ComponentTransferFunction nullFunction;263 effect = FEComponentTransfer::create(*this, transferFunction, transferFunction, transferFunction, nullFunction);264 break;265 }266 case FilterOperation::BLUR: {267 auto& blurOperation = downcast<BlurFilterOperation>(filterOperation);268 float stdDeviation = floatValueForLength(blurOperation.stdDeviation(), 0);269 effect = FEGaussianBlur::create(*this, stdDeviation, stdDeviation, consumer == FilterConsumer::FilterProperty ? EDGEMODE_NONE : EDGEMODE_DUPLICATE);270 break;271 }272 case FilterOperation::DROP_SHADOW: {273 auto& dropShadowOperation = downcast<DropShadowFilterOperation>(filterOperation);274 effect = FEDropShadow::create(*this, dropShadowOperation.stdDeviation(), dropShadowOperation.stdDeviation(),275 dropShadowOperation.x(), dropShadowOperation.y(), dropShadowOperation.color(), 1);276 break;277 }278 default:279 break;280 }281 309 282 310 if (effect) { 283 // Unlike SVG Filters and CSSFilterImages, filter functions on the filter 284 // property applied here should not clip to their primitive subregions. 285 effect->setClipsToBounds(consumer == FilterConsumer::FilterFunction); 286 effect->setOperatingColorSpace(DestinationColorSpace::SRGB()); 287 288 if (filterOperation.type() != FilterOperation::REFERENCE) { 289 effect->inputEffects() = { WTFMove(previousEffect) }; 290 m_effects.append(*effect); 291 } 311 setupLastEffectProperties(*effect, consumer); 312 effect->inputEffects() = { WTFMove(previousEffect) }; 313 m_functions.append({ *effect }); 292 314 previousEffect = WTFMove(effect); 293 315 } … … 295 317 296 318 // If we didn't make any effects, tell our caller we are not valid. 297 if (m_ effects.isEmpty())319 if (m_functions.isEmpty()) 298 320 return false; 299 321 300 m_effects.shrinkToFit(); 301 302 setMaxEffectRects(sourceImageRect()); 322 m_functions.shrinkToFit(); 323 303 324 #if USE(CORE_IMAGE) 304 325 if (!m_filterRenderer) 305 m_filterRenderer = FilterEffectRenderer::tryCreate(renderer.settings().coreImageAcceleratedFilterRenderEnabled(), m_effects.last().get());326 m_filterRenderer = FilterEffectRenderer::tryCreate(renderer.settings().coreImageAcceleratedFilterRenderEnabled(), *lastEffect()); 306 327 #endif 307 328 return true; 329 } 330 331 GraphicsContext* CSSFilter::inputContext() 332 { 333 return sourceImage() ? &sourceImage()->context() : nullptr; 308 334 } 309 335 … … 338 364 setSourceImage(ImageBuffer::create(logicalSize, mode, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8)); 339 365 #endif 340 } 366 if (auto context = inputContext()) 367 context->scale(filterScale()); 368 } 369 341 370 m_graphicsBufferAttached = true; 342 371 } 343 372 373 RefPtr<FilterEffect> CSSFilter::lastEffect() 374 { 375 if (m_functions.isEmpty()) 376 return nullptr; 377 378 auto& function = m_functions.last(); 379 if (function->isSVGFilter()) 380 return downcast<SVGFilter>(function.ptr())->lastEffect(); 381 382 return downcast<FilterEffect>(function.ptr()); 383 } 384 344 385 void CSSFilter::determineFilterPrimitiveSubregion() 345 386 { 346 auto & lastEffect = m_effects.last().get();347 lastEffect.determineFilterPrimitiveSubregion();348 FloatRect subRegion = lastEffect.maxEffectRect();387 auto effect = lastEffect(); 388 effect->determineFilterPrimitiveSubregion(); 389 FloatRect subRegion = effect->maxEffectRect(); 349 390 // At least one FilterEffect has a too big image size, recalculate the effect sizes with new scale factors. 350 391 FloatSize filterScale { 1, 1 }; 351 392 if (ImageBuffer::sizeNeedsClamping(subRegion.size(), filterScale)) { 352 393 setFilterScale(filterScale); 353 lastEffect.determineFilterPrimitiveSubregion();394 effect->determineFilterPrimitiveSubregion(); 354 395 } 355 396 } … … 357 398 void CSSFilter::clearIntermediateResults() 358 399 { 359 m_sourceGraphic->clearResult(); 360 for (auto& effect : m_effects) 361 effect->clearResult(); 400 for (auto& function : m_functions) 401 function->clearResult(); 362 402 } 363 403 364 404 void CSSFilter::apply() 365 405 { 366 auto & effect = m_effects.last().get();406 auto effect = lastEffect(); 367 407 if (m_filterRenderer) { 368 m_filterRenderer->applyEffects( effect);408 m_filterRenderer->applyEffects(*effect); 369 409 if (m_filterRenderer->hasResult()) { 370 effect .transformResultColorSpace(DestinationColorSpace::SRGB());410 effect->transformResultColorSpace(DestinationColorSpace::SRGB()); 371 411 return; 372 412 } 373 413 } 374 effect .apply();375 effect .transformResultColorSpace(DestinationColorSpace::SRGB());414 effect->apply(); 415 effect->transformResultColorSpace(DestinationColorSpace::SRGB()); 376 416 } 377 417 … … 386 426 } 387 427 388 ImageBuffer* CSSFilter::output() const428 ImageBuffer* CSSFilter::output() 389 429 { 390 430 if (m_filterRenderer && m_filterRenderer->hasResult()) 391 431 return m_filterRenderer->output(); 392 432 393 return m_effects.last()->imageBufferResult();433 return lastEffect()->imageBufferResult(); 394 434 } 395 435 396 436 void CSSFilter::setSourceImageRect(const FloatRect& sourceImageRect) 397 437 { 438 auto scaledSourceImageRect = sourceImageRect; 439 scaledSourceImageRect.scale(filterScale()); 440 398 441 Filter::setFilterRegion(sourceImageRect); 399 Filter::setSourceImageRect(sourceImageRect); 400 setMaxEffectRects(sourceImageRect); 442 Filter::setSourceImageRect(scaledSourceImageRect); 443 444 for (auto& function : m_functions) { 445 if (function->isSVGFilter()) { 446 downcast<SVGFilter>(function.ptr())->setFilterRegion(sourceImageRect); 447 downcast<SVGFilter>(function.ptr())->setSourceImageRect(scaledSourceImageRect); 448 } 449 } 450 401 451 m_graphicsBufferAttached = false; 402 452 } 403 453 404 void CSSFilter::setMaxEffectRects(const FloatRect& effectRect) 405 { 406 for (auto& effect : m_effects) 407 effect->setMaxEffectRect(effectRect); 408 } 409 410 IntRect CSSFilter::outputRect() const 411 { 412 auto& lastEffect = m_effects.last().get(); 413 414 if (lastEffect.hasResult() || (m_filterRenderer && m_filterRenderer->hasResult())) 415 return lastEffect.requestedRegionOfInputPixelBuffer(IntRect { filterRegion() }); 416 454 IntRect CSSFilter::outputRect() 455 { 456 auto effect = lastEffect(); 457 458 if (effect->hasResult() || (m_filterRenderer && m_filterRenderer->hasResult())) 459 return effect->requestedRegionOfInputPixelBuffer(IntRect { filterRegion() }); 460 417 461 return { }; 418 462 } … … 426 470 return m_outsets; 427 471 428 for (auto& effect : m_effects)429 m_outsets += effect->outsets();472 for (auto& function : m_functions) 473 m_outsets += function->outsets(); 430 474 return m_outsets; 431 475 } -
trunk/Source/WebCore/rendering/CSSFilter.h
r285597 r285618 45 45 class CSSFilter final : public Filter { 46 46 WTF_MAKE_FAST_ALLOCATED; 47 friend class RenderLayerFilters;48 47 public: 49 static Ref<CSSFilter> create(float scaleFactor = 1); 50 51 ImageBuffer* output() const; 48 static RefPtr<CSSFilter> create(const FilterOperations&, RenderingMode, float scaleFactor = 1); 52 49 53 50 void setSourceImageRect(const FloatRect&); 54 bool build(RenderElement&, const FilterOperations&, FilterConsumer); 55 void clearIntermediateResults(); 56 void apply(); 51 bool buildFilterFunctions(RenderElement&, const FilterOperations&, FilterConsumer); 52 void determineFilterPrimitiveSubregion(); 57 53 58 54 bool hasFilterThatMovesPixels() const { return m_hasFilterThatMovesPixels; } 59 55 bool hasFilterThatShouldBeRestrictedBySecurityOrigin() const { return m_hasFilterThatShouldBeRestrictedBySecurityOrigin; } 60 56 61 void determineFilterPrimitiveSubregion(); 62 IntOutsets outsets() const; 57 RefPtr<FilterEffect> lastEffect(); 58 GraphicsContext* inputContext(); 59 IntOutsets outsets() const override; 63 60 64 private: 65 CSSFilter(float scaleFactor);61 void clearIntermediateResults(); 62 void apply(); 66 63 67 RefPtr<FilterEffect> buildReferenceFilter(RenderElement&, FilterEffect& previousEffect, ReferenceFilterOperation&); 68 69 void setMaxEffectRects(const FloatRect&); 70 71 GraphicsContext* inputContext(); 64 ImageBuffer* output(); 72 65 73 66 bool updateBackingStoreRect(const FloatRect& filterRect); 74 67 void allocateBackingStoreIfNeeded(const GraphicsContext&); 75 68 76 IntRect outputRect() const;69 IntRect outputRect(); 77 70 78 71 LayoutRect computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect); 79 72 80 Vector<Ref<FilterEffect>> m_effects; 81 Ref<SourceGraphic> m_sourceGraphic; 82 83 mutable IntOutsets m_outsets; 73 private: 74 CSSFilter(bool hasFilterThatMovesPixels, bool hasFilterThatShouldBeRestrictedBySecurityOrigin, float scaleFactor); 84 75 85 76 bool m_graphicsBufferAttached { false }; 86 77 bool m_hasFilterThatMovesPixels { false }; 87 78 bool m_hasFilterThatShouldBeRestrictedBySecurityOrigin { false }; 88 79 80 Vector<Ref<FilterFunction>> m_functions; 81 82 mutable IntOutsets m_outsets; 83 89 84 std::unique_ptr<FilterEffectRenderer> m_filterRenderer; 90 85 }; -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r285583 r285618 3243 3243 auto rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, offsetFromRoot, { }); 3244 3244 3245 GraphicsContext* filterContext = paintingFilters->beginFilterEffect(destinationContext, enclosingIntRect(rootRelativeBounds), enclosingIntRect(paintingInfo.paintDirtyRect), enclosingIntRect(filterRepaintRect));3245 GraphicsContext* filterContext = paintingFilters->beginFilterEffect(destinationContext, renderer(), enclosingIntRect(rootRelativeBounds), enclosingIntRect(paintingInfo.paintDirtyRect), enclosingIntRect(filterRepaintRect)); 3246 3246 if (!filterContext) 3247 3247 return nullptr; -
trunk/Source/WebCore/rendering/RenderLayerFilters.cpp
r285597 r285618 119 119 void RenderLayerFilters::buildFilter(RenderElement& renderer, float scaleFactor, RenderingMode renderingMode) 120 120 { 121 // FIXME: this rebuilds the entire effects chain even if the filter style didn't change.122 m_filter = CSSFilter::create(scaleFactor);123 m_filter->setRenderingMode(renderingMode);124 125 121 // If the filter fails to build, remove it from the layer. It will still attempt to 126 122 // go through regular processing (e.g. compositing), but never apply anything. 127 if (!m_filter->build(renderer, renderer.style().filter(), FilterConsumer::FilterProperty))128 m_filter = nullptr;129 } 130 131 GraphicsContext* RenderLayerFilters::beginFilterEffect(GraphicsContext& destinationContext, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect)123 // FIXME: this rebuilds the entire effects chain even if the filter style didn't change. 124 m_filter = CSSFilter::create(renderer.style().filter(), renderingMode, scaleFactor); 125 } 126 127 GraphicsContext* RenderLayerFilters::beginFilterEffect(GraphicsContext& destinationContext, RenderElement& renderer, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect) 132 128 { 133 129 if (!m_filter) … … 140 136 141 137 bool hasUpdatedBackingStore = filter.updateBackingStoreRect(filterSourceRect); 138 139 // FIXME: this call should be moved to CSSFilter::create() when FilterEffect does not store its geometry. 140 if (hasUpdatedBackingStore || !m_filter->lastEffect()) { 141 // If the filter fails to build, remove it from the layer. It will still attempt to 142 // go through regular processing (e.g. compositing), but never apply anything. 143 if (!m_filter->buildFilterFunctions(renderer, renderer.style().filter(), FilterConsumer::FilterProperty)) 144 return nullptr; 145 } 146 142 147 if (!filter.hasFilterThatMovesPixels()) 143 148 m_repaintRect = dirtyRect; … … 185 190 destRect.move(m_paintOffset.x(), m_paintOffset.y()); 186 191 187 if (auto* outputBuffer = filter.output()) 192 if (auto* outputBuffer = filter.output()) { 193 destinationContext.scale({ 1 / filter.filterScale().width(), 1 / filter.filterScale().height() }); 188 194 destinationContext.drawImageBuffer(*outputBuffer, snapRectToDevicePixels(destRect, m_layer.renderer().document().deviceScaleFactor())); 195 destinationContext.scale(filter.filterScale()); 196 } 189 197 190 198 filter.clearIntermediateResults(); -
trunk/Source/WebCore/rendering/RenderLayerFilters.h
r261597 r285618 64 64 LayoutRect repaintRect() const { return m_repaintRect; } 65 65 66 GraphicsContext* beginFilterEffect(GraphicsContext& destinationContext, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect);66 GraphicsContext* beginFilterEffect(GraphicsContext& destinationContext, RenderElement&, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect); 67 67 void applyFilterEffect(GraphicsContext& destinationContext); 68 68 -
trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
r285597 r285618 83 83 } 84 84 85 std::unique_ptr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFilter& filter) const86 {87 static const unsigned maxCountChildNodes = 200;88 if (filterElement().countChildNodes() > maxCountChildNodes)89 return nullptr;90 91 FloatRect targetBoundingBox = filter.targetBoundingBox();92 93 // Add effects to the builder94 auto builder = makeUnique<SVGFilterBuilder>(SourceGraphic::create(filter));95 builder->setPrimitiveUnits(filterElement().primitiveUnits());96 builder->setTargetBoundingBox(targetBoundingBox);97 98 for (auto& element : childrenOfType<SVGFilterPrimitiveStandardAttributes>(filterElement())) {99 auto effect = element.build(builder.get(), filter);100 if (!effect) {101 builder->clearEffects();102 return nullptr;103 }104 builder->appendEffectToEffectReferences(effect.copyRef(), element.renderer());105 element.setStandardAttributes(effect.get());106 effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(&element, filterElement().primitiveUnits(), targetBoundingBox));107 if (element.renderer()) {108 #if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB)109 effect->setOperatingColorSpace(element.renderer()->style().svgStyle().colorInterpolationFilters() == ColorInterpolation::LinearRGB ? DestinationColorSpace::LinearSRGB() : DestinationColorSpace::SRGB());110 #else111 effect->setOperatingColorSpace(DestinationColorSpace::SRGB());112 #endif113 }114 builder->add(element.result(), WTFMove(effect));115 }116 return builder;117 }118 119 85 bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const RenderStyle&, GraphicsContext*& context, OptionSet<RenderSVGResourceMode> resourceMode) 120 86 { … … 156 122 157 123 // Create the SVGFilter object. 158 bool primitiveBoundingBoxMode = filterElement().primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; 159 filterData->filter = SVGFilter::create(filterScale, absoluteDrawingRegion, filterData->boundaries, targetBoundingBox, primitiveBoundingBoxMode); 160 161 // Create all relevant filter primitives. 162 filterData->builder = buildPrimitives(*filterData->filter); 163 if (!filterData->builder) 164 return false; 165 166 static const unsigned maxTotalOfEffectInputs = 100; 167 FilterEffect* lastEffect = filterData->builder->lastEffect(); 168 if (!lastEffect || lastEffect->totalNumberOfEffectInputs() > maxTotalOfEffectInputs) 169 return false; 124 filterData->builder = makeUnique<SVGFilterBuilder>(); 125 filterData->filter = SVGFilter::create(filterElement(), *filterData->builder, filterScale, absoluteDrawingRegion, filterData->boundaries, targetBoundingBox); 126 if (!filterData->filter) 127 return false; 128 129 auto lastEffect = filterData->builder->lastEffect(); 130 ASSERT(lastEffect); 170 131 171 132 LOG_WITH_STREAM(Filters, stream << "RenderSVGResourceFilter::applyResource\n" << *filterData->builder->lastEffect()); -
trunk/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
r285597 r285618 434 434 FloatRect dummyRect; 435 435 FloatSize dummyScale(1, 1); 436 auto dummyFilter = SVGFilter::create(dummyScale, dummyRect, dummyRect, dummyRect, true); 437 if (auto builder = filter.buildPrimitives(dummyFilter.get())) { 436 SVGFilterBuilder builder; 437 auto dummyFilter = SVGFilter::create(filter.filterElement(), builder, dummyScale, dummyRect, dummyRect, dummyRect); 438 if (dummyFilter) { 438 439 TextStream::IndentScope indentScope(ts); 439 440 440 if ( FilterEffect* lastEffect = builder->lastEffect())441 if (auto lastEffect = dummyFilter->lastEffect()) 441 442 lastEffect->externalRepresentation(ts); 442 443 } -
trunk/Source/WebCore/svg/graphics/filters/SVGFilter.cpp
r285597 r285618 23 23 #include "SVGFilter.h" 24 24 25 #include "SVGFilterBuilder.h" 26 #include "SVGFilterElement.h" 27 #include "SourceGraphic.h" 28 25 29 namespace WebCore { 30 31 RefPtr<SVGFilter> SVGFilter::create(SVGFilterElement& filterElement, SVGFilterBuilder& builder, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, FilterEffect& previousEffect) 32 { 33 return create(filterElement, builder, filterScale, sourceImageRect, filterRegion, filterRegion, &previousEffect); 34 } 35 36 RefPtr<SVGFilter> SVGFilter::create(SVGFilterElement& filterElement, SVGFilterBuilder& builder, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox) 37 { 38 return create(filterElement, builder, filterScale, sourceImageRect, filterRegion, targetBoundingBox, nullptr); 39 } 40 41 RefPtr<SVGFilter> SVGFilter::create(SVGFilterElement& filterElement, SVGFilterBuilder& builder, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, FilterEffect* previousEffect) 42 { 43 bool primitiveBoundingBoxMode = filterElement.primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; 44 45 auto filter = adoptRef(*new SVGFilter(filterScale, sourceImageRect, filterRegion, targetBoundingBox, primitiveBoundingBoxMode)); 46 47 if (!previousEffect) 48 builder.setupBuiltinEffects(SourceGraphic::create(filter)); 49 else 50 builder.setupBuiltinEffects({ *previousEffect }); 51 52 builder.setTargetBoundingBox(targetBoundingBox); 53 builder.setPrimitiveUnits(filterElement.primitiveUnits()); 54 55 auto lastEffect = builder.buildFilterEffects(filter, filterElement); 56 if (!lastEffect) 57 return nullptr; 58 59 filter->setLastEffect(WTFMove(lastEffect)); 60 return filter; 61 } 26 62 27 63 SVGFilter::SVGFilter(const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, bool effectBBoxMode) … … 40 76 } 41 77 42 Ref<SVGFilter> SVGFilter::create(const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, bool effectBBoxMode) 78 IntOutsets SVGFilter::outsets() const 43 79 { 44 return adoptRef(*new SVGFilter(filterScale, sourceImageRect, filterRegion, targetBoundingBox, effectBBoxMode)); 80 return m_lastEffect->outsets(); 81 } 82 83 void SVGFilter::clearResult() 84 { 85 m_lastEffect->clearResultsRecursive(); 45 86 } 46 87 -
trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h
r285597 r285618 28 28 namespace WebCore { 29 29 30 class SVGFilterBuilder; 31 class SVGFilterElement; 32 30 33 class SVGFilter final : public Filter { 31 34 public: 32 static Ref<SVGFilter> create(const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode); 35 static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, FilterEffect& previousEffect); 36 static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox); 37 static RefPtr<SVGFilter> create(SVGFilterElement&, SVGFilterBuilder&, const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& filterRegion, const FloatRect& targetBoundingBox, FilterEffect* previousEffect); 33 38 34 39 FloatSize scaledByFilterScale(FloatSize) const final; … … 36 41 FloatRect targetBoundingBox() const { return m_targetBoundingBox; } 37 42 43 RefPtr<FilterEffect> lastEffect() { return m_lastEffect; } 44 void setLastEffect(RefPtr<FilterEffect>&& lastEffect) { m_lastEffect = WTFMove(lastEffect); } 45 38 46 private: 39 47 SVGFilter(const FloatSize& filterScale, const FloatRect& sourceImageRect, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode); 40 48 49 IntOutsets outsets() const override; 50 void clearResult() override; 51 41 52 FloatRect m_targetBoundingBox; 42 53 bool m_effectBBoxMode; 54 55 RefPtr<FilterEffect> m_lastEffect; 43 56 }; 44 57 -
trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp
r285543 r285618 21 21 #include "SVGFilterBuilder.h" 22 22 23 #include " FilterEffect.h"23 #include "ElementIterator.h" 24 24 #include "ImageBuffer.h" 25 #include "SVGFilterElement.h" 26 #include "SVGFilterPrimitiveStandardAttributes.h" 25 27 #include "SourceAlpha.h" 26 28 #include "SourceGraphic.h" 27 29 #include <wtf/text/StringConcatenateNumbers.h> 28 30 31 #if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB) 32 #include "CSSComputedStyleDeclaration.h" 33 #include "CSSPrimitiveValueMappings.h" 34 #endif 35 29 36 namespace WebCore { 30 37 31 SVGFilterBuilder::SVGFilterBuilder(RefPtr<FilterEffect> sourceGraphic)38 void SVGFilterBuilder::setupBuiltinEffects(Ref<FilterEffect> sourceGraphic) 32 39 { 33 m_builtinEffects.add(SourceGraphic::effectName(), sourceGraphic );34 m_builtinEffects.add(SourceAlpha::effectName(), SourceAlpha::create( *sourceGraphic));40 m_builtinEffects.add(SourceGraphic::effectName(), sourceGraphic.ptr()); 41 m_builtinEffects.add(SourceAlpha::effectName(), SourceAlpha::create(sourceGraphic)); 35 42 addBuiltinEffects(); 43 } 44 45 #if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB) 46 static ColorInterpolation colorInterpolationForElement(SVGElement& element) 47 { 48 if (auto renderer = element.renderer()) 49 return renderer->style().svgStyle().colorInterpolationFilters(); 50 51 // Try to determine the property value from the computed style. 52 if (auto value = ComputedStyleExtractor(&element).propertyValue(CSSPropertyColorInterpolationFilters)) { 53 if (is<CSSPrimitiveValue>(value)) 54 return downcast<CSSPrimitiveValue>(*value); 55 } 56 57 return ColorInterpolation::Auto; 58 } 59 #endif 60 61 static unsigned collectEffects(const FilterEffect* effect, HashSet<const FilterEffect*>& allEffects) 62 { 63 allEffects.add(effect); 64 unsigned size = effect->numberOfEffectInputs(); 65 for (unsigned i = 0; i < size; ++i) { 66 FilterEffect* in = effect->inputEffect(i); 67 collectEffects(in, allEffects); 68 } 69 return allEffects.size(); 70 } 71 72 static unsigned totalNumberFilterEffects(const FilterEffect& lastEffect) 73 { 74 HashSet<const FilterEffect*> allEffects; 75 return collectEffects(&lastEffect, allEffects); 76 } 77 78 RefPtr<FilterEffect> SVGFilterBuilder::buildFilterEffects(Filter& filter, SVGFilterElement& filterElement) 79 { 80 static constexpr unsigned maxCountChildNodes = 200; 81 static constexpr unsigned maxTotalNumberFilterEffects = 100; 82 83 if (filterElement.countChildNodes() > maxCountChildNodes) 84 return nullptr; 85 86 RefPtr<FilterEffect> effect; 87 88 for (auto& effectElement : childrenOfType<SVGFilterPrimitiveStandardAttributes>(filterElement)) { 89 effect = effectElement.build(this, filter); 90 if (!effect) { 91 clearEffects(); 92 return nullptr; 93 } 94 95 effectElement.setStandardAttributes(effect.get()); 96 effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(&effectElement, m_primitiveUnits, m_targetBoundingBox)); 97 98 #if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB) 99 if (colorInterpolationForElement(effectElement) == ColorInterpolation::LinearRGB) 100 effect->setOperatingColorSpace(DestinationColorSpace::LinearSRGB()); 101 #endif 102 if (auto renderer = effectElement.renderer()) 103 appendEffectToEffectReferences(effect.copyRef(), renderer); 104 105 add(effectElement.result(), effect); 106 } 107 108 if (!effect || totalNumberFilterEffects(*effect) > maxTotalNumberFilterEffects) 109 return nullptr; 110 111 return effect; 36 112 } 37 113 -
trunk/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h
r248762 r285618 38 38 typedef HashSet<FilterEffect*> FilterEffectSet; 39 39 40 SVGFilterBuilder( RefPtr<FilterEffect> sourceGraphic);40 SVGFilterBuilder() = default; 41 41 42 42 void setTargetBoundingBox(const FloatRect& r) { m_targetBoundingBox = r; } … … 66 66 void clearResultsRecursive(FilterEffect*); 67 67 68 void setupBuiltinEffects(Ref<FilterEffect> sourceGraphic); 69 RefPtr<FilterEffect> buildFilterEffects(Filter&, SVGFilterElement&); 70 68 71 private: 69 72 inline void addBuiltinEffects()
Note:
See TracChangeset
for help on using the changeset viewer.