Remove ambient and spot mask filters.
authorJim Van Verth <jvanverth@google.com>
Thu, 18 May 2017 19:06:54 +0000 (15:06 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Thu, 18 May 2017 19:45:45 +0000 (19:45 +0000)
Also remove a deprecated interface in SkShadowUtils.

Change-Id: I32e67271be953f11071c512cb39a47ea1e7dcaaf
Reviewed-on: https://skia-review.googlesource.com/17266
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>

gn/effects.gni
include/utils/SkShadowUtils.h
src/effects/shadows/SkAmbientShadowMaskFilter.cpp [deleted file]
src/effects/shadows/SkAmbientShadowMaskFilter.h [deleted file]
src/effects/shadows/SkSpotShadowMaskFilter.cpp [deleted file]
src/effects/shadows/SkSpotShadowMaskFilter.h [deleted file]
src/gpu/GrRenderTargetContext.cpp
src/gpu/GrRenderTargetContext.h
src/gpu/SkGpuDevice.cpp
src/utils/SkShadowUtils.cpp

index df8e75b..278925b 100644 (file)
@@ -86,11 +86,6 @@ skia_effects_sources = [
   "$_src/effects/gradients/SkSweepGradient.cpp",
   "$_src/effects/gradients/SkSweepGradient.h",
 
-  "$_src/effects/shadows/SkAmbientShadowMaskFilter.cpp",
-  "$_src/effects/shadows/SkAmbientShadowMaskFilter.h",
-  "$_src/effects/shadows/SkSpotShadowMaskFilter.cpp",
-  "$_src/effects/shadows/SkSpotShadowMaskFilter.h",
-
   "$_include/effects/Sk1DPathEffect.h",
   "$_include/effects/Sk2DPathEffect.h",
   "$_include/effects/SkAlphaThresholdFilter.h",
index 2385a48..838a12b 100644 (file)
@@ -46,7 +46,7 @@ public:
     * Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
     * light.
     *
-    * Deprecated version with height value (to be removed when Android and Flutter are updated).
+    * Deprecated version with height value (to be removed when Flutter is updated).
     *
     * @param canvas  The canvas on which to draw the shadows.
     * @param path  The occluder used to generate the shadows.
@@ -69,42 +69,6 @@ public:
         DrawShadow(canvas, path, zPlane, lightPos, lightRadius, ambientAlpha, spotAlpha,
                    color, flags);
     }
-
-#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
-    /**
-     * Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
-     * light. Takes a function to vary the z value based on the local x and y position.
-     * This shadow will not be cached, as the assumption is that this will be used for animation.
-     *
-     * Deprecated (to be removed when Android is updated).
-     *
-     * @param canvas  The canvas on which to draw the shadows.
-     * @param path  The occluder used to generate the shadows.
-     * @param heightFunc  A function which returns the vertical offset of the occluder from the
-     *  canvas based on local x and y values (the current matrix is not applied).
-     * @param lightPos  The 3D position of the light relative to the canvas plane. This is
-     *  independent of the canvas's current matrix.
-     * @param lightRadius  The radius of the disc light.
-     * @param ambientAlpha  The maximum alpha of the ambient shadow.
-     * @param spotAlpha  The maxium alpha of the spot shadow.
-     * @param color  The shadow color.
-     * @param flags  Options controlling opaque occluder optimizations and shadow appearance. See
-     *               SkShadowFlags.
-     */
-    static void DrawUncachedShadow(SkCanvas* canvas, const SkPath& path,
-                                   std::function<SkScalar(SkScalar, SkScalar)> heightFunc,
-                                   const SkPoint3& lightPos, SkScalar lightRadius,
-                                   SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
-                                   uint32_t flags = SkShadowFlags::kNone_ShadowFlag) {
-        SkPoint3 zPlane;
-        zPlane.fZ = heightFunc(0, 0);
-        zPlane.fX = heightFunc(1, 0) - zPlane.fZ;
-        zPlane.fY = heightFunc(0, 1) - zPlane.fZ;
-
-        DrawShadow(canvas, path, zPlane, lightPos, lightRadius, ambientAlpha, spotAlpha,
-                   color, flags);
-    }
-#endif
 };
 
 #endif
