aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Jim Van Verth <jvanverth@google.com>2017-05-18 15:06:54 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-18 19:45:45 +0000
commit3af1af9e979552cf2e3b22feb1de5aeba810fc4e (patch)
tree20bfe9c69557b91e42d77920d2625a0eaa3efc8d
parent7f1ce29c9bb9be8b2d8dbf9a99f14f74d5dc6d80 (diff)
Remove ambient and spot mask filters.
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>
-rw-r--r--gn/effects.gni5
-rw-r--r--include/utils/SkShadowUtils.h38
-rw-r--r--src/effects/shadows/SkAmbientShadowMaskFilter.cpp271
-rw-r--r--src/effects/shadows/SkAmbientShadowMaskFilter.h33
-rw-r--r--src/effects/shadows/SkSpotShadowMaskFilter.cpp356
-rw-r--r--src/effects/shadows/SkSpotShadowMaskFilter.h37
-rw-r--r--src/gpu/GrRenderTargetContext.cpp216
-rw-r--r--src/gpu/GrRenderTargetContext.h24
-rw-r--r--src/gpu/SkGpuDevice.cpp24
-rw-r--r--src/utils/SkShadowUtils.cpp64
10 files changed, 233 insertions, 835 deletions
diff --git a/gn/effects.gni b/gn/effects.gni
index df8e75b144..278925ba85 100644
--- a/gn/effects.gni
+++ b/gn/effects.gni
@@ -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",
diff --git a/include/utils/SkShadowUtils.h b/include/utils/SkShadowUtils.h
index 2385a48075..838a12bba8 100644
--- a/include/utils/SkShadowUtils.h
+++ b/include/utils/SkShadowUtils.h
@@ -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
index 66218cd96f..0000000000
--- a/src/effects/shadows/SkAmbientShadowMaskFilter.cpp
+++ /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
index cd77b106a4..0000000000
--- a/src/effects/shadows/SkAmbientShadowMaskFilter.h
+++ /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
index a51aa56632..0000000000
--- a/src/effects/shadows/SkSpotShadowMaskFilter.cpp
+++ /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
index 5e1a4a9ec9..0000000000
--- a/src/effects/shadows/SkSpotShadowMaskFilter.h
+++ /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
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 1fcb0aadc1..8232f09303 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -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;
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index 0f9e530b83..fe20a6dbcc 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -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
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index c90ad28129..87a4f99c7a 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -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) {
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index f0ab230acc..16a1eee9c1 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -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));