Snap for 5606075 from 7ec942143dc96fee8a132c1b30a5abf73a671d74 to qt-c2f2-release

Change-Id: Idf7dd749197e05807d77b7ddfc6a5289687b9b14
diff --git a/gm/savelayer.cpp b/gm/savelayer.cpp
index d6a33b2..1347cbc 100644
--- a/gm/savelayer.cpp
+++ b/gm/savelayer.cpp
@@ -281,7 +281,8 @@
 #include "SkGradientShader.h"
 #include "SkTextBlob.h"
 
-static void draw_cell(SkCanvas* canvas, sk_sp<SkTextBlob> blob, SkColor c, SkScalar w, SkScalar h) {
+static void draw_cell(SkCanvas* canvas, sk_sp<SkTextBlob> blob, SkColor c, SkScalar w, SkScalar h,
+                      bool useDrawBehind) {
     SkRect r = SkRect::MakeWH(w, h);
     SkPaint p;
     p.setColor(c);
@@ -309,7 +310,12 @@
     auto sh = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode);
     p.setShader(sh);
     p.setBlendMode(SkBlendMode::kDstIn);
-    canvas->drawRect(r, p);
+
+    if (useDrawBehind) {
+        SkCanvasPriv::DrawBehind(canvas, p);
+    } else {
+        canvas->drawRect(r, p);
+    }
 
     // this should restore the behind image
     canvas->restore();
@@ -320,10 +326,9 @@
     p.reset();
     p.setStyle(SkPaint::kStroke_Style);
     p.setAlphaf(0.25f);
-    canvas->drawRect(r, p);
 }
 
-static void draw_list(SkCanvas* canvas, sk_sp<SkTextBlob> blob) {
+static void draw_list(SkCanvas* canvas, sk_sp<SkTextBlob> blob, bool useDrawBehind) {
     SkAutoCanvasRestore acr(canvas, true);
 
     SkRandom rand;
@@ -332,19 +337,27 @@
     for (int i = 0; i < 8; ++i) {
         SkColor c = rand.nextU();   // ensure we're opaque
         c = (c & 0xFFFFFF) | 0x80000000;
-        draw_cell(canvas, blob, c, w, h);
+        draw_cell(canvas, blob, c, w, h, useDrawBehind);
         canvas->translate(0, h);
     }
 }
 
-DEF_SIMPLE_GM(save_behind, canvas, 400, 670) {
+DEF_SIMPLE_GM(save_behind, canvas, 830, 670) {
     SkFont font;
     font.setSize(30);
     const char text[] = "This is a very long line of text";
     auto blob = SkTextBlob::MakeFromText(text, strlen(text), font);
 
-    draw_list(canvas, blob);
-    canvas->translate(0, 350);
-    canvas->saveLayer({0, 0, 400, 320}, nullptr);
-    draw_list(canvas, blob);
+    for (bool useDrawBehind : {false, true}) {
+        canvas->save();
+
+        draw_list(canvas, blob, useDrawBehind);
+        canvas->translate(0, 350);
+        canvas->saveLayer({0, 0, 400, 320}, nullptr);
+        draw_list(canvas, blob, useDrawBehind);
+        canvas->restore();
+
+        canvas->restore();
+        canvas->translate(430, 0);
+    }
 }
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 397939b..40f1601 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -2379,6 +2379,7 @@
     // SkCanvasVirtualEnforcer (in SkCanvasVirtualEnforcer.h). This ensures that subclasses using
     // that mechanism  will be required to implement the new function.
     virtual void onDrawPaint(const SkPaint& paint);
+    virtual void onDrawBehind(const SkPaint& paint);
     virtual void onDrawRect(const SkRect& rect, const SkPaint& paint);
     virtual void onDrawEdgeAARect(const SkRect& rect, QuadAAFlags edgeAA, SkColor color,
                                   SkBlendMode mode);
@@ -2587,6 +2588,12 @@
      */
     int only_axis_aligned_saveBehind(const SkRect* subset);
 
+    /**
+     *  Like drawPaint, but magically clipped to the most recent saveBehind buffer rectangle.
+     *  If there is no active saveBehind, then this draws nothing.
+     */
+    void drawClippedToSaveBehind(const SkPaint&);
+
     void resetForNextPicture(const SkIRect& bounds);
 
     // needs gettotalclip()
diff --git a/include/core/SkCanvasVirtualEnforcer.h b/include/core/SkCanvasVirtualEnforcer.h
index f097911..3a5dac3 100644
--- a/include/core/SkCanvasVirtualEnforcer.h
+++ b/include/core/SkCanvasVirtualEnforcer.h
@@ -20,6 +20,7 @@
 
 protected:
     void onDrawPaint(const SkPaint& paint) override = 0;
+    void onDrawBehind(const SkPaint&) override {} // make zero after android updates
     void onDrawRect(const SkRect& rect, const SkPaint& paint) override = 0;
     void onDrawRRect(const SkRRect& rrect, const SkPaint& paint) override = 0;
     void onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
diff --git a/include/core/SkOverdrawCanvas.h b/include/core/SkOverdrawCanvas.h
index e0d05c8..c75d7ae 100644
--- a/include/core/SkOverdrawCanvas.h
+++ b/include/core/SkOverdrawCanvas.h
@@ -25,6 +25,7 @@
     void onDrawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
                      const SkPaint&) override;
     void onDrawPaint(const SkPaint&) override;
+    void onDrawBehind(const SkPaint& paint) override;
     void onDrawRect(const SkRect&, const SkPaint&) override;
     void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
     void onDrawRegion(const SkRegion&, const SkPaint&) override;
diff --git a/include/utils/SkNWayCanvas.h b/include/utils/SkNWayCanvas.h
index 09b071d..de9f44b 100644
--- a/include/utils/SkNWayCanvas.h
+++ b/include/utils/SkNWayCanvas.h
@@ -41,6 +41,7 @@
                              const SkPaint& paint) override;
 
     void onDrawPaint(const SkPaint&) override;
