[SkDebugger] Flatten drawPicture ops

Add two drawPicture bracketing ops (BeginDrawPicture, EndDrawPicture) to
replace the current DrawPicture op, and flatten picture contents.

Review URL: https://codereview.chromium.org/1048383002
diff --git a/debugger/QT/SkDebuggerGUI.cpp b/debugger/QT/SkDebuggerGUI.cpp
index c51f242..237f701 100644
--- a/debugger/QT/SkDebuggerGUI.cpp
+++ b/debugger/QT/SkDebuggerGUI.cpp
@@ -783,7 +783,10 @@
                      SkDrawCommand::GetCommandString(SkDrawCommand::kBeginCommentGroup_OpType)));
     SkASSERT(!strcmp("EndCommentGroup",
                      SkDrawCommand::GetCommandString(SkDrawCommand::kEndCommentGroup_OpType)));
-
+    SkASSERT(!strcmp("BeginDrawPicture",
+                     SkDrawCommand::GetCommandString(SkDrawCommand::kBeginDrawPicture_OpType)));
+    SkASSERT(!strcmp("EndDrawPicture",
+                     SkDrawCommand::GetCommandString(SkDrawCommand::kEndDrawPicture_OpType)));
 
     fListWidget.clear();
     int counter = 0;
@@ -796,7 +799,8 @@
         item->setData(Qt::UserRole + 1, counter++);
 
         if (0 == strcmp("Restore", commandString.c_str()) ||
-            0 == strcmp("EndCommentGroup", commandString.c_str())) {
+            0 == strcmp("EndCommentGroup", commandString.c_str()) ||
+            0 == strcmp("EndDrawPicture", commandString.c_str())) {
             indent -= 10;
         }
 
@@ -804,7 +808,8 @@
 
         if (0 == strcmp("Save", commandString.c_str()) ||
             0 == strcmp("SaveLayer", commandString.c_str()) ||
-            0 == strcmp("BeginCommentGroup", commandString.c_str())) {
+            0 == strcmp("BeginCommentGroup", commandString.c_str()) ||
+            0 == strcmp("BeginDrawPicture", commandString.c_str())) {
             indent += 10;
         }
 
diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp
index b1e906a..1b50efa 100644
--- a/src/utils/debugger/SkDebugCanvas.cpp
+++ b/src/utils/debugger/SkDebugCanvas.cpp
@@ -459,7 +459,9 @@
 void SkDebugCanvas::onDrawPicture(const SkPicture* picture,
                                   const SkMatrix* matrix,
                                   const SkPaint* paint) {
-    this->addDrawCommand(new SkDrawPictureCommand(picture, matrix, paint));
+    this->addDrawCommand(new SkBeginDrawPictureCommand(picture, matrix, paint));
+    this->INHERITED::onDrawPicture(picture, matrix, paint);
+    this->addDrawCommand(new SkEndDrawPictureCommand(SkToBool(matrix) || SkToBool(paint)));
 }
 
 void SkDebugCanvas::onDrawPoints(PointMode mode, size_t count,
diff --git a/src/utils/debugger/SkDrawCommand.cpp b/src/utils/debugger/SkDrawCommand.cpp
index d09de78..09b1889 100644
--- a/src/utils/debugger/SkDrawCommand.cpp
+++ b/src/utils/debugger/SkDrawCommand.cpp
@@ -26,6 +26,7 @@
 const char* SkDrawCommand::GetCommandString(OpType type) {
     switch (type) {
         case kBeginCommentGroup_OpType: return "BeginCommentGroup";
+        case kBeginDrawPicture_OpType: return "BeginDrawPicture";
         case kClipPath_OpType: return "ClipPath";
         case kClipRegion_OpType: return "ClipRegion";
         case kClipRect_OpType: return "ClipRect";
@@ -41,7 +42,6 @@
         case kDrawPaint_OpType: return "DrawPaint";
         case kDrawPatch_OpType: return "DrawPatch";
         case kDrawPath_OpType: return "DrawPath";
-        case kDrawPicture_OpType: return "DrawPicture";
         case kDrawPoints_OpType: return "DrawPoints";
         case kDrawPosText_OpType: return "DrawPosText";
         case kDrawPosTextH_OpType: return "DrawPosTextH";
@@ -53,6 +53,7 @@
         case kDrawTextOnPath_OpType: return "DrawTextOnPath";
         case kDrawVertices_OpType: return "DrawVertices";
         case kEndCommentGroup_OpType: return "EndCommentGroup";
+        case kEndDrawPicture_OpType: return "EndDrawPicture";
         case kRestore_OpType: return "Restore";
         case kSave_OpType: return "Save";
         case kSaveLayer_OpType: return "SaveLayer";
@@ -445,41 +446,48 @@
     return true;
 }
 
-SkDrawPictureCommand::SkDrawPictureCommand(const SkPicture* picture,
-                                           const SkMatrix* matrix,
-                                           const SkPaint* paint)
-    : INHERITED(kDrawPicture_OpType)
-    , fPicture(SkRef(picture))
-    , fMatrixPtr(NULL)
-    , fPaintPtr(NULL) {
+SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
+                                                     const SkMatrix* matrix,
+                                                     const SkPaint* paint)
+    : INHERITED(kBeginDrawPicture_OpType)
+    , fPicture(SkRef(picture)) {
+
+    SkString* str = new SkString;
+    str->appendf("SkPicture: L: %f T: %f R: %f B: %f",
+                 picture->cullRect().fLeft, picture->cullRect().fTop,
+                 picture->cullRect().fRight, picture->cullRect().fBottom);
+    fInfo.push(str);
 
     if (matrix) {
-        fMatrix = *matrix;
-        fMatrixPtr = &fMatrix;
-    }
-    if (paint) {
-        fPaint = *paint;
-        fPaintPtr = &fPaint;
-    }
-
-    SkString* temp = new SkString;
-    temp->appendf("SkPicture: L: %f T: %f R: %f B: %f",
-                  picture->cullRect().fLeft, picture->cullRect().fTop,
-                  picture->cullRect().fRight, picture->cullRect().fBottom);
-    fInfo.push(temp);
-    if (matrix) {
+        fMatrix.set(*matrix);
         fInfo.push(SkObjectParser::MatrixToString(*matrix));
     }
+
     if (paint) {
+        fPaint.set(*paint);
         fInfo.push(SkObjectParser::PaintToString(*paint));
     }
+
+}
+
+void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
+    if (fPaint.isValid()) {
+        SkRect bounds = fPicture->cullRect();
+        if (fMatrix.isValid()) {
+            fMatrix.get()->mapRect(&bounds);
+        }
+        canvas->saveLayer(&bounds, fPaint.get());
+    }
+
+    if (fMatrix.isValid()) {
+        if (!fPaint.isValid()) {
+            canvas->save();
+        }
+        canvas->concat(*fMatrix.get());
+    }
 }
 
-void SkDrawPictureCommand::execute(SkCanvas* canvas) const {
-    canvas->drawPicture(fPicture, fMatrixPtr, fPaintPtr);
-}
-
-bool SkDrawPictureCommand::render(SkCanvas* canvas) const {
+bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
     canvas->clear(0xFFFFFFFF);
     canvas->save();
 
@@ -492,6 +500,15 @@
     return true;
 }
 
+SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
+    : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }
+
+void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
+    if (fRestore) {
+        canvas->restore();
+    }
+}
+
 SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
                                          const SkPoint pts[], const SkPaint& paint)
     : INHERITED(kDrawPoints_OpType) {
diff --git a/src/utils/debugger/SkDrawCommand.h b/src/utils/debugger/SkDrawCommand.h
index 760ce52..538dd23 100644
--- a/src/utils/debugger/SkDrawCommand.h
+++ b/src/utils/debugger/SkDrawCommand.h
@@ -16,6 +16,7 @@
 public:
     enum OpType {
         kBeginCommentGroup_OpType,
+        kBeginDrawPicture_OpType,
         kClipPath_OpType,
         kClipRegion_OpType,
         kClipRect_OpType,
@@ -31,7 +32,6 @@
         kDrawPaint_OpType,
         kDrawPatch_OpType,
         kDrawPath_OpType,
-        kDrawPicture_OpType,
         kDrawPoints_OpType,
         kDrawPosText_OpType,
         kDrawPosTextH_OpType,
@@ -43,6 +43,7 @@
         kDrawTextOnPath_OpType,
         kDrawVertices_OpType,
         kEndCommentGroup_OpType,
+        kEndDrawPicture_OpType,
         kRestore_OpType,
         kSave_OpType,
         kSaveLayer_OpType,
@@ -337,18 +338,31 @@
     typedef SkDrawCommand INHERITED;
 };
 
-class SkDrawPictureCommand : public SkDrawCommand {
+class SkBeginDrawPictureCommand : public SkDrawCommand {
 public:
-    SkDrawPictureCommand(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint);
+    SkBeginDrawPictureCommand(const SkPicture* picture,
+                              const SkMatrix* matrix,
+                              const SkPaint* paint);
+
     void execute(SkCanvas* canvas) const override;
     bool render(SkCanvas* canvas) const override;
 
 private:
     SkAutoTUnref<const SkPicture> fPicture;
-    SkMatrix                      fMatrix;
-    SkMatrix*                     fMatrixPtr;
-    SkPaint                       fPaint;
-    SkPaint*                      fPaintPtr;
+    SkTLazy<SkMatrix>             fMatrix;
+    SkTLazy<SkPaint>              fPaint;
+
+    typedef SkDrawCommand INHERITED;
+};
+
+class SkEndDrawPictureCommand : public SkDrawCommand {
+public:
+    SkEndDrawPictureCommand(bool restore);
+
+    void execute(SkCanvas* canvas) const override;
+
+private:
+    bool fRestore;
 
     typedef SkDrawCommand INHERITED;
 };