| Index: Source/core/rendering/FilterEffectRenderer.cpp
|
| diff --git a/Source/core/rendering/FilterEffectRenderer.cpp b/Source/core/rendering/FilterEffectRenderer.cpp
|
| index 6d6ce158d6ef4900745dbe18ee657e6fa76934b6..7ea0e8fac10faf7ada596e899dec63531b1de04f 100644
|
| --- a/Source/core/rendering/FilterEffectRenderer.cpp
|
| +++ b/Source/core/rendering/FilterEffectRenderer.cpp
|
| @@ -53,6 +53,7 @@
|
| #include "core/loader/cache/CachedSVGDocument.h"
|
| #include "core/loader/cache/CachedSVGDocumentReference.h"
|
| #include "core/platform/graphics/filters/SourceAlpha.h"
|
| +#include "core/rendering/svg/ReferenceFilterBuilder.h"
|
| #include "core/svg/SVGElement.h"
|
| #include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
|
| #endif
|
| @@ -115,70 +116,6 @@ GraphicsContext* FilterEffectRenderer::inputContext()
|
| return sourceImage() ? sourceImage()->context() : 0;
|
| }
|
|
|
| -PassRefPtr<FilterEffect> FilterEffectRenderer::buildReferenceFilter(RenderObject* renderer, PassRefPtr<FilterEffect> previousEffect, ReferenceFilterOperation* filterOperation)
|
| -{
|
| -#if ENABLE(SVG)
|
| - if (!renderer)
|
| - return 0;
|
| -
|
| - Document* document = renderer->document();
|
| - ASSERT(document);
|
| -
|
| - CachedSVGDocumentReference* cachedSVGDocumentReference = filterOperation->cachedSVGDocumentReference();
|
| - CachedSVGDocument* 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;
|
| - }
|
| -
|
| - 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));
|
| -
|
| - for (Node* node = filter->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());
|
| - builder->add(effectElement->result(), effect);
|
| - m_effects.append(effect);
|
| - }
|
| - return effect;
|
| -#else
|
| - UNUSED_PARAM(renderer);
|
| - UNUSED_PARAM(previousEffect);
|
| - UNUSED_PARAM(filterOperation);
|
| - return 0;
|
| -#endif
|
| -}
|
| -
|
| bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations& operations)
|
| {
|
| m_hasCustomShaderFilter = false;
|
| @@ -186,11 +123,6 @@ bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations&
|
| if (m_hasFilterThatMovesPixels)
|
| m_outsets = operations.outsets();
|
|
|
| - // 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);
|
| -
|
| RefPtr<FilterEffect> previousEffect = m_sourceGraphic;
|
| for (size_t i = 0; i < operations.operations().size(); ++i) {
|
| RefPtr<FilterEffect> effect;
|
| @@ -198,8 +130,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);
|
| + effect = ReferenceFilterBuilder::build(this, renderer, previousEffect.get(), referenceOperation);
|
| break;
|
| }
|
| case FilterOperation::GRAYSCALE: {
|
| @@ -355,16 +286,20 @@ bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations&
|
| effect->setClipsToBounds(false);
|
| effect->setOperatingColorSpace(ColorSpaceDeviceRGB);
|
|
|
| - if (filterOperation->getOperationType() != FilterOperation::REFERENCE) {
|
| + // Reference filters already have a reference to the previousFilter.
|
| + if (filterOperation->getOperationType() != FilterOperation::REFERENCE)
|
| 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;
|
|
|
| setMaxEffectRects(m_sourceDrawingRegion);
|
| @@ -372,6 +307,12 @@ bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations&
|
| return true;
|
| }
|
|
|
| +void FilterEffectRenderer::setMaxEffectRects(const FloatRect& effectRect)
|
| +{
|
| + if (m_lastEffect.get())
|
| + m_lastEffect->setMaxEffectRectRecursive(effectRect);
|
| +}
|
| +
|
| bool FilterEffectRenderer::updateBackingStoreRect(const FloatRect& filterRect)
|
| {
|
| if (!filterRect.isZero() && isFilterSizeValid(filterRect)) {
|
| @@ -399,9 +340,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()
|
|
|