SkLiteDL: thread the original canvas matrix through for SetMatrix::Draw().

The SkLiteDL is recorded in some identity space (imagine, SkMatrix::I()),
but played back in a different one (here named SkMatrix original).  Any
calls to setMatrix() need to be made relative to this new space.

All other ops already operate in relative coordinates.

This should let us not fiddle with setMatrix().

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2247353003

Review-Url: https://codereview.chromium.org/2247353003
diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp
index 2c0b3a5..bf722e7 100644
--- a/src/core/SkLiteDL.cpp
+++ b/src/core/SkLiteDL.cpp
@@ -92,11 +92,11 @@
 
     struct Save final : Op {
         static const auto kType = Type::Save;
-        void draw(SkCanvas* c) { c->save(); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->save(); }
     };
     struct Restore final : Op {
         static const auto kType = Type::Restore;
-        void draw(SkCanvas* c) { c->restore(); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->restore(); }
     };
     struct SaveLayer final : Op {
         static const auto kType = Type::SaveLayer;
@@ -111,7 +111,7 @@
         SkPaint                    paint;
         sk_sp<const SkImageFilter> backdrop;
         SkCanvas::SaveLayerFlags   flags;
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
             c->saveLayer({ maybe_unset(bounds), &paint, backdrop.get(), flags });
         }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); }
@@ -121,21 +121,23 @@
         static const auto kType = Type::Concat;
         Concat(const SkMatrix& matrix) : matrix(matrix) {}
         SkMatrix matrix;
-        void draw(SkCanvas* c) { c->concat(matrix); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->concat(matrix); }
         void makeThreadsafe() { make_threadsafe(nullptr, &matrix); }
     };
     struct SetMatrix final : Op {
         static const auto kType = Type::SetMatrix;
         SetMatrix(const SkMatrix& matrix) : matrix(matrix) {}
         SkMatrix matrix;
-        void draw(SkCanvas* c) { c->setMatrix(matrix); }
+        void draw(SkCanvas* c, const SkMatrix& original) {
+            c->setMatrix(SkMatrix::Concat(original, matrix));
+        }
         void makeThreadsafe() { make_threadsafe(nullptr, &matrix); }
     };
     struct TranslateZ final : Op {
         static const auto kType = Type::TranslateZ;
         TranslateZ(SkScalar dz) : dz(dz) {}
         SkScalar dz;
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
         #ifdef SK_EXPERIMENTAL_SHADOWING
             c->translateZ(dz);
         #endif
@@ -148,7 +150,7 @@
         SkPath       path;
         SkRegion::Op op;
         bool         aa;
-        void draw(SkCanvas* c) { c->clipPath(path, op, aa); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->clipPath(path, op, aa); }
         void makeThreadsafe() { make_threadsafe(&path, nullptr); }
     };
     struct ClipRect final : Op {
@@ -157,7 +159,7 @@
         SkRect       rect;
         SkRegion::Op op;
         bool         aa;
-        void draw(SkCanvas* c) { c->clipRect(rect, op, aa); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->clipRect(rect, op, aa); }
     };
     struct ClipRRect final : Op {
         static const auto kType = Type::ClipRRect;
@@ -165,21 +167,21 @@
         SkRRect      rrect;
         SkRegion::Op op;
         bool         aa;
-        void draw(SkCanvas* c) { c->clipRRect(rrect, op, aa); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->clipRRect(rrect, op, aa); }
     };
     struct ClipRegion final : Op {
         static const auto kType = Type::ClipRegion;
         ClipRegion(const SkRegion& region, SkRegion::Op op) : region(region), op(op) {}
         SkRegion     region;
         SkRegion::Op op;
-        void draw(SkCanvas* c) { c->clipRegion(region, op); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->clipRegion(region, op); }
     };
 
     struct DrawPaint final : Op {
         static const auto kType = Type::DrawPaint;
         DrawPaint(const SkPaint& paint) : paint(paint) {}
         SkPaint paint;
-        void draw(SkCanvas* c) { c->drawPaint(paint); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->drawPaint(paint); }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); }
     };
     struct DrawPath final : Op {
@@ -187,7 +189,7 @@
         DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(paint) {}
         SkPath  path;
         SkPaint paint;
-        void draw(SkCanvas* c) { c->drawPath(path, paint); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->drawPath(path, paint); }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); }
         void makeThreadsafe() { make_threadsafe(&path, nullptr); }
     };
@@ -196,7 +198,7 @@
         DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(paint) {}
         SkRect  rect;
         SkPaint paint;
-        void draw(SkCanvas* c) { c->drawRect(rect, paint); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->drawRect(rect, paint); }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); }
     };
     struct DrawOval final : Op {
@@ -204,7 +206,7 @@
         DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(paint) {}
         SkRect  oval;
         SkPaint paint;
-        void draw(SkCanvas* c) { c->drawOval(oval, paint); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->drawOval(oval, paint); }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); }
     };
     struct DrawRRect final : Op {
@@ -212,7 +214,7 @@
         DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), paint(paint) {}
         SkRRect rrect;
         SkPaint paint;
