Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(775)

Unified Diff: Source/core/rendering/FilterEffectRenderer.cpp

Issue 14793008: Extract the SVG Filter Reference implementation out of the FilterEffectRenderer into its own type (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix copyrights Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/rendering/FilterEffectRenderer.h ('k') | Source/core/rendering/RenderLayer.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/rendering/FilterEffectRenderer.cpp
diff --git a/Source/core/rendering/FilterEffectRenderer.cpp b/Source/core/rendering/FilterEffectRenderer.cpp
index dc57d05096d70b2078582fb64309e7ce90834aad..7ee85c3e1a803608c4a579096b2db2bd1d4bb468 100644
--- a/Source/core/rendering/FilterEffectRenderer.cpp
+++ b/Source/core/rendering/FilterEffectRenderer.cpp
@@ -28,8 +28,6 @@
#include "core/rendering/FilterEffectRenderer.h"
-#include "SVGNames.h"
-#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/dom/Document.h"
#include "core/loader/cache/CachedDocument.h"
#include "core/loader/cache/CachedSVGDocumentReference.h"
@@ -39,13 +37,14 @@
#include "core/platform/graphics/filters/FEComponentTransfer.h"
#include "core/platform/graphics/filters/FEDropShadow.h"
#include "core/platform/graphics/filters/FEGaussianBlur.h"
-#include "core/platform/graphics/filters/SourceAlpha.h"
#include "core/platform/graphics/filters/custom/CustomFilterGlobalContext.h"
#include "core/platform/graphics/filters/custom/CustomFilterValidatedProgram.h"
#include "core/platform/graphics/filters/custom/FECustomFilter.h"
#include "core/platform/graphics/filters/custom/ValidatedCustomFilterOperation.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/svg/ReferenceFilterBuilder.h"
+
#include "core/svg/SVGElement.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
#include "wtf/MathExtras.h"
@@ -90,46 +89,6 @@ static PassRefPtr<FECustomFilter> createCustomFilterEffect(Filter* filter, Docum
operation->meshRows(), operation->meshColumns(), operation->meshType());
}
-// Returns whether or not the SVGStyledElement object contains a valid color-interpolation-filters attribute
-static bool getSVGStyledElementColorSpace(SVGStyledElement* svgStyledElement, ColorSpace& cs)
-{
- if (!svgStyledElement)
- return false;
-
- const RenderObject* renderer = svgStyledElement->renderer();
- const RenderStyle* style = renderer ? renderer->style() : 0;
- const SVGRenderStyle* svgStyle = style ? style->svgStyle() : 0;
- EColorInterpolation eColorInterpolation = CI_AUTO;
- if (svgStyle) {
- // If a layout has been performed, then we can use the fast path to get this attribute
- eColorInterpolation = svgStyle->colorInterpolationFilters();
- } else {
- // Otherwise, use the slow path by using string comparison (used by external svg files)
- RefPtr<CSSValue> cssValue = svgStyledElement->getPresentationAttribute(
- SVGNames::color_interpolation_filtersAttr.toString());
- if (cssValue.get() && cssValue->isPrimitiveValue()) {
- const CSSPrimitiveValue& primitiveValue = *((CSSPrimitiveValue*)cssValue.get());
- eColorInterpolation = (EColorInterpolation)primitiveValue;
- } else {
- return false;
- }
- }
-
- switch (eColorInterpolation) {
- case CI_AUTO:
- case CI_SRGB:
- cs = ColorSpaceDeviceRGB;
- break;
- case CI_LINEARRGB:
- cs = ColorSpaceLinearRGB;
- break;
- default:
- return false;
- }
-
- return true;
-}
-
FilterEffectRenderer::FilterEffectRenderer()
: Filter(AffineTransform())
, m_graphicsBufferAttached(false)
@@ -149,95 +108,11 @@ GraphicsContext* FilterEffectRenderer::inputContext()
return sourceImage() ? sourceImage()->context() : 0;
}
-PassRefPtr<FilterEffect> FilterEffectRenderer::buildReferenceFilter(RenderObject* renderer, PassRefPtr<FilterEffect> previousEffect, ReferenceFilterOperation* filterOperation)
-{
- if (!renderer)
- return 0;
-
- Document* document = renderer->document();
- ASSERT(document);
-
- CachedSVGDocumentReference* cachedSVGDocumentReference = filterOperation->cachedSVGDocumentReference();
- CachedDocument* cachedSVGDocument = cachedSVGDocumentReference ? cachedSVGDocumentReference->document() : 0;
-
- // If we have an SVG document, this is an external reference. Otherwise
- // we look up the referenced node in the current document.
- if (cachedSVGDocument)
- document = cachedSVGDocument->document();
-
- if (!document)
- return 0;
-
- Element* filter = document->getElementById(filterOperation->fragment());
- if (!filter) {
- // Although we did not find the referenced filter, it might exist later
- // in the document
- document->accessSVGExtensions()->addPendingResource(filterOperation->fragment(), toElement(renderer->node()));
- return 0;
- }
-
- if (!filter->isSVGElement() || !filter->hasTagName(SVGNames::filterTag))
- return 0;
-
- SVGFilterElement* filterElement = toSVGFilterElement(toSVGElement(filter));
-
- RefPtr<FilterEffect> effect;
-
- // FIXME: Figure out what to do with SourceAlpha. Right now, we're
- // using the alpha of the original input layer, which is obviously
- // wrong. We should probably be extracting the alpha from the
- // previousEffect, but this requires some more processing.
- // This may need a spec clarification.
- RefPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(previousEffect, SourceAlpha::create(this));
-
- ColorSpace filterColorSpace = ColorSpaceDeviceRGB;
- const bool useFilterColorSpace = getSVGStyledElementColorSpace(filterElement, filterColorSpace);
-
- for (Node* node = filterElement->firstChild(); node; node = node->nextSibling()) {
- if (!node->isSVGElement())
- continue;
-
- SVGElement* element = toSVGElement(node);
- if (!element->isFilterEffect())
- continue;
-
- SVGFilterPrimitiveStandardAttributes* effectElement = static_cast<SVGFilterPrimitiveStandardAttributes*>(element);
-
- effect = effectElement->build(builder.get(), this);
- if (!effect)
- continue;
-
- effectElement->setStandardAttributes(effect.get());
- effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement->primitiveUnits(), sourceImageRect()));
-
- ColorSpace colorSpace = filterColorSpace;
- if (useFilterColorSpace || getSVGStyledElementColorSpace(effectElement, colorSpace))
- effect->setOperatingColorSpace(colorSpace);
- builder->add(effectElement->result(), effect);
- m_effects.append(effect);
- }
- return effect;
-}
-
bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations& operations)
{
m_hasCustomShaderFilter = false;
m_hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels();
- // Keep the old effects on the stack until we've created the new effects.
- // New FECustomFilters can reuse cached resources from old FECustomFilters.
- FilterEffectList oldEffects;
- m_effects.swap(oldEffects);
-
- // Inverse zoom the pre-zoomed CSS shorthand filters, so that they are in the zoom as the unzoomed reference filters
- const RenderStyle* style = renderer->style();
- float zoom = style ? style->effectiveZoom() : 1.0f;
- float invZoom = 1.0f / zoom;
- // Apply zoom to filter region here so that applyHorizontalScale/applyVerticalScale will
- // work while create hardware filters through FE<some filter effect>::createImageFilter()
- setFilterRegion(FloatRect(0, 0, 1, 1));
- setAbsoluteFilterRegion(FloatRect(0, 0, zoom, zoom));
-
RefPtr<FilterEffect> previousEffect = m_sourceGraphic;
for (size_t i = 0; i < operations.operations().size(); ++i) {
RefPtr<FilterEffect> effect;
@@ -245,8 +120,7 @@ bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations&
switch (filterOperation->getOperationType()) {
case FilterOperation::REFERENCE: {
ReferenceFilterOperation* referenceOperation = static_cast<ReferenceFilterOperation*>(filterOperation);
- effect = buildReferenceFilter(renderer, previousEffect, referenceOperation);
- referenceOperation->setFilterEffect(effect, this);
+ effect = ReferenceFilterBuilder::build(this, renderer, previousEffect.get(), referenceOperation);
break;
}
case FilterOperation::GRAYSCALE: {
@@ -370,15 +244,15 @@ bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations&
}
case FilterOperation::BLUR: {
BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation);
- float stdDeviation = floatValueForLength(blurOperation->stdDeviation(), 0) * invZoom;
+ float stdDeviation = floatValueForLength(blurOperation->stdDeviation(), 0);
effect = FEGaussianBlur::create(this, stdDeviation, stdDeviation);
break;
}
case FilterOperation::DROP_SHADOW: {
DropShadowFilterOperation* dropShadowOperation = static_cast<DropShadowFilterOperation*>(filterOperation);
- float stdDeviation = dropShadowOperation->stdDeviation() * invZoom;
- float x = dropShadowOperation->x() * invZoom;
- float y = dropShadowOperation->y() * invZoom;
+ float stdDeviation = dropShadowOperation->stdDeviation();
+ float x = dropShadowOperation->x();
+ float y = dropShadowOperation->y();
effect = FEDropShadow::create(this, stdDeviation, stdDeviation, x, y, dropShadowOperation->color(), 1);
break;
}
@@ -405,14 +279,17 @@ bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations&
effect->setClipsToBounds(false);
effect->setOperatingColorSpace(ColorSpaceDeviceRGB);
effect->inputEffects().append(previousEffect);
- m_effects.append(effect);
}
previousEffect = effect.release();
}
}
+ // We need to keep the old effects alive until this point, so that filters like FECustomFilter
+ // can share cached resources across frames.
+ m_lastEffect = previousEffect;
+
// If we didn't make any effects, tell our caller we are not valid
- if (!m_effects.size())
+ if (!m_lastEffect.get())
return false;
return true;
@@ -445,9 +322,8 @@ void FilterEffectRenderer::allocateBackingStoreIfNeeded()
void FilterEffectRenderer::clearIntermediateResults()
{
- m_sourceGraphic->clearResult();
- for (size_t i = 0; i < m_effects.size(); ++i)
- m_effects[i]->clearResult();
+ if (m_lastEffect.get())
+ m_lastEffect->clearResultsRecursive();
}
void FilterEffectRenderer::apply()
« no previous file with comments | « Source/core/rendering/FilterEffectRenderer.h ('k') | Source/core/rendering/RenderLayer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698