diff --git a/src/effects/shadows/SkAmbientShadowMaskFilter.cpp b/src/effects/shadows/SkAmbientShadowMaskFilter.cpp
deleted file mode 100644 (file)
index 66218cd..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkAmbientShadowMaskFilter.h"
-#include "SkReadBuffer.h"
-#include "SkStringUtils.h"
-#include "SkWriteBuffer.h"
-
-#if SK_SUPPORT_GPU
-#include "GrContext.h"
-#include "GrRenderTargetContext.h"
-#include "GrFragmentProcessor.h"
-#include "GrStyle.h"
-#include "GrTexture.h"
-#include "GrTextureProxy.h"
-#include "SkStrokeRec.h"
-#endif
-
-class SkAmbientShadowMaskFilterImpl : public SkMaskFilter {
-public:
-    SkAmbientShadowMaskFilterImpl(SkScalar occluderHeight, SkScalar ambientAlpha, uint32_t flags);
-
-    // overrides from SkMaskFilter
-    SkMask::Format getFormat() const override;
-    bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
-                    SkIPoint* margin) const override;
-
-#if SK_SUPPORT_GPU
-    bool canFilterMaskGPU(const SkRRect& devRRect,
-                          const SkIRect& clipBounds,
-                          const SkMatrix& ctm,
-                          SkRect* maskRect) const override;
-    bool directFilterMaskGPU(GrContext*,
-                             GrRenderTargetContext* drawContext,
-                             GrPaint&&,
-                             const GrClip&,
-                             const SkMatrix& viewMatrix,
-                             const SkStrokeRec& strokeRec,
-                             const SkPath& path) const override;
-    bool directFilterRRectMaskGPU(GrContext*,
-                                  GrRenderTargetContext* drawContext,
-                                  GrPaint&&,
-                                  const GrClip&,
-                                  const SkMatrix& viewMatrix,
-                                  const SkStrokeRec& strokeRec,
-                                  const SkRRect& rrect,
-                                  const SkRRect& devRRect) const override;
-    sk_sp<GrTextureProxy> filterMaskGPU(GrContext*,
-                                        sk_sp<GrTextureProxy> srcProxy,
-                                        const SkMatrix& ctm,
-                                        const SkIRect& maskRect) const override;
-#endif
-
-    void computeFastBounds(const SkRect&, SkRect*) const override;
-
-    SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAmbientShadowMaskFilterImpl)
-
-private:
-    SkScalar fOccluderHeight;
-    SkScalar fAmbientAlpha;
-    uint32_t fFlags;
-
-    SkAmbientShadowMaskFilterImpl(SkReadBuffer&);
-    void flatten(SkWriteBuffer&) const override;
-
-    friend class SkAmbientShadowMaskFilter;
-
-    typedef SkMaskFilter INHERITED;
-};
-
-sk_sp<SkMaskFilter> SkAmbientShadowMaskFilter::Make(SkScalar occluderHeight, SkScalar ambientAlpha,
-                                                    uint32_t flags) {
-    // add some param checks here for early exit
-
-    return sk_sp<SkMaskFilter>(new SkAmbientShadowMaskFilterImpl(occluderHeight, ambientAlpha,
-                                                                 flags));
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-SkAmbientShadowMaskFilterImpl::SkAmbientShadowMaskFilterImpl(SkScalar occluderHeight,
-                                                             SkScalar ambientAlpha,
-                                                             uint32_t flags)
-    : fOccluderHeight(occluderHeight)
-    , fAmbientAlpha(ambientAlpha)
-    , fFlags(flags) {
-    SkASSERT(fOccluderHeight > 0);
-    SkASSERT(fAmbientAlpha >= 0);
-}
-
-SkMask::Format SkAmbientShadowMaskFilterImpl::getFormat() const {
-    return SkMask::kA8_Format;
-}
-
-bool SkAmbientShadowMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src,
-                                               const SkMatrix& matrix,
-                                               SkIPoint* margin) const {
-    // TODO something
-    return false;
-}
-
-void SkAmbientShadowMaskFilterImpl::computeFastBounds(const SkRect& src, SkRect* dst) const {
-    // TODO compute based on ambient data
-    dst->set(src.fLeft, src.fTop, src.fRight, src.fBottom);
-}
-
-sk_sp<SkFlattenable> SkAmbientShadowMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
-    const SkScalar occluderHeight = buffer.readScalar();
-    const SkScalar ambientAlpha = buffer.readScalar();
-    const uint32_t flags = buffer.readUInt();
-
-    return SkAmbientShadowMaskFilter::Make(occluderHeight, ambientAlpha, flags);
-}
-
-void SkAmbientShadowMaskFilterImpl::flatten(SkWriteBuffer& buffer) const {
-    buffer.writeScalar(fOccluderHeight);
-    buffer.writeScalar(fAmbientAlpha);
-    buffer.writeUInt(fFlags);
-}
-
-#if SK_SUPPORT_GPU
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-bool SkAmbientShadowMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect,
-                                                     const SkIRect& clipBounds,
-                                                     const SkMatrix& ctm,
-                                                     SkRect* maskRect) const {
-    // TODO
-    *maskRect = devRRect.rect();
-    return true;
-}
-
-static const float kHeightFactor = 1.0f / 128.0f;
-static const float kGeomFactor = 64.0f;
-
-bool SkAmbientShadowMaskFilterImpl::directFilterMaskGPU(GrContext* context,
-                                                        GrRenderTargetContext* rtContext,
-                                                        GrPaint&& paint,
-                                                        const GrClip& clip,
-                                                        const SkMatrix& viewMatrix,
-                                                        const SkStrokeRec& strokeRec,
-                                                        const SkPath& path) const {
-    SkASSERT(rtContext);
-    // TODO: this will not handle local coordinates properly
-
-    SkRect rect;
-    SkRRect rrect;
-    if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(),
-                                                  rect.height())) {
-        rrect = SkRRect::MakeOval(rect);
-        return this->directFilterRRectMaskGPU(context, rtContext, std::move(paint), clip,
-                                              SkMatrix::I(), strokeRec, rrect, rrect);
-    } else if (path.isRect(&rect)) {
-        rrect = SkRRect::MakeRect(rect);
-        return this->directFilterRRectMaskGPU(context, rtContext, std::move(paint), clip,
-                                              SkMatrix::I(), strokeRec, rrect, rrect);
-    } else if (path.isRRect(&rrect) && rrect.isSimpleCircular()) {
-        return this->directFilterRRectMaskGPU(context, rtContext, std::move(paint), clip,
-                                              SkMatrix::I(), strokeRec, rrect, rrect);
-    }
-
-    return false;
-}
-
-bool SkAmbientShadowMaskFilterImpl::directFilterRRectMaskGPU(GrContext*,
-                                                             GrRenderTargetContext* rtContext,
-                                                             GrPaint&& paint,
-                                                             const GrClip& clip,
-                                                             const SkMatrix& viewMatrix,
-                                                             const SkStrokeRec& strokeRec,
-                                                             const SkRRect& rrect,
-                                                             const SkRRect& devRRect) const {
-    // Fast path only supports filled rrects for now.
-    // TODO: fill and stroke as well.
-    if (SkStrokeRec::kFill_Style != strokeRec.getStyle()) {
-        return false;
-    }
-    // These should have been checked by the caller.
-    // Fast path only supports simple rrects with circular corners.
-    SkASSERT(devRRect.isRect() || devRRect.isCircle() ||
-             (devRRect.isSimple() && devRRect.allCornersCircular()));
-    // Fast path only supports uniform scale.
-    SkASSERT(viewMatrix.isSimilarity());
-    // Assume we have positive alpha
-    SkASSERT(fAmbientAlpha > 0);
-
-    // 1/scale
-    SkScalar devToSrcScale = viewMatrix.isScaleTranslate() ?
-        SkScalarInvert(viewMatrix[SkMatrix::kMScaleX]) :
-        sk_float_rsqrt(viewMatrix[SkMatrix::kMScaleX] * viewMatrix[SkMatrix::kMScaleX] +
-                       viewMatrix[SkMatrix::kMSkewX] * viewMatrix[SkMatrix::kMSkewX]);
-
-    SkScalar devSpaceInsetWidth = fOccluderHeight * kHeightFactor * kGeomFactor;
-    const float umbraAlpha = (1.0f + SkTMax(fOccluderHeight * kHeightFactor, 0.0f));
-    const SkScalar devSpaceAmbientBlur = devSpaceInsetWidth * umbraAlpha;
-
-    // Outset the shadow rrect to the border of the penumbra
-    SkScalar ambientPathOutset = devSpaceInsetWidth * devToSrcScale;
-    SkRRect ambientRRect;
-    SkRect outsetRect = rrect.rect().makeOutset(ambientPathOutset, ambientPathOutset);
-    // If the rrect was an oval then its outset will also be one.
-    // We set it explicitly to avoid errors.
-    if (rrect.isOval()) {
-        ambientRRect = SkRRect::MakeOval(outsetRect);
-    } else {
-        SkScalar outsetRad = rrect.getSimpleRadii().fX + ambientPathOutset;
-        ambientRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
-    }
-
-    GrPaint newPaint(paint);
-    GrColor4f color = newPaint.getColor4f();
-    newPaint.setColor4f(color.mulByScalar(fAmbientAlpha));
-    if (SkToBool(fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag)) {
-        // set a large inset to force a fill
-        devSpaceInsetWidth = ambientRRect.width();
-    }
-
-    // the fraction of the blur we want to apply is devSpaceInsetWidth/devSpaceAmbientBlur,
-    // which is just 1/umbraAlpha.
-    SkScalar blurClamp = SkScalarInvert(umbraAlpha);
-    rtContext->drawShadowRRect(clip, std::move(newPaint), viewMatrix, ambientRRect,
-                               devSpaceAmbientBlur, devSpaceInsetWidth,
-                               blurClamp);
-
-    return true;
-}
-
-sk_sp<GrTextureProxy> SkAmbientShadowMaskFilterImpl::filterMaskGPU(GrContext*,
-                                                                   sk_sp<GrTextureProxy> srcProxy,
-                                                                   const SkMatrix& ctm,
-                                                                   const SkIRect& maskRect) const {
-    // This filter is generative and doesn't operate on pre-existing masks
-    return nullptr;
-}
-
-#endif // SK_SUPPORT_GPU
-
-#ifndef SK_IGNORE_TO_STRING
-void SkAmbientShadowMaskFilterImpl::toString(SkString* str) const {
-    str->append("SkAmbientShadowMaskFilterImpl: (");
-
-    str->append("occluderHeight: ");
-    str->appendScalar(fOccluderHeight);
-    str->append(" ");
-
-    str->append("ambientAlpha: ");
-    str->appendScalar(fAmbientAlpha);
-    str->append(" ");
-
-    str->append("flags: (");
-    if (fFlags) {
-        bool needSeparator = false;
-        SkAddFlagToString(str,
-                          SkToBool(fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag),
-                          "TransparentOccluder", &needSeparator);
-    } else {
-        str->append("None");
-    }
-    str->append("))");
-}
-#endif
-
-SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkAmbientShadowMaskFilter)
-SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAmbientShadowMaskFilterImpl)
-SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
diff --git a/src/effects/shadows/SkAmbientShadowMaskFilter.h b/src/effects/shadows/SkAmbientShadowMaskFilter.h
deleted file mode 100644 (file)
index cd77b10..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkAmbientShadowMaskFilter_DEFINED
-#define SkAmbientShadowMaskFilter_DEFINED
-
-#include "SkMaskFilter.h"
-#include "SkShadowFlags.h"
-
-/*
- * This filter implements a shadow representing ambient occlusion for an occluding object.
- */
-class SK_API SkAmbientShadowMaskFilter {
-public:
-    /** Create a shadow maskfilter.
-     *  @param occluderHeight Height of occluding object off of ground plane.
-     *  @param ambientAlpha   Base opacity of the ambient occlusion shadow.
-     *  @param flags          Flags to use - defaults to none
-     *  @return The new shadow maskfilter
-     */
-    static sk_sp<SkMaskFilter> Make(SkScalar occluderHeight, SkScalar ambientAlpha,
-                                    uint32_t flags = SkShadowFlags::kNone_ShadowFlag);
-
-    SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
-
-private:
-    SkAmbientShadowMaskFilter(); // can't be instantiated
-};
-#endif
diff --git a/src/effects/shadows/SkSpotShadowMaskFilter.cpp b/src/effects/shadows/SkSpotShadowMaskFilter.cpp
deleted file mode 100644 (file)
index a51aa56..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkSpotShadowMaskFilter.h"
-#include "SkReadBuffer.h"
-#include "SkStringUtils.h"
-#include "SkWriteBuffer.h"
-
-#if SK_SUPPORT_GPU
-#include "GrContext.h"
-#include "GrRenderTargetContext.h"
-#include "GrFragmentProcessor.h"
-#include "GrStyle.h"
-#include "GrTexture.h"
-#include "GrTextureProxy.h"
-#include "SkStrokeRec.h"
-#endif
-
-class SkSpotShadowMaskFilterImpl : public SkMaskFilter {
-public:
-    SkSpotShadowMaskFilterImpl(SkScalar occluderHeight, const SkPoint3& lightPos,
-                               SkScalar lightRadius, SkScalar spotAlpha, uint32_t flags);
-
-    // overrides from SkMaskFilter
-    SkMask::Format getFormat() const override;
-    bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
-                    SkIPoint* margin) const override;
-
-#if SK_SUPPORT_GPU
-    bool canFilterMaskGPU(const SkRRect& devRRect,
-                          const SkIRect& clipBounds,
-                          const SkMatrix& ctm,
-                          SkRect* maskRect) const override;
-    bool directFilterMaskGPU(GrContext*,
-                             GrRenderTargetContext* drawContext,
-                             GrPaint&&,
-                             const GrClip&,
-                             const SkMatrix& viewMatrix,
-                             const SkStrokeRec& strokeRec,
-                             const SkPath& path) const override;
-    bool directFilterRRectMaskGPU(GrContext*,
-                                  GrRenderTargetContext* drawContext,
-                                  GrPaint&&,
-                                  const GrClip&,
-                                  const SkMatrix& viewMatrix,
-                                  const SkStrokeRec& strokeRec,
-                                  const SkRRect& rrect,
-                                  const SkRRect& devRRect) const override;
-    sk_sp<GrTextureProxy> filterMaskGPU(GrContext*,
-                                        sk_sp<GrTextureProxy> srcProxy,
-                                        const SkMatrix& ctm,
-                                        const SkIRect& maskRect) const override;
-#endif
-
-    void computeFastBounds(const SkRect&, SkRect*) const override;
-
-    SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSpotShadowMaskFilterImpl)
-
-private:
-    SkScalar fOccluderHeight;
-    SkPoint3 fLightPos;
-    SkScalar fLightRadius;
-    SkScalar fSpotAlpha;
-    uint32_t fFlags;
-
-    SkSpotShadowMaskFilterImpl(SkReadBuffer&);
-    void flatten(SkWriteBuffer&) const override;
-
-    friend class SkSpotShadowMaskFilter;
-
-    typedef SkMaskFilter INHERITED;
-};
-
-sk_sp<SkMaskFilter> SkSpotShadowMaskFilter::Make(SkScalar occluderHeight, const SkPoint3& lightPos,
-                                                 SkScalar lightRadius, SkScalar spotAlpha,
-                                                 uint32_t flags) {
-    // add some param checks here for early exit
-
-    return sk_sp<SkMaskFilter>(new SkSpotShadowMaskFilterImpl(occluderHeight, lightPos,
-                                                              lightRadius, spotAlpha, flags));
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-SkSpotShadowMaskFilterImpl::SkSpotShadowMaskFilterImpl(SkScalar occluderHeight,
-                                                       const SkPoint3& lightPos,
-                                                       SkScalar lightRadius,
-                                                       SkScalar spotAlpha,
-                                                       uint32_t flags)
-    : fOccluderHeight(occluderHeight)
-    , fLightPos(lightPos)
-    , fLightRadius(lightRadius)
-    , fSpotAlpha(spotAlpha)
-    , fFlags(flags) {
-    SkASSERT(fOccluderHeight > 0);
-    SkASSERT(fLightPos.z() > 0 && fLightPos.z() > fOccluderHeight);
-    SkASSERT(fLightRadius > 0);
-    SkASSERT(fSpotAlpha >= 0);
-}
-
-SkMask::Format SkSpotShadowMaskFilterImpl::getFormat() const {
-    return SkMask::kA8_Format;
-}
-
-bool SkSpotShadowMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src,
-                                            const SkMatrix& matrix,
-                                            SkIPoint* margin) const {
-    // TODO something
-    return false;
-}
-
-void SkSpotShadowMaskFilterImpl::computeFastBounds(const SkRect& src, SkRect* dst) const {
-    // TODO compute based on ambient + spot data
-    dst->set(src.fLeft, src.fTop, src.fRight, src.fBottom);
-}
-
-sk_sp<SkFlattenable> SkSpotShadowMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
-    const SkScalar occluderHeight = buffer.readScalar();
-    const SkScalar lightX = buffer.readScalar();
-    const SkScalar lightY = buffer.readScalar();
-    const SkScalar lightZ = buffer.readScalar();
-    const SkPoint3 lightPos = SkPoint3::Make(lightX, lightY, lightZ);
-    const SkScalar lightRadius = buffer.readScalar();
-    const SkScalar spotAlpha = buffer.readScalar();
-    const uint32_t flags = buffer.readUInt();
-
-    return SkSpotShadowMaskFilter::Make(occluderHeight, lightPos, lightRadius,
-                                        spotAlpha, flags);
-}
-
-void SkSpotShadowMaskFilterImpl::flatten(SkWriteBuffer& buffer) const {
-    buffer.writeScalar(fOccluderHeight);
-    buffer.writeScalar(fLightPos.fX);
-    buffer.writeScalar(fLightPos.fY);
-    buffer.writeScalar(fLightPos.fZ);
-    buffer.writeScalar(fLightRadius);
-    buffer.writeScalar(fSpotAlpha);
-    buffer.writeUInt(fFlags);
-}
-
-#if SK_SUPPORT_GPU
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-bool SkSpotShadowMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect,
-                                                  const SkIRect& clipBounds,
-                                                  const SkMatrix& ctm,
-                                                  SkRect* maskRect) const {
-    // TODO
-    *maskRect = devRRect.rect();
-    return true;
-}
-
-bool SkSpotShadowMaskFilterImpl::directFilterMaskGPU(GrContext* context,
-                                                     GrRenderTargetContext* rtContext,
-                                                     GrPaint&& paint,
-                                                     const GrClip& clip,
-                                                     const SkMatrix& viewMatrix,
-                                                     const SkStrokeRec& strokeRec,
-                                                     const SkPath& path) const {
-    SkASSERT(rtContext);
-    // TODO: this will not handle local coordinates properly
-
-    SkRect rect;
-    SkRRect rrect;
-    if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(),
-                                                  rect.height())) {
-        rrect = SkRRect::MakeOval(rect);
-        return this->directFilterRRectMaskGPU(context, rtContext, std::move(paint), clip,
-                                              SkMatrix::I(), strokeRec, rrect, rrect);
-    } else if (path.isRect(&rect)) {
-        rrect = SkRRect::MakeRect(rect);
-        return this->directFilterRRectMaskGPU(context, rtContext, std::move(paint), clip,
-                                              SkMatrix::I(), strokeRec, rrect, rrect);
-    } else if (path.isRRect(&rrect) && rrect.isSimpleCircular()) {
-        return this->directFilterRRectMaskGPU(context, rtContext, std::move(paint), clip,
-                                              SkMatrix::I(), strokeRec, rrect, rrect);
-    }
-
-    return false;
-}
-
-bool SkSpotShadowMaskFilterImpl::directFilterRRectMaskGPU(GrContext*,
-                                                          GrRenderTargetContext* rtContext,
-                                                          GrPaint&& paint,
-                                                          const GrClip& clip,
-                                                          const SkMatrix& viewMatrix,
-                                                          const SkStrokeRec& strokeRec,
-                                                          const SkRRect& rrect,
-                                                          const SkRRect& devRRect) const {
-    // Fast path only supports filled rrects for now.
-    // TODO: fill and stroke as well.
-    if (SkStrokeRec::kFill_Style != strokeRec.getStyle()) {
-        return false;
-    }
-    // These should have been checked by the caller.
-    // Fast path only supports simple rrects with circular corners.
-    SkASSERT(devRRect.isRect() || devRRect.isCircle() ||
-        (devRRect.isSimple() && devRRect.allCornersCircular()));
-    // Fast path only supports uniform scale.
-    SkASSERT(viewMatrix.isSimilarity());
-    // Assume we have positive alpha
-    SkASSERT(fSpotAlpha > 0);
-
-    // 1/scale
-    SkScalar devToSrcScale = viewMatrix.isScaleTranslate() ?
-        SkScalarInvert(viewMatrix[SkMatrix::kMScaleX]) :
-        sk_float_rsqrt(viewMatrix[SkMatrix::kMScaleX] * viewMatrix[SkMatrix::kMScaleX] +
-                       viewMatrix[SkMatrix::kMSkewX] * viewMatrix[SkMatrix::kMSkewX]);
-
-    float zRatio = SkTPin(fOccluderHeight / (fLightPos.fZ - fOccluderHeight), 0.0f, 0.95f);
-
-    SkScalar devSpaceSpotBlur = 2.0f * fLightRadius * zRatio;
-    // handle scale of radius and pad due to CTM
-    const SkScalar srcSpaceSpotBlur = devSpaceSpotBlur * devToSrcScale;
-
-    // Compute the scale and translation for the spot shadow.
-    const SkScalar spotScale = fLightPos.fZ / (fLightPos.fZ - fOccluderHeight);
-    SkPoint spotOffset = SkPoint::Make(zRatio*(-fLightPos.fX), zRatio*(-fLightPos.fY));
-    // Adjust translate for the effect of the scale.
-    spotOffset.fX += spotScale*viewMatrix[SkMatrix::kMTransX];
-    spotOffset.fY += spotScale*viewMatrix[SkMatrix::kMTransY];
-    // This offset is in dev space, need to transform it into source space.
-    SkMatrix ctmInverse;
-    if (!viewMatrix.invert(&ctmInverse)) {
-        // Since the matrix is a similarity, this should never happen, but just in case...
-        SkDebugf("Matrix is degenerate. Will not render spot shadow!\n");
-        return true;
-    }
-    ctmInverse.mapPoints(&spotOffset, 1);
-
-    // Compute the transformed shadow rrect
-    SkRRect spotShadowRRect;
-    SkMatrix shadowTransform;
-    shadowTransform.setScaleTranslate(spotScale, spotScale, spotOffset.fX, spotOffset.fY);
-    rrect.transform(shadowTransform, &spotShadowRRect);
-    SkScalar spotRadius = spotShadowRRect.getSimpleRadii().fX;
-
-    // Compute the insetWidth
-    SkScalar blurOutset = 0.5f*srcSpaceSpotBlur;
-    SkScalar insetWidth = blurOutset;
-    if (fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag) {
-        // If transparent, just do a fill
-        insetWidth += spotShadowRRect.width();
-    } else {
-        // For shadows, instead of using a stroke we specify an inset from the penumbra
-        // border. We want to extend this inset area so that it meets up with the caster
-        // geometry. The inset geometry will by default already be inset by the blur width.
-        //
-        // We compare the min and max corners inset by the radius between the original
-        // rrect and the shadow rrect. The distance between the two plus the difference
-        // between the scaled radius and the original radius gives the distance from the
-        // transformed shadow shape to the original shape in that corner. The max
-        // of these gives the maximum distance we need to cover.
-        //
-        // Since we are outsetting by 1/2 the blur distance, we just add the maxOffset to
-        // that to get the full insetWidth.
-        SkScalar maxOffset;
-        if (rrect.isRect()) {
-            // Manhattan distance works better for rects
-            maxOffset = SkTMax(SkTMax(SkTAbs(spotShadowRRect.rect().fLeft -
-                                             rrect.rect().fLeft),
-                                      SkTAbs(spotShadowRRect.rect().fTop -
-                                             rrect.rect().fTop)),
-                               SkTMax(SkTAbs(spotShadowRRect.rect().fRight -
-                                             rrect.rect().fRight),
-                                      SkTAbs(spotShadowRRect.rect().fBottom -
-                                             rrect.rect().fBottom)));
-        } else {
-            SkScalar dr = spotRadius - rrect.getSimpleRadii().fX;
-            SkPoint upperLeftOffset = SkPoint::Make(spotShadowRRect.rect().fLeft -
-                                                    rrect.rect().fLeft + dr,
-                                                    spotShadowRRect.rect().fTop -
-                                                    rrect.rect().fTop + dr);
-            SkPoint lowerRightOffset = SkPoint::Make(spotShadowRRect.rect().fRight -
-                                                     rrect.rect().fRight - dr,
-                                                     spotShadowRRect.rect().fBottom -
-                                                     rrect.rect().fBottom - dr);
-            maxOffset = SkScalarSqrt(SkTMax(upperLeftOffset.lengthSqd(),
-                                            lowerRightOffset.lengthSqd())) + dr;
-        }
-        insetWidth += maxOffset;
-    }
-
-    // Outset the shadow rrect to the border of the penumbra
-    SkRect outsetRect = spotShadowRRect.rect().makeOutset(blurOutset, blurOutset);
-    if (spotShadowRRect.isOval()) {
-        spotShadowRRect = SkRRect::MakeOval(outsetRect);
-    } else {
-        SkScalar outsetRad = spotRadius + blurOutset;
-        spotShadowRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
-    }
-
-    GrColor4f color = paint.getColor4f();
-    paint.setColor4f(color.mulByScalar(fSpotAlpha));
-    rtContext->drawShadowRRect(clip, std::move(paint), viewMatrix, spotShadowRRect,
-                               devSpaceSpotBlur, insetWidth);
-
-    return true;
-}
-
-sk_sp<GrTextureProxy> SkSpotShadowMaskFilterImpl::filterMaskGPU(GrContext*,
-                                                                sk_sp<GrTextureProxy> srcProxy,
-                                                                const SkMatrix& ctm,
-                                                                const SkIRect& maskRect) const {
-    // This filter is generative and doesn't operate on pre-existing masks
-    return nullptr;
-}
-
-#endif
-
-#ifndef SK_IGNORE_TO_STRING
-void SkSpotShadowMaskFilterImpl::toString(SkString* str) const {
-    str->append("SkSpotShadowMaskFilterImpl: (");
-
-    str->append("occluderHeight: ");
-    str->appendScalar(fOccluderHeight);
-    str->append(" ");
-
-    str->append("lightPos: (");
-    str->appendScalar(fLightPos.fX);
-    str->append(", ");
-    str->appendScalar(fLightPos.fY);
-    str->append(", ");
-    str->appendScalar(fLightPos.fZ);
-    str->append(") ");
-
-    str->append("lightRadius: ");
-    str->appendScalar(fLightRadius);
-    str->append(" ");
-
-    str->append("spotAlpha: ");
-    str->appendScalar(fSpotAlpha);
-    str->append(" ");
-
-    str->append("flags: (");
-    if (fFlags) {
-        bool needSeparator = false;
-        SkAddFlagToString(str,
-                          SkToBool(fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag),
-                          "TransparentOccluder", &needSeparator);
-    } else {
-        str->append("None");
-    }
-    str->append("))");
-}
-#endif
-
-SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkSpotShadowMaskFilter)
-SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpotShadowMaskFilterImpl)
-SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
diff --git a/src/effects/shadows/SkSpotShadowMaskFilter.h b/src/effects/shadows/SkSpotShadowMaskFilter.h
deleted file mode 100644 (file)
index 5e1a4a9..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkSpotShadowMaskFilter_DEFINED
-#define SkSpotShadowMaskFilter_DEFINED
-
-#include "SkMaskFilter.h"
-#include "SkShadowFlags.h"
-
-/*
- * This filter implements a shadow for an occluding object
- * representing a displaced shadow from a point light.
- */
-class SK_API SkSpotShadowMaskFilter {
-public:
-    /** Create a shadow maskfilter.
-     *  @param occluderHeight Height of occluding object off of ground plane.
-     *  @param lightPos       Position of the light applied to this object.
-     *  @param lightRadius    Radius of the light (light is assumed to be spherical).
-     *  @param spotAlpha      Base opacity of the displaced spot shadow.
-     *  @param flags          Flags to use - defaults to none
-     *  @return The new shadow maskfilter
-     */
-    static sk_sp<SkMaskFilter> Make(SkScalar occluderHeight, const SkPoint3& lightPos,
-                                    SkScalar lightRadius, SkScalar spotAlpha,
-                                    uint32_t flags = SkShadowFlags::kNone_ShadowFlag);
-
-    SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
-
-private:
-    SkSpotShadowMaskFilter(); // can't be instantiated
-};
-#endif
index 1fcb0aa..8232f09 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "GrRenderTargetContext.h"
 #include "../private/GrAuditTrail.h"