-        void draw(SkCanvas* c) { c->drawRRect(rrect, paint); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->drawRRect(rrect, paint); }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); }
     };
     struct DrawDRRect final : Op {
@@ -221,7 +223,7 @@
             : outer(outer), inner(inner), paint(paint) {}
         SkRRect outer, inner;
         SkPaint paint;
-        void draw(SkCanvas* c) { c->drawDRRect(outer, inner, paint); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->drawDRRect(outer, inner, paint); }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); }
     };
 
@@ -230,7 +232,9 @@
         DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk_ref_sp(value)) {}
         SkRect        rect;
         sk_sp<SkData> value;
-        void draw(SkCanvas* c) { c->drawAnnotation(rect, pod<char>(this), value.get()); }
+        void draw(SkCanvas* c, const SkMatrix&) {
+            c->drawAnnotation(rect, pod<char>(this), value.get());
+        }
     };
     struct DrawDrawable final : Op {
         static const auto kType = Type::DrawDrawable;
@@ -240,7 +244,7 @@
         sk_sp<SkDrawable>      drawable;
         sk_sp<const SkPicture> snapped;
         SkMatrix               matrix = SkMatrix::I();
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
             snapped ? c->drawPicture(snapped.get(), &matrix, nullptr)
                     : c->drawDrawable(drawable.get(), &matrix);
         }
@@ -260,7 +264,7 @@
         SkMatrix               matrix = SkMatrix::I();
         SkPaint                paint;
         bool                   has_paint = false;  // TODO: why is a default paint not the same?
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
             c->drawPicture(picture.get(), &matrix, has_paint ? &paint : nullptr);
         }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); }
@@ -276,7 +280,7 @@
         sk_sp<const SkPicture> picture;
         SkMatrix               matrix = SkMatrix::I();
         SkPaint                paint;
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
         #ifdef SK_EXPERIMENTAL_SHADOWING
             c->drawShadowedPicture(picture.get(), &matrix, &paint);
         #endif
@@ -294,7 +298,7 @@
         sk_sp<const SkImage> image;
         SkScalar x,y;
         SkPaint paint;
-        void draw(SkCanvas* c) { c->drawImage(image.get(), x,y, &paint); }
+        void draw(SkCanvas* c, const SkMatrix&) { c->drawImage(image.get(), x,y, &paint); }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &image); }
     };
     struct DrawImageNine final : Op {
@@ -308,7 +312,9 @@
         SkIRect center;
         SkRect  dst;
         SkPaint paint;
-        void draw(SkCanvas* c) { c->drawImageNine(image.get(), center, dst, &paint); }
+        void draw(SkCanvas* c, const SkMatrix&) {
+            c->drawImageNine(image.get(), center, dst, &paint);
+        }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &image); }
     };
     struct DrawImageRect final : Op {
@@ -323,7 +329,7 @@
         SkRect src, dst;
         SkPaint paint;
         SkCanvas::SrcRectConstraint constraint;
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
             c->drawImageRect(image.get(), src, dst, &paint, constraint);
         }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &image); }
@@ -339,7 +345,7 @@
         int                  xs, ys;
         SkRect               dst;
         SkPaint              paint;
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
             auto xdivs = pod<int>(this, 0),
                  ydivs = pod<int>(this, xs*sizeof(int));
             c->drawImageLattice(image.get(), {xdivs, xs, ydivs, ys}, dst, &paint);
@@ -354,7 +360,9 @@
         size_t bytes;
         SkScalar x,y;
         SkPaint paint;
-        void draw(SkCanvas* c) { c->drawText(pod<void>(this), bytes, x,y, paint); }
+        void draw(SkCanvas* c, const SkMatrix&) {
+            c->drawText(pod<void>(this), bytes, x,y, paint);
+        }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); }
     };
     struct DrawPosText final : Op {
@@ -364,7 +372,7 @@
         size_t bytes;
         SkPaint paint;
         int n;
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
             auto points = pod<SkPoint>(this);
             auto text   = pod<void>(this, n*sizeof(SkPoint));
             c->drawPosText(text, bytes, points, paint);
@@ -379,7 +387,7 @@
         SkScalar y;
         SkPaint  paint;
         int n;
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
             auto xs   = pod<SkScalar>(this);
             auto text = pod<void>(this, n*sizeof(SkScalar));
             c->drawPosTextH(text, bytes, xs, y, paint);
@@ -397,7 +405,7 @@
         SkPath   path;
         SkMatrix matrix = SkMatrix::I();
         SkPaint  paint;
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
             c->drawTextOnPath(pod<void>(this), bytes, path, &matrix, paint);
         }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); }
