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

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

Issue 13984002: Extracting the SVG Filter Reference implementation out of the FilterEffectRenderer into its own typ… Base URL: https://chromium.googlesource.com/chromium/blink@master
Patch Set: Updated to ToT, fixed style, warnings Created 7 years, 7 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 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()
« 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