+#include "../private/SkShadowFlags.h"
 #include "GrAppliedClip.h"
 #include "GrColor.h"
 #include "GrContextPriv.h"
@@ -20,6 +21,7 @@
 #include "GrRenderTargetPriv.h"
 #include "GrResourceProvider.h"
 #include "GrStencilAttachment.h"
+#include "SkDrawShadowRec.h"
 #include "SkLatticeIter.h"
 #include "SkMatrixPriv.h"
 #include "SkSurfacePriv.h"
@@ -977,32 +979,210 @@ void GrRenderTargetContext::drawRRect(const GrClip& origClip,
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void GrRenderTargetContext::drawShadowRRect(const GrClip& clip,
-                                            GrPaint&& paint,
-                                            const SkMatrix& viewMatrix,
-                                            const SkRRect& rrect,
-                                            SkScalar blurWidth,
-                                            SkScalar insetWidth,
-                                            SkScalar blurClamp) {
+static SkPoint3 map(const SkMatrix& m, const SkPoint3& pt) {
+    SkPoint3 result;
+    m.mapXY(pt.fX, pt.fY, (SkPoint*)&result.fX);
+    result.fZ = pt.fZ;
+    return result;
+}
+
+bool GrRenderTargetContext::drawFastShadow(const GrClip& clip,
+                                           GrPaint&& paint,
+                                           const SkMatrix& viewMatrix,
+                                           const SkPath& path,
+                                           const SkDrawShadowRec& rec) {
     ASSERT_SINGLE_OWNER
-    RETURN_IF_ABANDONED
+    if (this->drawingManager()->wasAbandoned()) {
+        return true;
+    }
     SkDEBUGCODE(this->validate();)
-    GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawShadowRRect");
+    GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawFastShadow");
+
+    // check z plane
+    bool tiltZPlane = SkToBool(!SkScalarNearlyZero(rec.fZPlaneParams.fX) ||
+                               !SkScalarNearlyZero(rec.fZPlaneParams.fY));
+    bool skipAnalytic = SkToBool(rec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
+    if (tiltZPlane || skipAnalytic || !viewMatrix.rectStaysRect() || !viewMatrix.isSimilarity()) {
+        return false;
+    }
+
+    SkRRect rrect;
+    SkRect rect;
+    // we can only handle rects, circles, and rrects with circular corners
+    bool isRRect = path.isRRect(&rrect) && rrect.isSimpleCircular() &&
+        rrect.radii(SkRRect::kUpperLeft_Corner).fX > SK_ScalarNearlyZero;
+    if (!isRRect &&
+        path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height()) &&
+        rect.width() > SK_ScalarNearlyZero) {
+        rrect.setOval(rect);
+        isRRect = true;
+    }
+    if (!isRRect && path.isRect(&rect)) {
+        rrect.setRect(rect);
+        isRRect = true;
+    }
+
+    if (!isRRect) {
+        return false;
+    }
+
     if (rrect.isEmpty()) {
-        return;
+        return true;
     }
 
     AutoCheckFlush acf(this->drawingManager());
-    // TODO: add instancing support?
 
-    std::unique_ptr<GrLegacyMeshDrawOp> op = GrShadowRRectOp::Make(paint.getColor(), viewMatrix,
-                                                                   rrect, blurWidth, insetWidth,
-                                                                   blurClamp);
-    if (op) {
-        GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
-        this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op));
-        return;
+    // transform light
+    SkPoint3 devLightPos = map(viewMatrix, rec.fLightPos);
+
+    // 1/scale
+    SkScalar devToSrcScale = viewMatrix.isScaleTranslate() ?
+        SkScalarInvert(viewMatrix[SkMatrix::kMScaleX]) :
+        sk_float_rsqrt(viewMatrix[SkMatrix::kMScaleX] * viewMatrix[SkMatrix::kMScaleX] +
+                       viewMatrix[SkMatrix::kMSkewX] * viewMatrix[SkMatrix::kMSkewX]);
+
+    SkScalar occluderHeight = rec.fZPlaneParams.fZ;
+    GrColor4f color = paint.getColor4f();
+    bool transparent = SkToBool(rec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
+
+    if (rec.fAmbientAlpha > 0) {
+        static constexpr float kHeightFactor = 1.0f / 128.0f;
+        static constexpr float kGeomFactor = 64.0f;
+
+        SkScalar devSpaceInsetWidth = occluderHeight * kHeightFactor * kGeomFactor;
+        const float umbraAlpha = (1.0f + SkTMax(occluderHeight * kHeightFactor, 0.0f));
+        const SkScalar devSpaceAmbientBlur = devSpaceInsetWidth * umbraAlpha;
+
+        // Outset the shadow rrect to the border of the penumbra
+        SkScalar ambientPathOutset = devSpaceInsetWidth * devToSrcScale;
+        SkRRect ambientRRect;
+        SkRect outsetRect = rrect.rect().makeOutset(ambientPathOutset, ambientPathOutset);
+        // If the rrect was an oval then its outset will also be one.
+        // We set it explicitly to avoid errors.
+        if (rrect.isOval()) {
+            ambientRRect = SkRRect::MakeOval(outsetRect);
+        } else {
+            SkScalar outsetRad = rrect.getSimpleRadii().fX + ambientPathOutset;
+            ambientRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
+        }
+
+        GrColor ambientColor = color.mulByScalar(rec.fAmbientAlpha).toGrColor();
+        if (transparent) {
+            // set a large inset to force a fill
+            devSpaceInsetWidth = ambientRRect.width();
+        }
+        // the fraction of the blur we want to apply is devSpaceInsetWidth/devSpaceAmbientBlur,
+        // which is just 1/umbraAlpha.
+        SkScalar blurClamp = SkScalarInvert(umbraAlpha);
+
+        std::unique_ptr<GrLegacyMeshDrawOp> op = GrShadowRRectOp::Make(ambientColor, viewMatrix,
+                                                                       ambientRRect,
+                                                                       devSpaceAmbientBlur,
+                                                                       devSpaceInsetWidth,
+                                                                       blurClamp);
+        if (op) {
+            GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
+            this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op));
+        }
     }
+
+    if (rec.fSpotAlpha > 0) {
+        float zRatio = SkTPin(occluderHeight / (devLightPos.fZ - occluderHeight), 0.0f, 0.95f);
+
+        SkScalar devSpaceSpotBlur = 2.0f * rec.fLightRadius * zRatio;
+        // handle scale of radius and pad due to CTM
+        const SkScalar srcSpaceSpotBlur = devSpaceSpotBlur * devToSrcScale;
+
+        // Compute the scale and translation for the spot shadow.
+        const SkScalar spotScale = devLightPos.fZ / (devLightPos.fZ - occluderHeight);
+        SkPoint spotOffset = SkPoint::Make(zRatio*(-devLightPos.fX), zRatio*(-devLightPos.fY));
+        // Adjust translate for the effect of the scale.
+        spotOffset.fX += spotScale*viewMatrix[SkMatrix::kMTransX];
+        spotOffset.fY += spotScale*viewMatrix[SkMatrix::kMTransY];
+        // This offset is in dev space, need to transform it into source space.
+        SkMatrix ctmInverse;
+        if (viewMatrix.invert(&ctmInverse)) {
+            ctmInverse.mapPoints(&spotOffset, 1);
+        } else {
+            // Since the matrix is a similarity, this should never happen, but just in case...
+            SkDebugf("Matrix is degenerate. Will not render spot shadow correctly!\n");
+            SkASSERT(false);
+        }
+
+        // Compute the transformed shadow rrect
+        SkRRect spotShadowRRect;
+        SkMatrix shadowTransform;
+        shadowTransform.setScaleTranslate(spotScale, spotScale, spotOffset.fX, spotOffset.fY);
+        rrect.transform(shadowTransform, &spotShadowRRect);
+        SkScalar spotRadius = spotShadowRRect.getSimpleRadii().fX;
+
+        // Compute the insetWidth
+        SkScalar blurOutset = 0.5f*srcSpaceSpotBlur;
+        SkScalar insetWidth = blurOutset;
+        if (transparent) {
+            // If transparent, just do a fill
+            insetWidth += spotShadowRRect.width();
+        } else {
+            // For shadows, instead of using a stroke we specify an inset from the penumbra
+            // border. We want to extend this inset area so that it meets up with the caster
+            // geometry. The inset geometry will by default already be inset by the blur width.
+            //
+            // We compare the min and max corners inset by the radius between the original
+            // rrect and the shadow rrect. The distance between the two plus the difference
+            // between the scaled radius and the original radius gives the distance from the
+            // transformed shadow shape to the original shape in that corner. The max
+            // of these gives the maximum distance we need to cover.
+            //
+            // Since we are outsetting by 1/2 the blur distance, we just add the maxOffset to
+            // that to get the full insetWidth.
+            SkScalar maxOffset;
+            if (rrect.isRect()) {
+                // Manhattan distance works better for rects
+                maxOffset = SkTMax(SkTMax(SkTAbs(spotShadowRRect.rect().fLeft -
+                                                 rrect.rect().fLeft),
+                                          SkTAbs(spotShadowRRect.rect().fTop -
+                                                 rrect.rect().fTop)),
+                                   SkTMax(SkTAbs(spotShadowRRect.rect().fRight -
+                                                 rrect.rect().fRight),
+                                          SkTAbs(spotShadowRRect.rect().fBottom -
+                                                 rrect.rect().fBottom)));
+            } else {
+                SkScalar dr = spotRadius - rrect.getSimpleRadii().fX;
+                SkPoint upperLeftOffset = SkPoint::Make(spotShadowRRect.rect().fLeft -
+                                                        rrect.rect().fLeft + dr,
+                                                        spotShadowRRect.rect().fTop -
+                                                        rrect.rect().fTop + dr);
+                SkPoint lowerRightOffset = SkPoint::Make(spotShadowRRect.rect().fRight -
+                                                         rrect.rect().fRight - dr,
+                                                         spotShadowRRect.rect().fBottom -
+                                                         rrect.rect().fBottom - dr);
+                maxOffset = SkScalarSqrt(SkTMax(upperLeftOffset.lengthSqd(),
+                                                lowerRightOffset.lengthSqd())) + dr;
+            }
+            insetWidth += maxOffset;
+        }
+
+        // Outset the shadow rrect to the border of the penumbra
+        SkRect outsetRect = spotShadowRRect.rect().makeOutset(blurOutset, blurOutset);
+        if (spotShadowRRect.isOval()) {
+            spotShadowRRect = SkRRect::MakeOval(outsetRect);
+        } else {
+            SkScalar outsetRad = spotRadius + blurOutset;
+            spotShadowRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
+        }
+
+        GrColor spotColor = color.mulByScalar(rec.fSpotAlpha).toGrColor();
+        std::unique_ptr<GrLegacyMeshDrawOp> op = GrShadowRRectOp::Make(spotColor, viewMatrix,
+                                                                       spotShadowRRect,
+                                                                       devSpaceSpotBlur,
+                                                                       insetWidth);
+        if (op) {
+            GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
+            this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op));
+        }
+    }
+
+    return true;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
index 0f9e530..fe20a6d 100644 (file)
@@ -32,6 +32,7 @@ class GrStyle;
 class GrTextureProxy;
 struct GrUserStencilSettings;
 class SkDrawFilter;
