| Index: trunk/Source/core/rendering/FilterEffectRenderer.cpp
|
| ===================================================================
|
| --- trunk/Source/core/rendering/FilterEffectRenderer.cpp (revision 150368)
|
| +++ trunk/Source/core/rendering/FilterEffectRenderer.cpp (working copy)
|
| @@ -50,7 +50,6 @@
|
| #include "core/rendering/RenderView.h"
|
|
|
| #if ENABLE(SVG)
|
| -#include "SVGNames.h"
|
| #include "core/loader/cache/CachedSVGDocument.h"
|
| #include "core/loader/cache/CachedSVGDocumentReference.h"
|
| #include "core/platform/graphics/filters/SourceAlpha.h"
|
| @@ -144,11 +143,6 @@
|
| 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
|
| @@ -158,7 +152,7 @@
|
| // This may need a spec clarification.
|
| RefPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(previousEffect, SourceAlpha::create(this));
|
|
|
| - for (Node* node = filterElement->firstChild(); node; node = node->nextSibling()) {
|
| + for (Node* node = filter->firstChild(); node; node = node->nextSibling()) {
|
| if (!node->isSVGElement())
|
| continue;
|
|
|
| @@ -173,7 +167,6 @@
|
| continue;
|
|
|
| effectElement->setStandardAttributes(effect.get());
|
| - effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement->primitiveUnits(), sourceImageRect()));
|
| builder->add(effectElement->result(), effect);
|
| m_effects.append(effect);
|
| }
|
| @@ -190,6 +183,8 @@
|
| {
|
| m_hasCustomShaderFilter = false;
|
| m_hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels();
|
| + 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.
|
| @@ -356,11 +351,11 @@
|
| }
|
|
|
| if (effect) {
|
| + // Unlike SVG, filters applied here should not clip to their primitive subregions.
|
| + effect->setClipsToBounds(false);
|
| effect->setOperatingColorSpace(ColorSpaceDeviceRGB);
|
|
|
| if (filterOperation->getOperationType() != FilterOperation::REFERENCE) {
|
| - // Unlike SVG, filters applied here should not clip to their primitive subregions.
|
| - effect->setClipsToBounds(false);
|
| effect->inputEffects().append(previousEffect);
|
| m_effects.append(effect);
|
| }
|
| @@ -372,6 +367,8 @@
|
| if (!m_effects.size())
|
| return false;
|
|
|
| + setMaxEffectRects(m_sourceDrawingRegion);
|
| +
|
| return true;
|
| }
|
|
|
| @@ -422,14 +419,15 @@
|
| return filterBoxRect;
|
| }
|
| // The result of this function is the area in the "filterBoxRect" that needs to be repainted, so that we fully cover the "dirtyRect".
|
| - FloatRect rectForRepaint = dirtyRect;
|
| - rectForRepaint.move(-filterBoxRect.location().x(), -filterBoxRect.location().y());
|
| - float inf = std::numeric_limits<float>::infinity();
|
| - FloatRect clipRect = FloatRect(FloatPoint(-inf, -inf), FloatSize(inf, inf));
|
| - rectForRepaint = lastEffect()->getSourceRect(rectForRepaint, clipRect);
|
| - rectForRepaint.move(filterBoxRect.location().x(), filterBoxRect.location().y());
|
| + LayoutRect rectForRepaint = dirtyRect;
|
| + if (hasFilterThatMovesPixels()) {
|
| + // Note that the outsets are reversed here because we are going backwards -> we have the dirty rect and
|
| + // need to find out what is the rectangle that might influence the result inside that dirty rect.
|
| + rectForRepaint.move(-m_outsets.right(), -m_outsets.bottom());
|
| + rectForRepaint.expand(m_outsets.left() + m_outsets.right(), m_outsets.top() + m_outsets.bottom());
|
| + }
|
| rectForRepaint.intersect(filterBoxRect);
|
| - return LayoutRect(rectForRepaint);
|
| + return rectForRepaint;
|
| }
|
|
|
| bool FilterEffectRendererHelper::prepareFilterEffect(RenderLayer* renderLayer, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect)
|
| @@ -440,19 +438,13 @@
|
|
|
| FilterEffectRenderer* filter = renderLayer->filterRenderer();
|
| LayoutRect filterSourceRect = filter->computeSourceImageRectForDirtyRect(filterBoxRect, dirtyRect);
|
| + m_paintOffset = filterSourceRect.location();
|
|
|
| if (filterSourceRect.isEmpty()) {
|
| // The dirty rect is not in view, just bail out.
|
| m_haveFilterEffect = false;
|
| return false;
|
| }
|
| -
|
| - AffineTransform absoluteTransform;
|
| - absoluteTransform.translate(filterBoxRect.x(), filterBoxRect.y());
|
| - filter->setAbsoluteTransform(absoluteTransform);
|
| - filter->setAbsoluteFilterRegion(filterSourceRect);
|
| - filter->setFilterRegion(absoluteTransform.inverse().mapRect(filterSourceRect));
|
| - filter->lastEffect()->determineFilterPrimitiveSubregion();
|
|
|
| bool hasUpdatedBackingStore = filter->updateBackingStoreRect(filterSourceRect);
|
| if (filter->hasFilterThatMovesPixels()) {
|
| @@ -474,7 +466,7 @@
|
| filter->allocateBackingStoreIfNeeded();
|
| // Paint into the context that represents the SourceGraphic of the filter.
|
| GraphicsContext* sourceGraphicsContext = filter->inputContext();
|
| - if (!sourceGraphicsContext || !isFilterSizeValid(filter->absoluteFilterRegion())) {
|
| + if (!sourceGraphicsContext || !isFilterSizeValid(filter->filterRegion())) {
|
| // Disable the filters and continue.
|
| m_haveFilterEffect = false;
|
| return oldContext;
|
| @@ -484,10 +476,7 @@
|
|
|
| // Translate the context so that the contents of the layer is captuterd in the offscreen memory buffer.
|
| sourceGraphicsContext->save();
|
| - // FIXME: can we just use sourceImageRect for everything, and get rid of
|
| - // m_repaintRect?
|
| - FloatPoint offset = filter->sourceImageRect().location();
|
| - sourceGraphicsContext->translate(-offset.x(), -offset.y());
|
| + sourceGraphicsContext->translate(-m_paintOffset.x(), -m_paintOffset.y());
|
| sourceGraphicsContext->clearRect(m_repaintRect);
|
| sourceGraphicsContext->clip(m_repaintRect);
|
|
|
| @@ -503,8 +492,11 @@
|
| filter->apply();
|
|
|
| // Get the filtered output and draw it in place.
|
| - m_savedGraphicsContext->drawImageBuffer(filter->output(), m_renderLayer->renderer()->style()->colorSpace(), filter->outputRect(), CompositeSourceOver);
|
| + LayoutRect destRect = filter->outputRect();
|
| + destRect.move(m_paintOffset.x(), m_paintOffset.y());
|
|
|
| + m_savedGraphicsContext->drawImageBuffer(filter->output(), m_renderLayer->renderer()->style()->colorSpace(), pixelSnappedIntRect(destRect), CompositeSourceOver);
|
| +
|
| filter->clearIntermediateResults();
|
|
|
| return m_savedGraphicsContext;
|
|
|