+    void onDrawBehind(const SkPaint&) override;
     void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
     void onDrawRect(const SkRect&, const SkPaint&) override;
     void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
diff --git a/include/utils/SkNoDrawCanvas.h b/include/utils/SkNoDrawCanvas.h
index ff1b027..43b49bc 100644
--- a/include/utils/SkNoDrawCanvas.h
+++ b/include/utils/SkNoDrawCanvas.h
@@ -49,6 +49,7 @@
                      const SkPaint&) override {}
 
     void onDrawPaint(const SkPaint&) override {}
+    void onDrawBehind(const SkPaint&) override {}
     void onDrawPoints(PointMode, size_t, const SkPoint[], const SkPaint&) override {}
     void onDrawRect(const SkRect&, const SkPaint&) override {}
     void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override {}
diff --git a/include/utils/SkPaintFilterCanvas.h b/include/utils/SkPaintFilterCanvas.h
index c1d31b6..0d154e5 100644
--- a/include/utils/SkPaintFilterCanvas.h
+++ b/include/utils/SkPaintFilterCanvas.h
@@ -68,6 +68,7 @@
     virtual bool onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Type type) const = 0;
 
     void onDrawPaint(const SkPaint&) override;
+    void onDrawBehind(const SkPaint&) override;
     void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
     void onDrawRect(const SkRect&, const SkPaint&) override;
     void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 1368850..8e84c32 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1145,11 +1145,7 @@
 
     SkPaint paint;
     paint.setBlendMode(SkBlendMode::kClear);
-    if (localBounds) {
-        this->drawRect(*localBounds, paint);
-    } else {
-        this->drawPaint(paint);
-    }
+    this->drawClippedToSaveBehind(paint);
 }
 
 void SkCanvas::internalRestore() {
@@ -1702,6 +1698,11 @@
     this->onDrawRect(r.makeSorted(), paint);
 }
 
