aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkCanvas.h4
-rw-r--r--include/utils/SkNWayCanvas.h1
-rw-r--r--src/core/SkCanvas.cpp15
-rw-r--r--src/core/SkColorSpaceXformCanvas.cpp7
-rw-r--r--src/core/SkDevice.h3
-rw-r--r--src/core/SkDrawShadowRec.h23
-rw-r--r--src/core/SkLiteDL.cpp17
-rw-r--r--src/core/SkLiteDL.h1
-rw-r--r--src/core/SkLiteRecorder.cpp3
-rw-r--r--src/core/SkLiteRecorder.h1
-rw-r--r--src/core/SkRecordDraw.cpp5
-rw-r--r--src/core/SkRecorder.cpp4
-rw-r--r--src/core/SkRecorder.h1
-rw-r--r--src/core/SkRecords.h5
-rw-r--r--src/gpu/SkGpuDevice.h1
-rw-r--r--src/utils/SkNWayCanvas.cpp7
-rw-r--r--src/utils/SkShadowUtils.cpp181
17 files changed, 200 insertions, 79 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index e03b4f3daf..8ab281814e 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -24,6 +24,7 @@ class SkData;
class SkDraw;
class SkDrawable;
class SkDrawFilter;
+struct SkDrawShadowRec;
class SkImage;
class SkImageFilter;
class SkLights;
@@ -1237,6 +1238,8 @@ public:
*/
void temporary_internal_getRgnClip(SkRegion* region);
+ void private_draw_shadow_rec(const SkPath&, const SkDrawShadowRec&);
+
protected:
// default impl defers to getDevice()->newSurface(info)
virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props);
@@ -1331,6 +1334,7 @@ protected:
const SkPaint* paint);
virtual void onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
const SkRect& dst, const SkPaint* paint);
+ virtual void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&);
enum ClipEdgeStyle {
kHard_ClipEdgeStyle,
diff --git a/include/utils/SkNWayCanvas.h b/include/utils/SkNWayCanvas.h
index ba0745e420..7701d50e26 100644
--- a/include/utils/SkNWayCanvas.h
+++ b/include/utils/SkNWayCanvas.h
@@ -71,6 +71,7 @@ protected:
void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
const SkPaint*) override;
void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
+ void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 10e2181aff..afc1203e6b 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1909,6 +1909,21 @@ void SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
}
}
+void SkCanvas::private_draw_shadow_rec(const SkPath& path, const SkDrawShadowRec& rec) {
+ this->onDrawShadowRec(path, rec);
+}
+
+void SkCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
+ SkPaint paint;
+ const SkRect& pathBounds = path.getBounds();
+
+ LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, &pathBounds)
+ while (iter.next()) {
+ iter.fDevice->drawShadow(path, rec);
+ }
+ LOOPER_END
+}
+
//////////////////////////////////////////////////////////////////////////////
// These are the virtual drawing methods
//////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkColorSpaceXformCanvas.cpp b/src/core/SkColorSpaceXformCanvas.cpp
index 65297a1801..530552862d 100644
--- a/src/core/SkColorSpaceXformCanvas.cpp
+++ b/src/core/SkColorSpaceXformCanvas.cpp
@@ -8,6 +8,7 @@
#include "SkColorFilter.h"
#include "SkColorSpaceXformCanvas.h"
#include "SkColorSpaceXformer.h"
+#include "SkDrawShadowRec.h"
#include "SkGradientShader.h"
#include "SkImageFilter.h"
#include "SkImagePriv.h"
@@ -217,7 +218,11 @@ public:
fTarget->drawImageLattice(fXformer->apply(bitmap).get(), lattice, dst,
MaybePaint(paint, fXformer.get()));
}
-
+ void onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) override {
+ SkDrawShadowRec newRec(rec);
+ newRec.fColor = fXformer->apply(rec.fColor);
+ fTarget->private_draw_shadow_rec(path, newRec);
+ }
void onDrawPicture(const SkPicture* pic,
const SkMatrix* matrix,
const SkPaint* paint) override {
diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h
index 17ccfdd198..17ea6f71f7 100644
--- a/src/core/SkDevice.h
+++ b/src/core/SkDevice.h
@@ -15,6 +15,7 @@
class SkBitmap;
class SkDrawFilter;
+struct SkDrawShadowRec;
class SkImageFilterCache;
struct SkIRect;
class SkMatrix;
@@ -234,6 +235,8 @@ protected:
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint& paint) = 0;
virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) = 0;
+ virtual void drawShadow(const SkPath&, const SkDrawShadowRec&);
+
// default implementation unrolls the blob runs.
virtual void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
const SkPaint& paint, SkDrawFilter* drawFilter);
diff --git a/src/core/SkDrawShadowRec.h b/src/core/SkDrawShadowRec.h
new file mode 100644
index 0000000000..19199c0cad
--- /dev/null
+++ b/src/core/SkDrawShadowRec.h
@@ -0,0 +1,23 @@
+/*
+ * 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 SkDrawShadowRec_DEFINED
+#define SkDrawShadowRec_DEFINED
+
+#include "SkPath.h"
+
+struct SkDrawShadowRec {
+ SkPoint3 fZPlaneParams;
+ SkPoint3 fLightPos;
+ SkScalar fLightRadius;
+ float fAmbientAlpha;
+ float fSpotAlpha;
+ SkColor fColor;
+ uint32_t fFlags;
+};
+
+#endif
diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp
index b3149a7d42..f1101b1be2 100644
--- a/src/core/SkLiteDL.cpp
+++ b/src/core/SkLiteDL.cpp
@@ -8,6 +8,7 @@
#include "SkCanvas.h"
#include "SkData.h"
#include "SkDrawFilter.h"
+#include "SkDrawShadowRec.h"
#include "SkImage.h"
#include "SkImageFilter.h"
#include "SkLiteDL.h"
@@ -55,7 +56,7 @@ namespace {
M(DrawImage) M(DrawImageNine) M(DrawImageRect) M(DrawImageLattice) \
M(DrawText) M(DrawPosText) M(DrawPosTextH) \
M(DrawTextOnPath) M(DrawTextRSXform) M(DrawTextBlob) \
- M(DrawPatch) M(DrawPoints) M(DrawVertices) M(DrawAtlas)
+ M(DrawPatch) M(DrawPoints) M(DrawVertices) M(DrawAtlas) M(DrawShadowRec)
#define M(T) T,
enum class Type : uint8_t { TYPES(M) };
@@ -477,6 +478,17 @@ namespace {
maybe_unset(cull), &paint);
}
};
+ struct DrawShadowRec final : Op {
+ static const auto kType = Type::DrawShadowRec;
+ DrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec)
+ : fPath(path), fRec(rec)
+ {}
+ SkPath fPath;
+ SkDrawShadowRec fRec;
+ void draw(SkCanvas* c, const SkMatrix&) const {
+ c->private_draw_shadow_rec(fPath, fRec);
+ }
+ };
}
template <typename T, typename... Args>
@@ -662,6 +674,9 @@ void SkLiteDL::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], const S
texs, count,
colors, colors ? count : 0);
}
+void SkLiteDL::drawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
+ this->push<DrawShadowRec>(0, path, rec);
+}
typedef void(*draw_fn)(const void*, SkCanvas*, const SkMatrix&);
typedef void(*void_fn)(const void*);
diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h
index c5df350957..31ef38e6bf 100644
--- a/src/core/SkLiteDL.h
+++ b/src/core/SkLiteDL.h
@@ -77,6 +77,7 @@ public:
void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&);
void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
SkBlendMode, const SkRect*, const SkPaint*);
+ void drawShadowRec(const SkPath&, const SkDrawShadowRec&);
private:
template <typename T, typename... Args>
diff --git a/src/core/SkLiteRecorder.cpp b/src/core/SkLiteRecorder.cpp
index 5affb3d4ab..dbee48e1bd 100644
--- a/src/core/SkLiteRecorder.cpp
+++ b/src/core/SkLiteRecorder.cpp
@@ -194,3 +194,6 @@ void SkLiteRecorder::onDrawAtlas(const SkImage* atlas,
const SkPaint* paint) {
fDL->drawAtlas(atlas, xforms, texs, colors, count, bmode, cull, paint);
}
+void SkLiteRecorder::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
+ fDL->drawShadowRec(path, rec);
+}
diff --git a/src/core/SkLiteRecorder.h b/src/core/SkLiteRecorder.h
index 3c156af721..4d49eb5336 100644
--- a/src/core/SkLiteRecorder.h
+++ b/src/core/SkLiteRecorder.h
@@ -77,6 +77,7 @@ public:
void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
int, SkBlendMode, const SkRect*, const SkPaint*) override;
+ void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
private:
typedef SkNoDrawCanvas INHERITED;
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index e668cc874c..953e874854 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -125,6 +125,7 @@ DRAW(DrawTextRSXform, drawTextRSXform(r.text, r.byteLength, r.xforms, r.cull, r.
DRAW(DrawAtlas, drawAtlas(r.atlas.get(),
r.xforms, r.texs, r.colors, r.count, r.mode, r.cull, r.paint));
DRAW(DrawVertices, drawVertices(r.vertices, r.bmode, r.paint));
+DRAW(DrawShadowRec, private_draw_shadow_rec(r.path, r.rec));
DRAW(DrawAnnotation, drawAnnotation(r.rect, r.key.c_str(), r.value.get()));
#undef DRAW
@@ -455,6 +456,10 @@ private:
}
}
+ Bounds bounds(const DrawShadowRec& op) const {
+ return this->adjustAndMap(op.path.getBounds(), nullptr);
+ }
+
Bounds bounds(const DrawPicture& op) const {
SkRect dst = op.picture->cullRect();
op.matrix.mapRect(&dst);
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index 64d613df96..1eeef532e6 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -338,6 +338,10 @@ void SkRecorder::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], cons
this->copy(cull));
}
+void SkRecorder::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
+ APPEND(DrawShadowRec, path, rec);
+}
+
void SkRecorder::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
APPEND(DrawAnnotation, rect, SkString(key), sk_ref_sp(value));
}
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index 5344934665..04e75edd26 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -121,6 +121,7 @@ public:
void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
int count, SkBlendMode, const SkRect* cull, const SkPaint*) override;
+ void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
void onClipRect(const SkRect& rect, SkClipOp, ClipEdgeStyle) override;
void onClipRRect(const SkRRect& rrect, SkClipOp, ClipEdgeStyle) override;
diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h
index 6af4aad3f5..a63ef1c6a5 100644
--- a/src/core/SkRecords.h
+++ b/src/core/SkRecords.h
@@ -11,6 +11,7 @@
#include "SkData.h"
#include "SkCanvas.h"
#include "SkDrawable.h"
+#include "SkDrawShadowRec.h"
#include "SkImage.h"
#include "SkImageFilter.h"
#include "SkMatrix.h"
@@ -80,6 +81,7 @@ namespace SkRecords {
M(DrawTextBlob) \
M(DrawAtlas) \
M(DrawVertices) \
+ M(DrawShadowRec) \
M(DrawAnnotation)
// Defines SkRecords::Type, an enum of all record types.
@@ -345,6 +347,9 @@ RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag,
SkPaint paint;
sk_sp<SkVertices> vertices;
SkBlendMode bmode);
+RECORD(DrawShadowRec, kDraw_Tag,
+ SkPath path;
+ SkDrawShadowRec rec);
RECORD(DrawAnnotation, 0, // TODO: kDraw_Tag, skia:5548
SkRect rect;
SkString key;
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index 340f39a072..0b60a96516 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -92,6 +92,7 @@ public:
void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
const SkPaint& paint, SkDrawFilter* drawFilter) override;
void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
+ void drawShadow(const SkPath&, const SkDrawShadowRec&) override;
void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
const SkColor[], int count, SkBlendMode, const SkPaint&) override;
void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp
index 4f6ad46d85..208f3b4719 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -299,6 +299,13 @@ void SkNWayCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4]
}
}
+void SkNWayCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
+ Iter iter(fList);
+ while (iter.next()) {
+ iter->private_draw_shadow_rec(path, rec);
+ }
+}
+
void SkNWayCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* data) {
Iter iter(fList);
while (iter.next()) {
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index 806c98e68b..f0ab230acc 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -9,6 +9,8 @@
#include "SkCanvas.h"
#include "SkColorFilter.h"
#include "SkColorPriv.h"
+#include "SkDevice.h"
+#include "SkDrawShadowRec.h"
#include "SkPath.h"
#include "SkPM4f.h"
#include "SkRandom.h"
@@ -20,9 +22,9 @@
#if SK_SUPPORT_GPU
#include "GrShape.h"
#include "effects/GrBlurredEdgeFragmentProcessor.h"
-#endif
#include "../../src/effects/shadows/SkAmbientShadowMaskFilter.h"
#include "../../src/effects/shadows/SkSpotShadowMaskFilter.h"
+#endif
/**
* Gaussian color filter -- produces a Gaussian ramp based on the color's B value,
@@ -444,7 +446,9 @@ static void* kNamespace;
* they are first found in SkResourceCache.
*/
template <typename FACTORY>
-void draw_shadow(const FACTORY& factory, SkCanvas* canvas, ShadowedPath& path, SkColor color) {
+ void draw_shadow(const FACTORY& factory,
+ std::function<void(const SkVertices*, SkBlendMode, const SkPaint&,
+ SkScalar tx, SkScalar ty)> drawProc, ShadowedPath& path, SkColor color) {
FindContext<FACTORY> context(&path.viewMatrix(), &factory);
SkResourceCache::Key* key = nullptr;
@@ -496,82 +500,83 @@ void draw_shadow(const FACTORY& factory, SkCanvas* canvas, ShadowedPath& path, S
paint.setColorFilter(SkColorFilter::MakeComposeFilter(
SkColorFilter::MakeModeFilter(color, SkBlendMode::kModulate),
SkGaussianColorFilter::Make()));
- if (translate->fX || translate->fY) {
- canvas->save();
- canvas->translate(translate->fX, translate->fY);
- }
- canvas->drawVertices(vertices, SkBlendMode::kModulate, paint);
- if (translate->fX || translate->fY) {
- canvas->restore();
- }
+
+ drawProc(vertices.get(), SkBlendMode::kModulate, paint, translate->fX, translate->fY);
}
}
-static bool draw_analytic_shadows(SkCanvas* canvas, const SkPath& path, SkScalar occluderZ,
- const SkPoint3& devLightPos, SkScalar lightRadius,
- SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
- uint32_t flags) {
- // only supported in GPU code
- if (!canvas->getGrContext()) {
- return false;
- }
+static bool tilted(const SkPoint3& zPlaneParams) {
+ return !SkScalarNearlyZero(zPlaneParams.fX) || !SkScalarNearlyZero(zPlaneParams.fY);
+}
+
+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;
+}
+
+#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();
- SkRect rect;
- SkRRect rrect;
- const SkMatrix& ctm = canvas->getTotalMatrix();
- if (ctm.rectStaysRect() && ctm.isSimilarity()) {
+ 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)) {
- SkPaint newPaint;
- newPaint.setColor(color);
- if (ambientAlpha > 0) {
- newPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderZ,
- ambientAlpha, flags));
- canvas->drawRect(rect, newPaint);
+ if (rec.fAmbientAlpha > 0) {
+ this->drawRect(rect, ambientPaint);
}
- if (spotAlpha > 0) {
- newPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderZ, devLightPos,
- lightRadius, spotAlpha,
- flags));
- canvas->drawRect(rect, newPaint);
+ if (rec.fSpotAlpha > 0) {
+ this->drawRect(rect, spotPaint);
}
- return true;
+ return;
} else if (path.isRRect(&rrect) && rrect.isSimpleCircular() &&
rrect.radii(SkRRect::kUpperLeft_Corner).fX > SK_ScalarNearlyZero) {
- SkPaint newPaint;
- newPaint.setColor(color);
- if (ambientAlpha > 0) {
- newPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderZ,
- ambientAlpha, flags));
- canvas->drawRRect(rrect, newPaint);
+ if (rec.fAmbientAlpha > 0) {
+ this->drawRRect(rrect, ambientPaint);
}
- if (spotAlpha > 0) {
- newPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderZ, devLightPos,
- lightRadius, spotAlpha,
- flags));
- canvas->drawRRect(rrect, newPaint);
+ if (rec.fSpotAlpha > 0) {
+ this->drawRRect(rrect, spotPaint);
}
- return true;
+ return;
} else if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height()) &&
rect.width() > SK_ScalarNearlyZero) {
- SkPaint newPaint;
- newPaint.setColor(color);
- if (ambientAlpha > 0) {
- newPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderZ,
- ambientAlpha, flags));
- canvas->drawOval(rect, newPaint);
+ if (rec.fAmbientAlpha > 0) {
+ this->drawOval(rect, ambientPaint);
}
- if (spotAlpha > 0) {
- newPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderZ, devLightPos,
- lightRadius, spotAlpha,
- flags));
- canvas->drawOval(rect, newPaint);
+ if (rec.fSpotAlpha > 0) {
+ this->drawOval(rect, spotPaint);
}
- return true;
+ return;
}
}
- return false;
+ // 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),
@@ -583,26 +588,47 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
const SkPoint3& devLightPos, SkScalar lightRadius,
SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
uint32_t flags) {
- // check z plane
- bool tiltZPlane = !SkScalarNearlyZero(zPlaneParams.fX) || !SkScalarNearlyZero(zPlaneParams.fY);
-
- // try fast paths
- bool skipAnalytic = SkToBool(flags & SkShadowFlags::kGeometricOnly_ShadowFlag) || tiltZPlane;
- if (!skipAnalytic && draw_analytic_shadows(canvas, path, zPlaneParams.fZ, devLightPos,
- lightRadius, ambientAlpha, spotAlpha, color,
- flags)) {
+ SkMatrix inverse;
+ if (!canvas->getTotalMatrix().invert(&inverse)) {
return;
}
+ SkPoint pt = inverse.mapXY(devLightPos.fX, devLightPos.fY);
+
+ SkDrawShadowRec rec;
+ rec.fZPlaneParams = zPlaneParams;
+ rec.fLightPos = { pt.fX, pt.fY, devLightPos.fZ };
+ rec.fLightRadius = lightRadius;
+ rec.fAmbientAlpha = SkScalarToFloat(ambientAlpha);
+ rec.fSpotAlpha = SkScalarToFloat(spotAlpha);
+ rec.fColor = color;
+ rec.fFlags = flags;
+
+ canvas->private_draw_shadow_rec(path, rec);
+}
+
+void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
+ auto drawVertsProc = [this](const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint,
+ SkScalar tx, SkScalar ty) {
+ SkAutoDeviceCTMRestore adr(this, SkMatrix::Concat(this->ctm(),
+ SkMatrix::MakeTrans(tx, ty)));
+ this->drawVertices(vertices, mode, paint);
+ };
- SkAutoCanvasRestore acr(canvas, true);
- SkMatrix viewMatrix = canvas->getTotalMatrix();
- canvas->resetMatrix();
+ SkMatrix viewMatrix = this->ctm();
+ SkAutoDeviceCTMRestore adr(this, SkMatrix::I());
ShadowedPath shadowedPath(&path, &viewMatrix);
- bool transparent = SkToBool(flags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
+ bool tiltZPlane = tilted(rec.fZPlaneParams);
+ bool transparent = SkToBool(rec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
bool uncached = tiltZPlane || path.isVolatile();
+ SkColor color = rec.fColor;
+ SkPoint3 zPlaneParams = rec.fZPlaneParams;
+ SkPoint3 devLightPos = map(viewMatrix, rec.fLightPos);
+ float lightRadius = rec.fLightRadius;
+
+ float ambientAlpha = rec.fAmbientAlpha;
if (ambientAlpha > 0) {
ambientAlpha = SkTMin(ambientAlpha, 1.f);
if (uncached) {
@@ -614,19 +640,20 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
// Run the vertex color through a GaussianColorFilter and then modulate the grayscale
// result of that against our 'color' param.
paint.setColorFilter(SkColorFilter::MakeComposeFilter(
- SkColorFilter::MakeModeFilter(renderColor, SkBlendMode::kModulate),
- SkGaussianColorFilter::Make()));
- canvas->drawVertices(vertices, SkBlendMode::kModulate, paint);
+ SkColorFilter::MakeModeFilter(renderColor, SkBlendMode::kModulate),
+ SkGaussianColorFilter::Make()));
+ this->drawVertices(vertices.get(), SkBlendMode::kModulate, paint);
} else {
AmbientVerticesFactory factory;
factory.fOccluderHeight = zPlaneParams.fZ;
factory.fTransparent = transparent;
SkColor renderColor = compute_render_color(color, ambientAlpha);
- draw_shadow(factory, canvas, shadowedPath, renderColor);
+ draw_shadow(factory, drawVertsProc, shadowedPath, renderColor);
}
}
+ float spotAlpha = rec.fSpotAlpha;
if (spotAlpha > 0) {
spotAlpha = SkTMin(spotAlpha, 1.f);
if (uncached) {
@@ -641,7 +668,7 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
paint.setColorFilter(SkColorFilter::MakeComposeFilter(
SkColorFilter::MakeModeFilter(renderColor, SkBlendMode::kModulate),
SkGaussianColorFilter::Make()));
- canvas->drawVertices(vertices, SkBlendMode::kModulate, paint);
+ this->drawVertices(vertices.get(), SkBlendMode::kModulate, paint);
} else {
SpotVerticesFactory factory;
SkScalar occluderHeight = zPlaneParams.fZ;
@@ -690,7 +717,7 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
}
#endif
SkColor renderColor = compute_render_color(color, spotAlpha);
- draw_shadow(factory, canvas, shadowedPath, renderColor);
+ draw_shadow(factory, drawVertsProc, shadowedPath, renderColor);
}
}
}