SkImageFilter* CanvasRenderingContext2DState::shadowAndForegroundImageFilter() const
{
    if (!m_shadowAndForegroundImageFilter) {
        double sigma = skBlurRadiusToSigma(m_shadowBlur);
        m_shadowAndForegroundImageFilter = adoptRef(SkDropShadowImageFilter::Create(m_shadowOffset.width(), m_shadowOffset.height(), sigma, sigma, m_shadowColor, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode));
    }
    return m_shadowAndForegroundImageFilter.get();
}
SkImageFilter* CanvasRenderingContext2DState::shadowOnlyImageFilter() const
{
    if (!m_shadowOnlyImageFilter) {
        double sigma = skBlurRadiusToSigma(m_shadowBlur);
        m_shadowOnlyImageFilter = SkDropShadowImageFilter::Make(m_shadowOffset.width(), m_shadowOffset.height(), sigma, sigma, m_shadowColor, SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode, nullptr);
    }
    return m_shadowOnlyImageFilter.get();
}
void DrawLooperBuilder::addShadow(const FloatSize& offset, float blur, const Color& color,
    ShadowTransformMode shadowTransformMode, ShadowAlphaMode shadowAlphaMode)
{
    // Negative blurs are not allowed, so just pin the value to 0
    if (blur < 0)
        blur = 0;

    // Detect when there's no effective shadow.
    if (!color.alpha())
        return;

    SkColor skColor = color.rgb();

    SkLayerDrawLooper::LayerInfo info;

    switch (shadowAlphaMode) {
    case ShadowRespectsAlpha:
        info.fColorMode = SkXfermode::kDst_Mode;
        break;
    case ShadowIgnoresAlpha:
        info.fColorMode = SkXfermode::kSrc_Mode;
        break;
    default:
        ASSERT_NOT_REACHED();
    }

    if (blur)
        info.fPaintBits |= SkLayerDrawLooper::kMaskFilter_Bit; // our blur
    info.fPaintBits |= SkLayerDrawLooper::kColorFilter_Bit;
    info.fOffset.set(offset.width(), offset.height());
    info.fPostTranslate = (shadowTransformMode == ShadowIgnoresTransforms);

    SkPaint* paint = m_skDrawLooperBuilder.addLayerOnTop(info);

    if (blur) {
        const SkScalar sigma = skBlurRadiusToSigma(blur);
        uint32_t mfFlags = SkBlurMaskFilter::kHighQuality_BlurFlag;
        if (shadowTransformMode == ShadowIgnoresTransforms)
            mfFlags |= SkBlurMaskFilter::kIgnoreTransform_BlurFlag;
        RefPtr<SkMaskFilter> mf = adoptRef(SkBlurMaskFilter::Create(kNormal_SkBlurStyle, sigma, mfFlags));
        paint->setMaskFilter(mf.get());
    }

    RefPtr<SkColorFilter> cf = adoptRef(SkColorFilter::CreateModeFilter(skColor, SkXfermode::kSrcIn_Mode));
    paint->setColorFilter(cf.get());
}