+void SkCanvas::drawClippedToSaveBehind(const SkPaint& paint) {
+    TRACE_EVENT0("skia", TRACE_FUNC);
+    this->onDrawBehind(paint);
+}
+
 void SkCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) {
     TRACE_EVENT0("skia", TRACE_FUNC);
     if (region.isEmpty()) {
@@ -2127,6 +2128,40 @@
     LOOPER_END
 }
 
+void SkCanvas::onDrawBehind(const SkPaint& paint) {
+    SkIRect bounds;
+    SkDeque::Iter iter(fMCStack, SkDeque::Iter::kBack_IterStart);
+    for (;;) {
+        const MCRec* rec = (const MCRec*)iter.prev();
+        if (!rec) {
+            return; // no backimages, so nothing to draw
+        }
+        if (rec->fBackImage) {
+            bounds = SkIRect::MakeXYWH(rec->fBackImage->fLoc.fX, rec->fBackImage->fLoc.fY,
+                                       rec->fBackImage->fImage->width(),
+                                       rec->fBackImage->fImage->height());
+            break;
+        }
+    }
+
+    LOOPER_BEGIN(paint, nullptr)
+
+    while (iter.next()) {
+        SkBaseDevice* dev = iter.fDevice;
+
+        dev->save();
+        // We use clipRegion because it is already defined to operate in dev-space
+        // (i.e. ignores the ctm). However, it is going to first translate by -origin,
+        // but we don't want that, so we undo that before calling in.
+        SkRegion rgn(bounds.makeOffset(dev->fOrigin.fX, dev->fOrigin.fY));
+        dev->clipRegion(rgn, SkClipOp::kIntersect);
+        dev->drawPaint(looper.paint());
+        dev->restore(fMCRec->fMatrix);
+    }
+
+    LOOPER_END
+}
+
 void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
     SkASSERT(oval.isSorted());
     if (paint.canComputeFastBounds()) {
diff --git a/src/core/SkCanvasPriv.h b/src/core/SkCanvasPriv.h
index cb25401..0c3a2d8 100644
--- a/src/core/SkCanvasPriv.h
+++ b/src/core/SkCanvasPriv.h
@@ -43,6 +43,16 @@
     static int SaveBehind(SkCanvas* canvas, const SkRect* subset) {
         return canvas->only_axis_aligned_saveBehind(subset);
     }
+
+    static void DrawBehind(SkCanvas* canvas, const SkPaint& paint) {
+        canvas->drawClippedToSaveBehind(paint);
+    }
+
+    // The experimental_DrawEdgeAAImageSet API accepts separate dstClips and preViewMatrices arrays,
+    // where entries refer into them, but no explicit size is provided. Given a set of entries,
+    // computes the minimum length for these arrays that would provide index access errors.
+    static void GetDstClipAndMatrixCounts(const SkCanvas::ImageSetEntry set[], int count,
+                                          int* totalDstClipCount, int* totalMatrixCount);
 };
 
 #endif
diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp
index 1c9c742..562cd4f 100644
--- a/src/core/SkLiteDL.cpp
+++ b/src/core/SkLiteDL.cpp
@@ -52,7 +52,7 @@
     M(Flush) M(Save) M(Restore) M(SaveLayer) M(SaveBehind)                             \
     M(Concat) M(SetMatrix) M(Translate)                                                \
     M(ClipPath) M(ClipRect) M(ClipRRect) M(ClipRegion)                                 \
-    M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawEdgeAARect)                             \
+    M(DrawPaint) M(DrawBehind) M(DrawPath) M(DrawRect) M(DrawEdgeAARect)               \
     M(DrawRegion) M(DrawOval) M(DrawArc)                                               \
     M(DrawRRect) M(DrawDRRect) M(DrawAnnotation) M(DrawDrawable) M(DrawPicture)        \
     M(DrawImage) M(DrawImageNine) M(DrawImageRect) M(DrawImageLattice) M(DrawImageSet) \
@@ -176,6 +176,12 @@
         SkPaint paint;
         void draw(SkCanvas* c, const SkMatrix&) const { c->drawPaint(paint); }
     };
