move shadows to device virtual

This CL keeps the impl for each device backend in the
utils file for simplicity (shared helpers). Future CLs
may move into their respective impl as they become
more specialized.

Bug: skia:
Change-Id: I97ce6cdcc5106ebf4c84778f943cc32d0b7613c1
Reviewed-on: https://skia-review.googlesource.com/15893
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 10e2181..afc1203 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1909,6 +1909,21 @@
     }
 }
 
+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 65297a1..5305528 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 @@
         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 17ccfdd..17ea6f7 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 @@
                              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 0000000..19199c0
--- /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 b3149a7..f1101b1 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 @@
     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 @@
                          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 @@
                   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 c5df350..31ef38e 100644
--- a/src/core/SkLiteDL.h
+++ b/src/core/SkLiteDL.h
@@ -77,6 +77,7 @@
     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 5affb3d..dbee48e 100644
--- a/src/core/SkLiteRecorder.cpp
+++ b/src/core/SkLiteRecorder.cpp
@@ -194,3 +194,6 @@
                                  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 3c156af..4d49eb5 100644
--- a/src/core/SkLiteRecorder.h
+++ b/src/core/SkLiteRecorder.h
@@ -77,6 +77,7 @@
     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 e668cc8..953e874 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -125,6 +125,7 @@
 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 @@
         }
     }
 
+    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 64d613d..1eeef53 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -338,6 +338,10 @@
            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 5344934..04e75ed 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -121,6 +121,7 @@
     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 6af4aad..a63ef1c 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 @@
     M(DrawTextBlob)                                                 \
     M(DrawAtlas)                                                    \
     M(DrawVertices)                                                 \
+    M(DrawShadowRec)                                                \
     M(DrawAnnotation)
 
 // Defines SkRecords::Type, an enum of all record types.
@@ -345,6 +347,9 @@
         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;