void RenderSVGResourceFilter::postApplyResource(RenderElement& renderer, GraphicsContext*& context, unsigned short resourceMode, const Path*, const RenderSVGShape*) { ASSERT(context); ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode); FilterData* filterData = m_filter.get(&renderer); if (!filterData) return; switch (filterData->state) { case FilterData::MarkedForRemoval: m_filter.remove(&renderer); return; 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; case FilterData::PaintingSource: if (!filterData->savedContext) { removeClientFromCache(renderer); return; } context = filterData->savedContext; filterData->savedContext = 0; break; case FilterData::Built: { } // Empty } 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->state != FilterData::Built) filterData->filter->setSourceImage(WTF::move(filterData->sourceGraphicBuffer)); // Always true if filterData is just built (filterData->state == FilterData::Built). if (!lastEffect->hasResult()) { filterData->state = FilterData::Applying; lastEffect->applyAll(); lastEffect->correctFilterResultIfNeeded(); lastEffect->transformResultColorSpace(ColorSpaceDeviceRGB); } filterData->state = FilterData::Built; ImageBuffer* resultImage = lastEffect->asImageBuffer(); if (resultImage) { context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse()); context->scale(FloatSize(1 / filterData->filter->filterResolution().width(), 1 / filterData->filter->filterResolution().height())); context->drawImageBuffer(resultImage, renderer.style().colorSpace(), lastEffect->absolutePaintRect()); context->scale(filterData->filter->filterResolution()); context->concatCTM(filterData->shearFreeAbsoluteTransform); } } filterData->sourceGraphicBuffer.reset(); }