+    struct DrawBehind final : Op {
+        static const auto kType = Type::DrawBehind;
+        DrawBehind(const SkPaint& paint) : paint(paint) {}
+        SkPaint paint;
+        void draw(SkCanvas* c, const SkMatrix&) const { SkCanvasPriv::DrawBehind(c, paint); }
+    };
     struct DrawPath final : Op {
         static const auto kType = Type::DrawPath;
         DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(paint) {}
@@ -527,6 +533,9 @@
 void SkLiteDL::drawPaint(const SkPaint& paint) {
     this->push<DrawPaint>(0, paint);
 }
+void SkLiteDL::drawBehind(const SkPaint& paint) {
+    this->push<DrawBehind>(0, paint);
+}
 void SkLiteDL::drawPath(const SkPath& path, const SkPaint& paint) {
     this->push<DrawPath>(0, path, paint);
 }
diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h
index a6041bc..0758f01 100644
--- a/src/core/SkLiteDL.h
+++ b/src/core/SkLiteDL.h
@@ -44,6 +44,7 @@
     void clipRegion(const SkRegion&, SkClipOp);
 
     void drawPaint (const SkPaint&);
+    void drawBehind(const SkPaint&);
     void drawPath  (const SkPath&, const SkPaint&);
     void drawRect  (const SkRect&, const SkPaint&);
     void drawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode);
diff --git a/src/core/SkLiteRecorder.cpp b/src/core/SkLiteRecorder.cpp
index 6dda8d6..e4ea47e 100644
--- a/src/core/SkLiteRecorder.cpp
+++ b/src/core/SkLiteRecorder.cpp
@@ -60,6 +60,9 @@
 void SkLiteRecorder::onDrawPaint(const SkPaint& paint) {
     fDL->drawPaint(paint);
 }
+void SkLiteRecorder::onDrawBehind(const SkPaint& paint) {
+    fDL->drawBehind(paint);
+}
 void SkLiteRecorder::onDrawPath(const SkPath& path, const SkPaint& paint) {
     fDL->drawPath(path, paint);
 }
diff --git a/src/core/SkLiteRecorder.h b/src/core/SkLiteRecorder.h
index 81eedb3..0bc5db3 100644
--- a/src/core/SkLiteRecorder.h
+++ b/src/core/SkLiteRecorder.h
@@ -37,6 +37,7 @@
     void onClipRegion(const SkRegion&, SkClipOp) override;
 
     void onDrawPaint (const SkPaint&) override;
+    void onDrawBehind(const SkPaint&) override;
     void onDrawPath  (const SkPath&, const SkPaint&) override;
     void onDrawRect  (const SkRect&, const SkPaint&) override;
     void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
diff --git a/src/core/SkOverdrawCanvas.cpp b/src/core/SkOverdrawCanvas.cpp
index a7b39bb..a760ea0 100644
--- a/src/core/SkOverdrawCanvas.cpp
+++ b/src/core/SkOverdrawCanvas.cpp
@@ -113,6 +113,10 @@
     }
 }
 
+void SkOverdrawCanvas::onDrawBehind(const SkPaint& paint) {
+    fList[0]->onDrawBehind(this->overdrawPaint(paint));
+}
+
 void SkOverdrawCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
     fList[0]->onDrawRect(rect, this->overdrawPaint(paint));
 }
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index de1c269..cdea96d 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -103,7 +103,9 @@
 
     DRAW_EDGEAA_RECT,
 
-    LAST_DRAWTYPE_ENUM = DRAW_EDGEAA_RECT,
+    DRAW_BEHIND_PAINT,
+
+    LAST_DRAWTYPE_ENUM = DRAW_BEHIND_PAINT,
 };
 
 enum DrawVertexFlags {
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index e0120dd..9724695 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -368,6 +368,14 @@
                 canvas->drawPaint(*paint);
             }
         } break;
+        case DRAW_BEHIND_PAINT: {
+            const SkPaint* paint = fPictureData->getPaint(reader);
+            BREAK_ON_READ_ERROR(reader);
+
+            if (paint) {
+                SkCanvasPriv::DrawBehind(canvas, *paint);
+            }
+        } break;
         case DRAW_PATCH: {
             const SkPaint* paint = fPictureData->getPaint(reader);
 
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 01115bf..f7d5971 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -422,6 +422,15 @@
     this->validate(initialOffset, size);
 }
 