@@ -412,7 +420,7 @@
         size_t  bytes;
         SkRect  cull = kUnset;
         SkPaint paint;
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
             c->drawTextRSXform(pod<void>(this), bytes, pod<SkRSXform>(this, bytes),
                                maybe_unset(cull), paint);
         }
@@ -425,7 +433,9 @@
         sk_sp<const SkTextBlob> blob;
         SkScalar x,y;
         SkPaint paint;
-        void draw(SkCanvas* c) { c->drawTextBlob(blob.get(), x,y, paint); }
+        void draw(SkCanvas* c, const SkMatrix&) {
+            c->drawTextBlob(blob.get(), x,y, paint);
+        }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); }
     };
 
@@ -445,7 +455,7 @@
         SkPaint           paint;
         bool              has_colors = false;
         bool              has_texs   = false;
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
             c->drawPatch(cubics, has_colors ? colors : nullptr, has_texs ? texs : nullptr,
                          xfermode.get(), paint);
         }
@@ -458,7 +468,9 @@
         SkCanvas::PointMode mode;
         size_t              count;
         SkPaint             paint;
-        void draw(SkCanvas* c) { c->drawPoints(mode, count, pod<SkPoint>(this), paint); }
+        void draw(SkCanvas* c, const SkMatrix&) {
+            c->drawPoints(mode, count, pod<SkPoint>(this), paint);
+        }
         void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); }
     };
     struct DrawVertices final : Op {
@@ -475,7 +487,7 @@
         bool                 has_texs;
         bool                 has_colors;
         bool                 has_indices;
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
             SkPoint* vertices = pod<SkPoint>(this, 0);
             size_t offset = count*sizeof(SkPoint);
 
@@ -514,7 +526,7 @@
         SkRect               cull = kUnset;
         SkPaint              paint;
         bool                 has_colors;
-        void draw(SkCanvas* c) {
+        void draw(SkCanvas* c, const SkMatrix&) {
             auto xforms = pod<SkRSXform>(this, 0);
             auto   texs = pod<SkRect>(this, count*sizeof(SkRSXform));
             auto colors = has_colors
@@ -546,8 +558,8 @@
     return op+1;
 }
 
-template <typename... Args>
-inline void SkLiteDL::map(void (*const fns[])(void*, Args...), Args... args) {
+template <typename Fn, typename... Args>
+inline void SkLiteDL::map(const Fn fns[], Args... args) {
     auto end = fBytes.get() + fUsed;
     for (uint8_t* ptr = fBytes.get(); ptr < end; ) {
         auto op = (Op*)ptr;
@@ -730,13 +742,13 @@
                 colors, colors ? count : 0);
 }
 
-typedef void(* skcanvas_fn)(void*,  SkCanvas*);
+typedef void(*     draw_fn)(void*,  SkCanvas*, const SkMatrix&);
 typedef void(*grcontext_fn)(void*, GrContext*);
 typedef void(*     void_fn)(void*);
 
 // All ops implement draw().
-#define M(T) [](void* op, SkCanvas* c) { ((T*)op)->draw(c); },
-static const skcanvas_fn draw_fns[] = { TYPES(M) };
+#define M(T) [](void* op, SkCanvas* c, const SkMatrix& original) { ((T*)op)->draw(c, original); },
+static const draw_fn draw_fns[] = { TYPES(M) };
 #undef M
 
 // Ops that implement optimizeFor() or makeThreadsafe() return void from those functions;
@@ -763,9 +775,12 @@
 static const void_fn dtor_fns[] = { TYPES(M) };
 #undef M
 
-void SkLiteDL::onDraw        (SkCanvas* canvas) { this->map(draw_fns, canvas); }
-void SkLiteDL::optimizeFor   (GrContext* ctx)   { this->map(optimize_for_fns, ctx); }
-void SkLiteDL::makeThreadsafe()                 { this->map(make_threadsafe_fns); }
+void SkLiteDL::onDraw(SkCanvas* canvas) {
+    SkMatrix original = canvas->getTotalMatrix();
+    this->map(draw_fns, canvas, original);
+}
+void SkLiteDL::optimizeFor   (GrContext* ctx) { this->map(optimize_for_fns, ctx); }
+void SkLiteDL::makeThreadsafe()               { this->map(make_threadsafe_fns); }
 
 SkRect SkLiteDL::onGetBounds() {
     return fBounds;
diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h
index ac1eb9f..d53c8de 100644
--- a/src/core/SkLiteDL.h
+++ b/src/core/SkLiteDL.h
@@ -89,8 +89,8 @@
     template <typename T, typename... Args>
     void* push(size_t, Args&&...);
 
-    template <typename... Args>
-    void map(void (*const [])(void*, Args...), Args...);
+    template <typename Fn, typename... Args>
+    void map(const Fn[], Args...);
 
     SkAutoTMalloc<uint8_t> fBytes;
     size_t                 fUsed;