+struct SkDrawShadowRec;
 struct SkIPoint;
 struct SkIRect;
 class SkLatticeIter;
@@ -153,24 +154,19 @@ public:
                    const GrStyle& style);
 
     /**
-     * Draw a roundrect using a paint and a shadow shader. This is separate from drawRRect
-     * because it uses different underlying geometry and GeometryProcessor
+     * Use a fast method to render the ambient and spot shadows for a path.
+     * Will return false if not possible for the given path.
      *
      * @param paint        describes how to color pixels.
      * @param viewMatrix   transformation matrix
-     * @param rrect        the roundrect to draw
-     * @param blurWidth    amount of shadow blur to apply (in device space)
-     * @param insetWidth   minimum amount to inset from the rrect edge (in local space).
-     *                     We may inset more depending on the blur radius and geometry.
-     * @param blurClamp    Optional parameter used to indicate fraction of blur to actually apply
+     * @param path         the path to shadow
+     * @param rec          parameters for shadow rendering
      */
-    void drawShadowRRect(const GrClip&,
-                         GrPaint&&,
-                         const SkMatrix& viewMatrix,
-                         const SkRRect& rrect,
-                         SkScalar blurRadius,
-                         SkScalar insetWidth,
-                         SkScalar blurClamp = 1);
+    bool drawFastShadow(const GrClip&,
+                        GrPaint&&,
+                        const SkMatrix& viewMatrix,
+                        const SkPath& path,
+                        const SkDrawShadowRec& rec);
 
     /**
      * Shortcut for filling a SkPath consisting of nested rrects using a paint. The result is
index c90ad28..87a4f99 100644 (file)
@@ -47,6 +47,7 @@
 #include "effects/GrBicubicEffect.h"
 #include "effects/GrSimpleTextureEffect.h"
 #include "effects/GrTextureDomain.h"
+#include "../private/SkShadowFlags.h"
 #include "text/GrTextUtils.h"
 
 #if SK_SUPPORT_GPU
@@ -1661,6 +1662,29 @@ void SkGpuDevice::drawVertices(const SkVertices* vertices, SkBlendMode mode,
 
 ///////////////////////////////////////////////////////////////////////////////
 
+void SkGpuDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
+
+    ASSERT_SINGLE_OWNER
+    CHECK_SHOULD_DRAW();
+    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawShadow", fContext.get());
+
+    SkPaint p;
+    p.setColor(rec.fColor);
+    GrPaint grPaint;
+    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), p, this->ctm(),
+                          &grPaint)) {
+        return;
+    }
+
+    if (!fRenderTargetContext->drawFastShadow(this->clip(), std::move(grPaint),
+                                              this->ctm(), path, rec)) {
+        // failed to find an accelerated case
+        this->INHERITED::drawShadow(path, rec);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 void SkGpuDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
                             const SkRect texRect[], const SkColor colors[], int count,
                             SkBlendMode mode, const SkPaint& paint) {
index f0ab230..16a1eee 100644 (file)
@@ -22,8 +22,6 @@
 #if SK_SUPPORT_GPU
 #include "GrShape.h"
 #include "effects/GrBlurredEdgeFragmentProcessor.h"
-#include "../../src/effects/shadows/SkAmbientShadowMaskFilter.h"
-#include "../../src/effects/shadows/SkSpotShadowMaskFilter.h"
 #endif
 
 /**
@@ -516,68 +514,6 @@ static SkPoint3 map(const SkMatrix& m, const SkPoint3& pt) {
     return result;
 }
 
-#if SK_SUPPORT_GPU
-#include "SkGpuDevice.h"
-void SkGpuDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
-    // check z plane
-    bool tiltZPlane = tilted(rec.fZPlaneParams);
-    bool skipAnalytic = SkToBool(rec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
-
-    const SkMatrix& ctm = this->ctm();
-
-    if (!tiltZPlane && !skipAnalytic && ctm.rectStaysRect() && ctm.isSimilarity()) {
-        SkPoint3 devLightPos = map(ctm, rec.fLightPos);
-
-        const SkScalar occluderZ = rec.fZPlaneParams.fZ;
-        SkPaint ambientPaint, spotPaint;
-        ambientPaint.setColor(rec.fColor);
-        spotPaint.setColor(rec.fColor);
-        if (rec.fAmbientAlpha > 0) {
-            ambientPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderZ, rec.fAmbientAlpha,
-                                                                       rec.fFlags));
-        }
-        if (rec.fSpotAlpha > 0) {
-            spotPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderZ, devLightPos,
-                                                                 rec.fLightRadius, rec.fSpotAlpha,
-                                                                 rec.fFlags));
-        }
-
-        SkRect rect;
-        SkRRect rrect;
-        if (path.isRect(&rect)) {
-            if (rec.fAmbientAlpha > 0) {
-                this->drawRect(rect, ambientPaint);
-            }
-            if (rec.fSpotAlpha > 0) {
-                this->drawRect(rect, spotPaint);
-            }
-            return;
-        } else if (path.isRRect(&rrect) && rrect.isSimpleCircular() &&
-                   rrect.radii(SkRRect::kUpperLeft_Corner).fX > SK_ScalarNearlyZero) {
-            if (rec.fAmbientAlpha > 0) {
-                this->drawRRect(rrect, ambientPaint);
-            }
-            if (rec.fSpotAlpha > 0) {
-                this->drawRRect(rrect, spotPaint);
-            }
-            return;
-        } else if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height()) &&
-                   rect.width() > SK_ScalarNearlyZero) {
-            if (rec.fAmbientAlpha > 0) {
-                this->drawOval(rect, ambientPaint);
-            }
-            if (rec.fSpotAlpha > 0) {
-                this->drawOval(rect, spotPaint);
-            }
-            return;
-        }
-    }
-
-    // failed to find an accelerated case
-    this->INHERITED::drawShadow(path, rec);
-}
-#endif
-
 static SkColor compute_render_color(SkColor color, float alpha) {
     return SkColorSetARGB(alpha*SkColorGetA(color), SkColorGetR(color),
                           SkColorGetG(color), SkColorGetB(color));