+void SkPictureRecord::onDrawBehind(const SkPaint& paint) {
+    // logically the same as drawPaint, but with a diff enum
+    // op + paint index
+    size_t size = 2 * kUInt32Size;
+    size_t initialOffset = this->addDraw(DRAW_BEHIND_PAINT, &size);
+    this->addPaint(paint);
+    this->validate(initialOffset, size);
+}
+
 void SkPictureRecord::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
                                    const SkPaint& paint) {
     // op + paint index + mode + count + point data
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 77137c4..59f16cf 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -174,6 +174,7 @@
                      SkBlendMode, const SkRect*, const SkPaint*) override;
 
     void onDrawPaint(const SkPaint&) override;
+    void onDrawBehind(const SkPaint&) override;
     void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
     void onDrawRect(const SkRect&, const SkPaint&) override;
     void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index 4dcc455..fac7e68 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -88,6 +88,10 @@
     SkCanvasPriv::SaveBehind(fCanvas, r.subset);
 }
 
+template <> void Draw::draw(const DrawBehind& r) {
+    SkCanvasPriv::DrawBehind(fCanvas, r.paint);
+}
+
 DRAW(SetMatrix, setMatrix(SkMatrix::Concat(fInitialCTM, r.matrix)));
 DRAW(Concat, concat(r.matrix));
 DRAW(Translate, translate(r.dx, r.dy));
@@ -354,6 +358,7 @@
     Bounds bounds(const Flush&) const { return fCullRect; }
 
     Bounds bounds(const DrawPaint&) const { return fCullRect; }
+    Bounds bounds(const DrawBehind&) const { return fCullRect; }
     Bounds bounds(const NoOp&)  const { return Bounds::MakeEmpty(); }    // NoOps don't draw.
 
     Bounds bounds(const DrawRect& op) const { return this->adjustAndMap(op.rect, &op.paint); }
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index bfe1067..9a4e1f6 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -139,6 +139,10 @@
     this->append<SkRecords::DrawPaint>(paint);
 }
 
+void SkRecorder::onDrawBehind(const SkPaint& paint) {
+    this->append<SkRecords::DrawBehind>(paint);
+}
+
 void SkRecorder::onDrawPoints(PointMode mode,
                               size_t count,
                               const SkPoint pts[],
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index 6b4c7fe..53fd3aa 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -77,6 +77,7 @@
                      const SkPaint& paint) override;
 
     void onDrawPaint(const SkPaint&) override;
+    void onDrawBehind(const SkPaint&) override;
     void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
     void onDrawRect(const SkRect&, const SkPaint&) override;
     void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h
index 8f80924..66a5e28 100644
--- a/src/core/SkRecords.h
+++ b/src/core/SkRecords.h
@@ -60,6 +60,7 @@
     M(DrawImageSet)                                                 \
     M(DrawDRRect)                                                   \
     M(DrawOval)                                                     \
+    M(DrawBehind)                                                   \
     M(DrawPaint)                                                    \
     M(DrawPath)                                                     \
     M(DrawPatch)                                                    \
@@ -269,6 +270,8 @@
         SkRect oval);
 RECORD(DrawPaint, kDraw_Tag|kHasPaint_Tag,
         SkPaint paint);
+RECORD(DrawBehind, kDraw_Tag|kHasPaint_Tag,
+       SkPaint paint);
 RECORD(DrawPath, kDraw_Tag|kHasPaint_Tag,
         SkPaint paint;
         PreCachedPath path);
diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp
index 1e6cd89..c952601 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -147,6 +147,13 @@
     }
 }
 
+void SkNWayCanvas::onDrawBehind(const SkPaint& paint) {
+    Iter iter(fList);
+    while (iter.next()) {
+        SkCanvasPriv::DrawBehind(iter.get(), paint);
+    }
+}
+
 void SkNWayCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
                                 const SkPaint& paint) {
     Iter iter(fList);
diff --git a/src/utils/SkPaintFilterCanvas.cpp b/src/utils/SkPaintFilterCanvas.cpp
index ded7fc2..f06e565 100644
--- a/src/utils/SkPaintFilterCanvas.cpp
+++ b/src/utils/SkPaintFilterCanvas.cpp
@@ -49,6 +49,13 @@
     }
 }
 
