SkImageFilter* CanvasRenderingContext2DState::getFilter(Element* styleResolutionHost, const Font& font, IntSize canvasSize) const
{
    if (!m_filterValue)
        return nullptr;

    if (!m_resolvedFilter) {
        RefPtr<ComputedStyle> filterStyle = ComputedStyle::create();
        // Must set font in case the filter uses any font-relative units (em, ex)
        filterStyle->setFont(font);

        StyleResolverState resolverState(styleResolutionHost->document(), styleResolutionHost, filterStyle.get());
        resolverState.setStyle(filterStyle);

        StyleBuilder::applyProperty(CSSPropertyWebkitFilter, resolverState, m_filterValue.get());
        RefPtrWillBeRawPtr<FilterEffectBuilder> filterEffectBuilder = FilterEffectBuilder::create();

        // We can't reuse m_fillPaint and m_strokePaint for the filter, since these incorporate
        // the global alpha, which isn't applicable here.
        SkPaint fillPaintForFilter;
        SkPaint strokePaintForFilter;
        m_fillStyle->applyToPaint(fillPaintForFilter);
        m_strokeStyle->applyToPaint(strokePaintForFilter);
        fillPaintForFilter.setColor(m_fillStyle->paintColor());
        strokePaintForFilter.setColor(m_strokeStyle->paintColor());
        FloatSize floatCanvasSize(canvasSize);
        const double effectiveZoom = 1.0; // Deliberately ignore zoom on the canvas element
        filterEffectBuilder->build(styleResolutionHost, filterStyle->filter(), effectiveZoom, &floatCanvasSize, &fillPaintForFilter, &strokePaintForFilter);

        SkiaImageFilterBuilder imageFilterBuilder;
        RefPtrWillBeRawPtr<FilterEffect> lastEffect = filterEffectBuilder->lastEffect();
        m_resolvedFilter = imageFilterBuilder.build(lastEffect.get(), ColorSpaceDeviceRGB);
    }

    return m_resolvedFilter.get();
}
SkImageFilter* CanvasRenderingContext2DState::getFilter(Element* styleResolutionHost, IntSize canvasSize, CanvasRenderingContext2D* context) const
{
    if (!m_filterValue)
        return nullptr;

    // StyleResolverState cannot be used in frame-less documents.
    if (!styleResolutionHost->document().frame())
        return nullptr;

    if (!m_resolvedFilter) {
        RefPtr<ComputedStyle> filterStyle = ComputedStyle::create();
        // Must set font in case the filter uses any font-relative units (em, ex)
        filterStyle->setFont(m_fontForFilter);

        StyleResolverState resolverState(styleResolutionHost->document(), styleResolutionHost, filterStyle.get());
        resolverState.setStyle(filterStyle);

        StyleBuilder::applyProperty(CSSPropertyFilter, resolverState, *m_filterValue);
        resolverState.loadPendingResources();
        FilterEffectBuilder* filterEffectBuilder = FilterEffectBuilder::create();

        // We can't reuse m_fillPaint and m_strokePaint for the filter, since these incorporate
        // the global alpha, which isn't applicable here.
        SkPaint fillPaintForFilter;
        SkPaint strokePaintForFilter;
        m_fillStyle->applyToPaint(fillPaintForFilter);
        m_strokeStyle->applyToPaint(strokePaintForFilter);
        fillPaintForFilter.setColor(m_fillStyle->paintColor());
        strokePaintForFilter.setColor(m_strokeStyle->paintColor());
        FloatSize floatCanvasSize(canvasSize);
        const double effectiveZoom = 1.0; // Deliberately ignore zoom on the canvas element
        filterEffectBuilder->build(styleResolutionHost, filterStyle->filter(), effectiveZoom, &floatCanvasSize, &fillPaintForFilter, &strokePaintForFilter);

        FilterEffect* lastEffect = filterEffectBuilder->lastEffect();
        if (lastEffect) {
            lastEffect->determineFilterPrimitiveSubregion();
        }
        m_resolvedFilter = SkiaImageFilterBuilder::build(lastEffect, ColorSpaceDeviceRGB);
        if (m_resolvedFilter) {
            updateFilterReferences(toHTMLCanvasElement(styleResolutionHost), context, filterStyle->filter());
            if (lastEffect->originTainted())
                context->setOriginTainted();
        }
    }

    return m_resolvedFilter.get();
}