| Index: Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
|
| ===================================================================
|
| --- Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp (revision 134257)
|
| +++ Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp (working copy)
|
| @@ -57,25 +57,6 @@
|
|
|
| namespace WebCore {
|
|
|
| -class ApplyingFilterEffectGuard {
|
| -public:
|
| - ApplyingFilterEffectGuard(FilterData* data)
|
| - : m_filterData(data)
|
| - {
|
| - // The guard must be constructed when the filter is not applying.
|
| - ASSERT(!m_filterData->isApplying);
|
| - m_filterData->isApplying = true;
|
| - }
|
| -
|
| - ~ApplyingFilterEffectGuard()
|
| - {
|
| - ASSERT(m_filterData->isApplying);
|
| - m_filterData->isApplying = false;
|
| - }
|
| -
|
| - FilterData* m_filterData;
|
| -};
|
| -
|
| RenderSVGResourceType RenderSVGResourceFilter::s_resourceType = FilterResourceType;
|
|
|
| RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement* node)
|
| @@ -108,7 +89,7 @@
|
|
|
| if (FilterData* filterData = m_filter.get(client)) {
|
| if (filterData->savedContext)
|
| - filterData->markedForRemoval = true;
|
| + filterData->state = FilterData::MarkedForRemoval;
|
| else
|
| delete m_filter.take(client);
|
| }
|
| @@ -168,14 +149,11 @@
|
| ASSERT(context);
|
| ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);
|
|
|
| - // Returning false here, to avoid drawings onto the context. We just want to
|
| - // draw the stored filter output, not the unfiltered object as well.
|
| if (m_filter.contains(object)) {
|
| FilterData* filterData = m_filter.get(object);
|
| - if (filterData->isBuilt || filterData->isApplying)
|
| - return false;
|
| -
|
| - delete m_filter.take(object); // Oops, have to rebuild, go through normal code path
|
| + if (filterData->state == FilterData::PaintingSource || filterData->state == FilterData::Applying)
|
| + filterData->state = FilterData::CycleDetected;
|
| + return false; // Already built, or we're in a cycle, or we're marked for removal. Regardless, just do nothing more now.
|
| }
|
|
|
| OwnPtr<FilterData> filterData(adoptPtr(new FilterData));
|
| @@ -292,17 +270,21 @@
|
| if (!filterData)
|
| return;
|
|
|
| - if (filterData->markedForRemoval) {
|
| + switch (filterData->state) {
|
| + case FilterData::MarkedForRemoval:
|
| delete m_filter.take(object);
|
| return;
|
| - }
|
|
|
| - // We have a cycle if we are already applying the data.
|
| - // This can occur due to FeImage referencing a source that makes use of the FEImage itself.
|
| - if (filterData->isApplying)
|
| + case FilterData::CycleDetected:
|
| + case FilterData::Applying:
|
| + // We have a cycle if we are already applying the data.
|
| + // This can occur due to FeImage referencing a source that makes use of the FEImage itself.
|
| + // This is the first place we've hit the cycle, so set the state back to PaintingSource so the return stack
|
| + // will continue correctly.
|
| + filterData->state = FilterData::PaintingSource;
|
| return;
|
|
|
| - if (!filterData->isBuilt) {
|
| + case FilterData::PaintingSource:
|
| if (!filterData->savedContext) {
|
| removeClientFromCache(object);
|
| return;
|
| @@ -310,21 +292,23 @@
|
|
|
| context = filterData->savedContext;
|
| filterData->savedContext = 0;
|
| + break;
|
| +
|
| + case FilterData::Built: { } // Empty
|
| }
|
|
|
| - ApplyingFilterEffectGuard isApplyingGuard(filterData);
|
| -
|
| FilterEffect* lastEffect = filterData->builder->lastEffect();
|
|
|
| if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->filterPrimitiveSubregion().isEmpty()) {
|
| // This is the real filtering of the object. It just needs to be called on the
|
| // initial filtering process. We just take the stored filter result on a
|
| // second drawing.
|
| - if (!filterData->isBuilt)
|
| + if (filterData->state != FilterData::Built)
|
| filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.release());
|
|
|
| - // Always true if filterData is just built (filterData->isBuilt is false).
|
| + // Always true if filterData is just built (filterData->state == FilterData::Built).
|
| if (!lastEffect->hasResult()) {
|
| + filterData->state = FilterData::Applying;
|
| lastEffect->apply();
|
| lastEffect->correctFilterResultIfNeeded();
|
| #if !USE(CG)
|
| @@ -333,7 +317,7 @@
|
| resultImage->transformColorSpace(lastEffect->colorSpace(), ColorSpaceDeviceRGB);
|
| #endif
|
| }
|
| - filterData->isBuilt = true;
|
| + filterData->state = FilterData::Built;
|
|
|
| ImageBuffer* resultImage = lastEffect->asImageBuffer();
|
| if (resultImage) {
|
| @@ -365,7 +349,7 @@
|
|
|
| for (; it != end; ++it) {
|
| FilterData* filterData = it->second;
|
| - if (!filterData->isBuilt)
|
| + if (filterData->state != FilterData::Built)
|
| continue;
|
|
|
| SVGFilterBuilder* builder = filterData->builder.get();
|
|
|