+void SkPaintFilterCanvas::onDrawBehind(const SkPaint& paint) {
+    AutoPaintFilter apf(this, kPaint_Type, paint);
+    if (apf.shouldDraw()) {
+        this->SkNWayCanvas::onDrawBehind(*apf.paint());
+    }
+}
+
 void SkPaintFilterCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
                                        const SkPaint& paint) {
     AutoPaintFilter apf(this, kPoint_Type, paint);
diff --git a/tools/debugger/SkDebugCanvas.cpp b/tools/debugger/SkDebugCanvas.cpp
index 96c0de2..59d3dd8 100644
--- a/tools/debugger/SkDebugCanvas.cpp
+++ b/tools/debugger/SkDebugCanvas.cpp
@@ -429,6 +429,10 @@
     this->addDrawCommand(new SkDrawPatchCommand(cubics, colors, texCoords, bmode, paint));
 }
 
+void SkDebugCanvas::onDrawBehind(const SkPaint& paint) {
+    this->addDrawCommand(new SkDrawBehindCommand(paint));
+}
+
 void SkDebugCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[],
                                          int boneCount, SkBlendMode bmode, const SkPaint& paint) {
     // TODO: ANIMATION NOT LOGGED
diff --git a/tools/debugger/SkDebugCanvas.h b/tools/debugger/SkDebugCanvas.h
index 194ce11..83819bf 100644
--- a/tools/debugger/SkDebugCanvas.h
+++ b/tools/debugger/SkDebugCanvas.h
@@ -129,6 +129,7 @@
     void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
                      const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint) override;
     void onDrawPaint(const SkPaint&) override;
+    void onDrawBehind(const SkPaint&) override;
 
     void onDrawRect(const SkRect&, const SkPaint&) override;
     void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
diff --git a/tools/debugger/SkDrawCommand.cpp b/tools/debugger/SkDrawCommand.cpp
index d9723ac..2de0c0c 100644
--- a/tools/debugger/SkDrawCommand.cpp
+++ b/tools/debugger/SkDrawCommand.cpp
@@ -9,6 +9,7 @@
 
 #include <algorithm>
 #include "SkAutoMalloc.h"
+#include "SkCanvasPriv.h"
 #include "SkClipOpPriv.h"
 #include "SkColorFilter.h"
 #include "SkDashPathEffect.h"
@@ -1639,6 +1640,27 @@
     writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT); MakeJsonPaint(writer, fPaint, urlDataManager);
 }
 
+SkDrawBehindCommand::SkDrawBehindCommand(const SkPaint& paint) : INHERITED(kDrawPaint_OpType) {
+    fPaint = paint;
+}
+
+void SkDrawBehindCommand::execute(SkCanvas* canvas) const {
+    SkCanvasPriv::DrawBehind(canvas, fPaint);
+}
+
+bool SkDrawBehindCommand::render(SkCanvas* canvas) const {
+    canvas->clear(0xFFFFFFFF);
+    SkCanvasPriv::DrawBehind(canvas, fPaint);
+    return true;
+}
+
+void SkDrawBehindCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
+    INHERITED::toJSON(writer, urlDataManager);
+    writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT);
+    MakeJsonPaint(writer, fPaint, urlDataManager);
+}
+
+
 SkDrawRegionCommand::SkDrawRegionCommand(const SkRegion& region, const SkPaint& paint)
     : INHERITED(kDrawRegion_OpType) {
     fRegion = region;
diff --git a/tools/debugger/SkDrawCommand.h b/tools/debugger/SkDrawCommand.h
index 7c386bc..50d2cc5 100644
--- a/tools/debugger/SkDrawCommand.h
+++ b/tools/debugger/SkDrawCommand.h
@@ -419,6 +419,19 @@
     typedef SkDrawCommand INHERITED;
 };
 
+class SkDrawBehindCommand : public SkDrawCommand {
+public:
+    SkDrawBehindCommand(const SkPaint& paint);
+    void execute(SkCanvas* canvas) const override;
+    bool render(SkCanvas* canvas) const override;
+    void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
+
+private:
+    SkPaint fPaint;
+
+    typedef SkDrawCommand INHERITED;
+};
+
 class SkDrawPathCommand : public SkDrawCommand {
 public:
     SkDrawPathCommand(const SkPath& path, const SkPaint& paint);