Debugger improvements

This CL:
  improves the 'SaveAs' functionality
  allows switching between # and offset indexing in the command list
  minor nit cleanup

R=bsalomon@google.com

Author: robertphillips@google.com

Review URL: https://codereview.chromium.org/211383003

git-svn-id: http://skia.googlecode.com/svn/trunk@13950 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp
index b4813e4..0f2b9e0 100644
--- a/src/utils/debugger/SkDebugCanvas.cpp
+++ b/src/utils/debugger/SkDebugCanvas.cpp
@@ -16,6 +16,7 @@
 
 SkDebugCanvas::SkDebugCanvas(int width, int height)
         : INHERITED(width, height)
+        , fPicture(NULL)
         , fWidth(width)
         , fHeight(height)
         , fFilter(false)
@@ -55,12 +56,13 @@
 }
 
 void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) {
+    command->setOffset(this->getOpID());
     fCommandVector.push(command);
 }
 
 void SkDebugCanvas::draw(SkCanvas* canvas) {
     if (!fCommandVector.isEmpty()) {
-        drawTo(canvas, fCommandVector.count() - 1);
+        this->drawTo(canvas, fCommandVector.count() - 1);
     }
 }
 
@@ -380,6 +382,16 @@
     return commandString;
 }
 
+SkTDArray<size_t>* SkDebugCanvas::getDrawCommandOffsets() const {
+    SkTDArray<size_t>* commandOffsets = new SkTDArray<size_t>;
+    if (!fCommandVector.isEmpty()) {
+        for (int i = 0; i < fCommandVector.count(); i ++) {
+            *commandOffsets->push() = fCommandVector[i]->offset();
+        }
+    }
+    return commandOffsets;
+}
+
 void SkDebugCanvas::overrideTexFiltering(bool overrideTexFiltering, SkPaint::FilterLevel level) {
     if (NULL == fTexOverrideFilter) {
         fTexOverrideFilter = new SkTexOverrideFilter;
@@ -390,7 +402,7 @@
 }
 
 void SkDebugCanvas::clear(SkColor color) {
-    addDrawCommand(new SkClearCommand(color));
+    this->addDrawCommand(new SkClearCommand(color));
 }
 
 void SkDebugCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
@@ -429,71 +441,71 @@
 
 void SkDebugCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
                                SkScalar top, const SkPaint* paint = NULL) {
-    addDrawCommand(new SkDrawBitmapCommand(bitmap, left, top, paint));
+    this->addDrawCommand(new SkDrawBitmapCommand(bitmap, left, top, paint));
 }
 
 void SkDebugCanvas::drawBitmapRectToRect(const SkBitmap& bitmap,
                                          const SkRect* src, const SkRect& dst,
                                          const SkPaint* paint,
                                          SkCanvas::DrawBitmapRectFlags flags) {
-    addDrawCommand(new SkDrawBitmapRectCommand(bitmap, src, dst, paint, flags));
+    this->addDrawCommand(new SkDrawBitmapRectCommand(bitmap, src, dst, paint, flags));
 }
 
 void SkDebugCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
                                      const SkMatrix& matrix, const SkPaint* paint) {
-    addDrawCommand(new SkDrawBitmapMatrixCommand(bitmap, matrix, paint));
+    this->addDrawCommand(new SkDrawBitmapMatrixCommand(bitmap, matrix, paint));
 }
 
 void SkDebugCanvas::drawBitmapNine(const SkBitmap& bitmap,
         const SkIRect& center, const SkRect& dst, const SkPaint* paint) {
-    addDrawCommand(new SkDrawBitmapNineCommand(bitmap, center, dst, paint));
+    this->addDrawCommand(new SkDrawBitmapNineCommand(bitmap, center, dst, paint));
 }
 
 void SkDebugCanvas::drawData(const void* data, size_t length) {
-    addDrawCommand(new SkDrawDataCommand(data, length));
+    this->addDrawCommand(new SkDrawDataCommand(data, length));
 }
 
 void SkDebugCanvas::beginCommentGroup(const char* description) {
-    addDrawCommand(new SkBeginCommentGroupCommand(description));
+    this->addDrawCommand(new SkBeginCommentGroupCommand(description));
 }
 
 void SkDebugCanvas::addComment(const char* kywd, const char* value) {
-    addDrawCommand(new SkCommentCommand(kywd, value));
+    this->addDrawCommand(new SkCommentCommand(kywd, value));
 }
 
 void SkDebugCanvas::endCommentGroup() {
-    addDrawCommand(new SkEndCommentGroupCommand());
+    this->addDrawCommand(new SkEndCommentGroupCommand());
 }
 
 void SkDebugCanvas::drawOval(const SkRect& oval, const SkPaint& paint) {
-    addDrawCommand(new SkDrawOvalCommand(oval, paint));
+    this->addDrawCommand(new SkDrawOvalCommand(oval, paint));
 }
 
 void SkDebugCanvas::drawPaint(const SkPaint& paint) {
-    addDrawCommand(new SkDrawPaintCommand(paint));
+    this->addDrawCommand(new SkDrawPaintCommand(paint));
 }
 
 void SkDebugCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
-    addDrawCommand(new SkDrawPathCommand(path, paint));
+    this->addDrawCommand(new SkDrawPathCommand(path, paint));
 }
 
 void SkDebugCanvas::drawPicture(SkPicture& picture) {
-    addDrawCommand(new SkDrawPictureCommand(picture));
+    this->addDrawCommand(new SkDrawPictureCommand(picture));
 }
 
 void SkDebugCanvas::drawPoints(PointMode mode, size_t count,
                                const SkPoint pts[], const SkPaint& paint) {
-    addDrawCommand(new SkDrawPointsCommand(mode, count, pts, paint));
+    this->addDrawCommand(new SkDrawPointsCommand(mode, count, pts, paint));
 }
 
 void SkDebugCanvas::drawPosText(const void* text, size_t byteLength,
         const SkPoint pos[], const SkPaint& paint) {
-    addDrawCommand(new SkDrawPosTextCommand(text, byteLength, pos, paint));
+    this->addDrawCommand(new SkDrawPosTextCommand(text, byteLength, pos, paint));
 }
 
 void SkDebugCanvas::drawPosTextH(const void* text, size_t byteLength,
         const SkScalar xpos[], SkScalar constY, const SkPaint& paint) {
-    addDrawCommand(
+    this->addDrawCommand(
         new SkDrawPosTextHCommand(text, byteLength, xpos, constY, paint));
 }
 
@@ -503,7 +515,7 @@
 }
 
 void SkDebugCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
-    addDrawCommand(new SkDrawRRectCommand(rrect, paint));
+    this->addDrawCommand(new SkDrawRRectCommand(rrect, paint));
 }
 
 void SkDebugCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
@@ -513,17 +525,17 @@
 
 void SkDebugCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
                                const SkPaint* paint = NULL) {
-    addDrawCommand(new SkDrawSpriteCommand(bitmap, left, top, paint));
+    this->addDrawCommand(new SkDrawSpriteCommand(bitmap, left, top, paint));
 }
 
 void SkDebugCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
         SkScalar y, const SkPaint& paint) {
-    addDrawCommand(new SkDrawTextCommand(text, byteLength, x, y, paint));
+    this->addDrawCommand(new SkDrawTextCommand(text, byteLength, x, y, paint));
 }
 
 void SkDebugCanvas::drawTextOnPath(const void* text, size_t byteLength,
         const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) {
-    addDrawCommand(
+    this->addDrawCommand(
         new SkDrawTextOnPathCommand(text, byteLength, path, matrix, paint));
 }
 
@@ -531,8 +543,8 @@
         const SkPoint vertices[], const SkPoint texs[], const SkColor colors[],
         SkXfermode*, const uint16_t indices[], int indexCount,
         const SkPaint& paint) {
-    addDrawCommand(new SkDrawVerticesCommand(vmode, vertexCount, vertices,
-                   texs, colors, NULL, indices, indexCount, paint));
+    this->addDrawCommand(new SkDrawVerticesCommand(vmode, vertexCount, vertices,
+                         texs, colors, NULL, indices, indexCount, paint));
 }
 
 void SkDebugCanvas::onPushCull(const SkRect& cullRect) {
@@ -562,7 +574,7 @@
 }
 
 void SkDebugCanvas::didSetMatrix(const SkMatrix& matrix) {
-    addDrawCommand(new SkSetMatrixCommand(matrix));
+    this->addDrawCommand(new SkSetMatrixCommand(matrix));
     this->INHERITED::didSetMatrix(matrix);
 }
 
diff --git a/src/utils/debugger/SkDebugCanvas.h b/src/utils/debugger/SkDebugCanvas.h
index ac3083e..d89cf94 100644
--- a/src/utils/debugger/SkDebugCanvas.h
+++ b/src/utils/debugger/SkDebugCanvas.h
@@ -26,11 +26,18 @@
     void toggleFilter(bool toggle) { fFilter = toggle; }
 
     void setMegaVizMode(bool megaVizMode) { fMegaVizMode = megaVizMode; }
+    bool getMegaVizMode() const { return fMegaVizMode; }
 
     /**
      * Enable or disable overdraw visualization
      */
     void setOverdrawViz(bool overdrawViz) { fOverdrawViz = overdrawViz; }
+    bool getOverdrawViz() const { return fOverdrawViz; }
+
+    void setOutstandingSaveCount(int saveCount) { fOutstandingSaveCount = saveCount; }
+    int getOutstandingSaveCount() const { return fOutstandingSaveCount; }
+
+    void setPicture(SkPicture* picture) { fPicture = picture; }
 
     /**
      * Enable or disable texure filtering override
@@ -118,6 +125,11 @@
     SkTArray<SkString>* getDrawCommandsAsStrings() const;
 
     /**
+     * Returns an array containing an offset (in the SkPicture) for each command
+     */
+    SkTDArray<size_t>* getDrawCommandOffsets() const;
+
+    /**
         Returns length of draw command vector.
      */
     int getSize() const {
@@ -250,6 +262,7 @@
 
 private:
     SkTDArray<SkDrawCommand*> fCommandVector;
+    SkPicture* fPicture;
     int fWidth;
     int fHeight;
     bool fFilter;
@@ -297,6 +310,13 @@
      */
     void applyUserTransform(SkCanvas* canvas);
 
+    size_t getOpID() const {
+        if (NULL != fPicture) {
+            return fPicture->EXPERIMENTAL_curOpID();
+        }
+        return 0;
+    }
+
     typedef SkCanvas INHERITED;
 };
 
diff --git a/src/utils/debugger/SkDrawCommand.cpp b/src/utils/debugger/SkDrawCommand.cpp
index 7e6b22b..f10f1e8 100644
--- a/src/utils/debugger/SkDrawCommand.cpp
+++ b/src/utils/debugger/SkDrawCommand.cpp
@@ -14,10 +14,12 @@
 
 SkDrawCommand::SkDrawCommand(DrawType type)
     : fDrawType(type)
+    , fOffset(0)
     , fVisible(true) {
 }
 
 SkDrawCommand::SkDrawCommand() {
+    fOffset = 0;
     fVisible = true;
 }
 
@@ -80,9 +82,8 @@
     return SkString(GetCommandString(fDrawType));
 }
 
-SkClearCommand::SkClearCommand(SkColor color) {
+SkClearCommand::SkClearCommand(SkColor color) : INHERITED(DRAW_CLEAR) {
     fColor = color;
-    fDrawType = DRAW_CLEAR;
     fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
 }
 
@@ -192,11 +193,11 @@
 };
 
 
-SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkRegion::Op op, bool doAA) {
+SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkRegion::Op op, bool doAA)
+    : INHERITED(CLIP_PATH) {
     fPath = path;
     fOp = op;
     fDoAA = doAA;
-    fDrawType = CLIP_PATH;
 
     fInfo.push(SkObjectParser::PathToString(path));
     fInfo.push(SkObjectParser::RegionOpToString(op));
@@ -212,10 +213,10 @@
     return true;
 }
 
-SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkRegion::Op op) {
+SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkRegion::Op op) 
+    : INHERITED(CLIP_REGION) {
     fRegion = region;
     fOp = op;
-    fDrawType = CLIP_REGION;
 
     fInfo.push(SkObjectParser::RegionToString(region));
     fInfo.push(SkObjectParser::RegionOpToString(op));
@@ -225,11 +226,11 @@
     canvas->clipRegion(fRegion, fOp);
 }
 
-SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkRegion::Op op, bool doAA) {
+SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkRegion::Op op, bool doAA)
+    : INHERITED(CLIP_RECT) {
     fRect = rect;
     fOp = op;
     fDoAA = doAA;
-    fDrawType = CLIP_RECT;
 
     fInfo.push(SkObjectParser::RectToString(rect));
     fInfo.push(SkObjectParser::RegionOpToString(op));
@@ -240,11 +241,11 @@
     canvas->clipRect(fRect, fOp, fDoAA);
 }
 
-SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkRegion::Op op, bool doAA) 
+    : INHERITED(CLIP_RRECT) {
     fRRect = rrect;
     fOp = op;
     fDoAA = doAA;
-    fDrawType = CLIP_RRECT;
 
     fInfo.push(SkObjectParser::RRectToString(rrect));
     fInfo.push(SkObjectParser::RegionOpToString(op));
@@ -260,9 +261,9 @@
     return true;
 }
 
-SkConcatCommand::SkConcatCommand(const SkMatrix& matrix) {
+SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
+    : INHERITED(CONCAT) {
     fMatrix = matrix;
-    fDrawType = CONCAT;
 
     fInfo.push(SkObjectParser::MatrixToString(matrix));
 }
@@ -272,7 +273,8 @@
 }
 
 SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
-                       const SkPaint* paint) {
+                       const SkPaint* paint) 
+    : INHERITED(DRAW_BITMAP) {
     fBitmap = bitmap;
     fLeft = left;
     fTop = top;
@@ -282,7 +284,6 @@
     } else {
         fPaintPtr = NULL;
     }
-    fDrawType = DRAW_BITMAP;
 
     fInfo.push(SkObjectParser::BitmapToString(bitmap));
     fInfo.push(SkObjectParser::ScalarToString(left, "SkScalar left: "));
@@ -303,7 +304,8 @@
 
 SkDrawBitmapMatrixCommand::SkDrawBitmapMatrixCommand(const SkBitmap& bitmap,
                                                      const SkMatrix& matrix,
-                                                     const SkPaint* paint) {
+                                                     const SkPaint* paint) 
+    : INHERITED(DRAW_BITMAP_MATRIX) {
     fBitmap = bitmap;
     fMatrix = matrix;
     if (NULL != paint) {
@@ -312,7 +314,6 @@
     } else {
         fPaintPtr = NULL;
     }
-    fDrawType = DRAW_BITMAP_MATRIX;
 
     fInfo.push(SkObjectParser::BitmapToString(bitmap));
     fInfo.push(SkObjectParser::MatrixToString(matrix));
@@ -331,7 +332,8 @@
 }
 
 SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
-                                                 const SkRect& dst, const SkPaint* paint) {
+                                                 const SkRect& dst, const SkPaint* paint) 
+    : INHERITED(DRAW_BITMAP_NINE) {
     fBitmap = bitmap;
     fCenter = center;
     fDst = dst;
@@ -341,7 +343,6 @@
     } else {
         fPaintPtr = NULL;
     }
-    fDrawType = DRAW_BITMAP_NINE;
 
     fInfo.push(SkObjectParser::BitmapToString(bitmap));
     fInfo.push(SkObjectParser::IRectToString(center));
@@ -362,7 +363,8 @@
 
 SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
                                                  const SkRect& dst, const SkPaint* paint,
-                                                 SkCanvas::DrawBitmapRectFlags flags) {
+                                                 SkCanvas::DrawBitmapRectFlags flags) 
+    : INHERITED(DRAW_BITMAP_RECT_TO_RECT) {
     fBitmap = bitmap;
     if (NULL != src) {
         fSrc = *src;
@@ -379,8 +381,6 @@
     }
     fFlags = flags;
 
-    fDrawType = DRAW_BITMAP_RECT_TO_RECT;
-
     fInfo.push(SkObjectParser::BitmapToString(bitmap));
     if (NULL != src) {
         fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
@@ -401,11 +401,11 @@
     return true;
 }
 
-SkDrawDataCommand::SkDrawDataCommand(const void* data, size_t length) {
+SkDrawDataCommand::SkDrawDataCommand(const void* data, size_t length) 
+    : INHERITED(DRAW_DATA) {
     fData = new char[length];
     memcpy(fData, data, length);
     fLength = length;
-    fDrawType = DRAW_DATA;
 
     // TODO: add display of actual data?
     SkString* str = new SkString;
@@ -434,13 +434,14 @@
     fInfo.push(temp);
 }
 
-SkEndCommentGroupCommand::SkEndCommentGroupCommand() : INHERITED(END_COMMENT_GROUP) {
+SkEndCommentGroupCommand::SkEndCommentGroupCommand() 
+    : INHERITED(END_COMMENT_GROUP) {
 }
 
-SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint) {
+SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
+    : INHERITED(DRAW_OVAL) {
     fOval = oval;
     fPaint = paint;
-    fDrawType = DRAW_OVAL;
 
     fInfo.push(SkObjectParser::RectToString(oval));
     fInfo.push(SkObjectParser::PaintToString(paint));
@@ -466,9 +467,9 @@
     return true;
 }
 
-SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint) {
+SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
+    : INHERITED(DRAW_PAINT) {
     fPaint = paint;
-    fDrawType = DRAW_PAINT;
 
     fInfo.push(SkObjectParser::PaintToString(paint));
 }
@@ -483,10 +484,10 @@
     return true;
 }
 
-SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint) {
+SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
+    : INHERITED(DRAW_PATH) {
     fPath = path;
     fPaint = paint;
-    fDrawType = DRAW_PATH;
 
     fInfo.push(SkObjectParser::PathToString(path));
     fInfo.push(SkObjectParser::PaintToString(paint));
@@ -501,9 +502,9 @@
     return true;
 }
 
-SkDrawPictureCommand::SkDrawPictureCommand(SkPicture& picture) :
-    fPicture(picture) {
-    fDrawType = DRAW_PICTURE;
+SkDrawPictureCommand::SkDrawPictureCommand(SkPicture& picture) 
+    : INHERITED(DRAW_PICTURE)
+    , fPicture(picture) {
     SkString* temp = new SkString;
     temp->appendf("SkPicture: W: %d H: %d", picture.width(), picture.height());
     fInfo.push(temp);
@@ -529,13 +530,13 @@
 }
 
 SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
-                                         const SkPoint pts[], const SkPaint& paint) {
+                                         const SkPoint pts[], const SkPaint& paint)
+    : INHERITED(DRAW_POINTS) {
     fMode = mode;
     fCount = count;
     fPts = new SkPoint[count];
     memcpy(fPts, pts, count * sizeof(SkPoint));
     fPaint = paint;
-    fDrawType = DRAW_POINTS;
 
     fInfo.push(SkObjectParser::PointsToString(pts, count));
     fInfo.push(SkObjectParser::ScalarToString(SkIntToScalar((unsigned int)count),
@@ -572,7 +573,8 @@
 }
 
 SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
-                                           const SkPoint pos[], const SkPaint& paint) {
+                                           const SkPoint pos[], const SkPaint& paint)
+    : INHERITED(DRAW_POS_TEXT) {
     size_t numPts = paint.countText(text, byteLength);
 
     fText = new char[byteLength];
@@ -583,7 +585,6 @@
     memcpy(fPos, pos, numPts * sizeof(SkPoint));
 
     fPaint = paint;
-    fDrawType = DRAW_POS_TEXT;
 
     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
     // TODO(chudy): Test that this works.
@@ -598,7 +599,8 @@
 
 SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
                                              const SkScalar xpos[], SkScalar constY,
-                                             const SkPaint& paint) {
+                                             const SkPaint& paint)
+    : INHERITED(DRAW_POS_TEXT_H) {
     size_t numPts = paint.countText(text, byteLength);
 
     fText = new char[byteLength];
@@ -610,7 +612,6 @@
 
     fConstY = constY;
     fPaint = paint;
-    fDrawType = DRAW_POS_TEXT_H;
 
     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
     fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: "));
@@ -622,10 +623,10 @@
     canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
 }
 
-SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint) {
+SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
+    : INHERITED(DRAW_RECT) {
     fRect = rect;
     fPaint = paint;
-    fDrawType = DRAW_RECT;
 
     fInfo.push(SkObjectParser::RectToString(rect));
     fInfo.push(SkObjectParser::PaintToString(paint));
@@ -635,10 +636,10 @@
     canvas->drawRect(fRect, fPaint);
 }
 
-SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint) {
+SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
+    : INHERITED(DRAW_RRECT) {
     fRRect = rrect;
     fPaint = paint;
-    fDrawType = DRAW_RRECT;
 
     fInfo.push(SkObjectParser::RRectToString(rrect));
     fInfo.push(SkObjectParser::PaintToString(paint));
@@ -655,11 +656,11 @@
 
 SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
                                          const SkRRect& inner,
-                                         const SkPaint& paint) {
+                                         const SkPaint& paint)
+    : INHERITED(DRAW_DRRECT) {
     fOuter = outer;
     fInner = inner;
     fPaint = paint;
-    fDrawType = DRAW_DRRECT;
 
     fInfo.push(SkObjectParser::RRectToString(outer));
     fInfo.push(SkObjectParser::RRectToString(inner));
@@ -676,7 +677,8 @@
 }
 
 SkDrawSpriteCommand::SkDrawSpriteCommand(const SkBitmap& bitmap, int left, int top,
-                                         const SkPaint* paint) {
+                                         const SkPaint* paint)
+    : INHERITED(DRAW_SPRITE) {
     fBitmap = bitmap;
     fLeft = left;
     fTop = top;
@@ -686,7 +688,6 @@
     } else {
         fPaintPtr = NULL;
     }
-    fDrawType = DRAW_SPRITE;
 
     fInfo.push(SkObjectParser::BitmapToString(bitmap));
     fInfo.push(SkObjectParser::IntToString(left, "Left: "));
@@ -706,14 +707,14 @@
 }
 
 SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
-                                     const SkPaint& paint) {
+                                     const SkPaint& paint)
+    : INHERITED(DRAW_TEXT) {
     fText = new char[byteLength];
     memcpy(fText, text, byteLength);
     fByteLength = byteLength;
     fX = x;
     fY = y;
     fPaint = paint;
-    fDrawType = DRAW_TEXT;
 
     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
     fInfo.push(SkObjectParser::ScalarToString(x, "SkScalar x: "));
@@ -727,7 +728,8 @@
 
 SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
                                                  const SkPath& path, const SkMatrix* matrix,
-                                                 const SkPaint& paint) {
+                                                 const SkPaint& paint)
+    : INHERITED(DRAW_TEXT_ON_PATH) {
     fText = new char[byteLength];
     memcpy(fText, text, byteLength);
     fByteLength = byteLength;
@@ -738,7 +740,6 @@
         fMatrix.setIdentity();
     }
     fPaint = paint;
-    fDrawType = DRAW_TEXT_ON_PATH;
 
     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
     fInfo.push(SkObjectParser::PathToString(path));
@@ -758,7 +759,8 @@
                                              const SkPoint vertices[], const SkPoint texs[],
                                              const SkColor colors[], SkXfermode* xfermode,
                                              const uint16_t indices[], int indexCount,
-                                             const SkPaint& paint) {
+                                             const SkPaint& paint)
+    : INHERITED(DRAW_VERTICES) {
     fVmode = vmode;
 
     fVertexCount = vertexCount;
@@ -794,7 +796,6 @@
 
     fIndexCount = indexCount;
     fPaint = paint;
-    fDrawType = DRAW_VERTICES;
 
     // TODO(chudy)
     fInfo.push(SkObjectParser::CustomTextToString("To be implemented."));
@@ -815,8 +816,8 @@
                          fIndexCount, fPaint);
 }
 
-SkRestoreCommand::SkRestoreCommand() {
-    fDrawType = RESTORE;
+SkRestoreCommand::SkRestoreCommand()
+    : INHERITED(RESTORE) {
     fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
 }
 
@@ -828,9 +829,9 @@
     (*state)--;
 }
 
-SkRotateCommand::SkRotateCommand(SkScalar degrees) {
+SkRotateCommand::SkRotateCommand(SkScalar degrees)
+    : INHERITED(ROTATE) {
     fDegrees = degrees;
-    fDrawType = ROTATE;
 
     fInfo.push(SkObjectParser::ScalarToString(degrees, "SkScalar degrees: "));
 }
@@ -839,9 +840,9 @@
     canvas->rotate(fDegrees);
 }
 
-SkSaveCommand::SkSaveCommand(SkCanvas::SaveFlags flags) {
+SkSaveCommand::SkSaveCommand(SkCanvas::SaveFlags flags)
+    : INHERITED(SAVE) {
     fFlags = flags;
-    fDrawType = SAVE;
     fInfo.push(SkObjectParser::SaveFlagsToString(flags));
 }
 
@@ -854,7 +855,8 @@
 }
 
 SkSaveLayerCommand::SkSaveLayerCommand(const SkRect* bounds, const SkPaint* paint,
-                                       SkCanvas::SaveFlags flags) {
+                                       SkCanvas::SaveFlags flags)
+    : INHERITED(SAVE_LAYER) {
     if (NULL != bounds) {
         fBounds = *bounds;
     } else {
@@ -868,7 +870,6 @@
         fPaintPtr = NULL;
     }
     fFlags = flags;
-    fDrawType = SAVE_LAYER;
 
     if (NULL != bounds) {
         fInfo.push(SkObjectParser::RectToString(*bounds, "Bounds: "));
@@ -893,10 +894,10 @@
     (*state)++;
 }
 
-SkScaleCommand::SkScaleCommand(SkScalar sx, SkScalar sy) {
+SkScaleCommand::SkScaleCommand(SkScalar sx, SkScalar sy)
+    : INHERITED(SCALE) {
     fSx = sx;
     fSy = sy;
-    fDrawType = SCALE;
 
     fInfo.push(SkObjectParser::ScalarToString(sx, "SkScalar sx: "));
     fInfo.push(SkObjectParser::ScalarToString(sy, "SkScalar sy: "));
@@ -906,9 +907,9 @@
     canvas->scale(fSx, fSy);
 }
 
-SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix) {
+SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
+    : INHERITED(SET_MATRIX) {
     fMatrix = matrix;
-    fDrawType = SET_MATRIX;
 
     fInfo.push(SkObjectParser::MatrixToString(matrix));
 }
@@ -917,10 +918,10 @@
     canvas->setMatrix(fMatrix);
 }
 
-SkSkewCommand::SkSkewCommand(SkScalar sx, SkScalar sy) {
+SkSkewCommand::SkSkewCommand(SkScalar sx, SkScalar sy)
+    : INHERITED(SKEW) {
     fSx = sx;
     fSy = sy;
-    fDrawType = SKEW;
 
     fInfo.push(SkObjectParser::ScalarToString(sx, "SkScalar sx: "));
     fInfo.push(SkObjectParser::ScalarToString(sy, "SkScalar sy: "));
@@ -930,10 +931,10 @@
     canvas->skew(fSx, fSy);
 }
 
-SkTranslateCommand::SkTranslateCommand(SkScalar dx, SkScalar dy) {
+SkTranslateCommand::SkTranslateCommand(SkScalar dx, SkScalar dy)
+    : INHERITED(TRANSLATE) {
     fDx = dx;
     fDy = dy;
-    fDrawType = TRANSLATE;
 
     fInfo.push(SkObjectParser::ScalarToString(dx, "SkScalar dx: "));
     fInfo.push(SkObjectParser::ScalarToString(dy, "SkScalar dy: "));
@@ -944,8 +945,8 @@
 }
 
 SkPushCullCommand::SkPushCullCommand(const SkRect& cullRect)
-    : fCullRect(cullRect) {
-    fDrawType = PUSH_CULL;
+    : INHERITED(PUSH_CULL)
+    , fCullRect(cullRect) {
     fInfo.push(SkObjectParser::RectToString(cullRect));
 }
 
@@ -962,9 +963,7 @@
     canvas->drawRect(fCullRect, p);
 }
 
-SkPopCullCommand::SkPopCullCommand() {
-    fDrawType = POP_CULL;
-}
+SkPopCullCommand::SkPopCullCommand() : INHERITED(POP_CULL) { }
 
 void SkPopCullCommand::execute(SkCanvas* canvas) {
     canvas->popCull();
diff --git a/src/utils/debugger/SkDrawCommand.h b/src/utils/debugger/SkDrawCommand.h
index 3c40393..f2e151a 100644
--- a/src/utils/debugger/SkDrawCommand.h
+++ b/src/utils/debugger/SkDrawCommand.h
@@ -23,6 +23,9 @@
 
     virtual SkString toString();
 
+    void setOffset(size_t offset) { fOffset = offset; }
+    virtual size_t offset() { return fOffset; }
+
     virtual const char* toCString() {
         return GetCommandString(fDrawType);
     }
@@ -46,13 +49,13 @@
     // pushCull and popCull. It is used in two ways:
     // To determine which saveLayers are currently active (at a
     // given point in the rendering).
-    //      save just return a kPushLayer action but don't track active state
-    //      restore just return a kPopLayer action
+    //      saves just return a kPushLayer action but don't track active state
+    //      restores just return a kPopLayer action
     //      saveLayers return kPushLayer but also track the active state
     // To determine which culls are currently active (at a given point)
     // in the rendering).
-    //      pushCull returns a kPushCull action
-    //      popCull  returns a kPopCull action
+    //      pushCulls return a kPushCull action
+    //      popCulls  return a kPopCull action
     enum Action {
         kNone_Action,
         kPopLayer_Action,
@@ -71,11 +74,12 @@
     static const char* GetCommandString(DrawType type);
 
 protected:
-    DrawType fDrawType;
     SkTDArray<SkString*> fInfo;
 
 private:
-    bool fVisible;
+    DrawType fDrawType;
+    size_t fOffset;
+    bool   fVisible;
 };
 
 class SkRestoreCommand : public SkDrawCommand {
@@ -171,7 +175,7 @@
 class SkDrawBitmapCommand : public SkDrawCommand {
 public:
     SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
-               const SkPaint* paint);
+                        const SkPaint* paint);
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
 private:
@@ -187,7 +191,7 @@
 class SkDrawBitmapMatrixCommand : public SkDrawCommand {
 public:
     SkDrawBitmapMatrixCommand(const SkBitmap& bitmap, const SkMatrix& matrix,
-                     const SkPaint* paint);
+                              const SkPaint* paint);
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
 private:
@@ -202,7 +206,7 @@
 class SkDrawBitmapNineCommand : public SkDrawCommand {
 public:
     SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
-                   const SkRect& dst, const SkPaint* paint);
+                            const SkRect& dst, const SkPaint* paint);
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
 private:
@@ -352,7 +356,7 @@
 class SkDrawPointsCommand : public SkDrawCommand {
 public:
     SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
-               const SkPaint& paint);
+                        const SkPaint& paint);
     virtual ~SkDrawPointsCommand() { delete [] fPts; }
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
@@ -368,7 +372,7 @@
 class SkDrawTextCommand : public SkDrawCommand {
 public:
     SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
-              const SkPaint& paint);
+                      const SkPaint& paint);
     virtual ~SkDrawTextCommand() { delete [] fText; }
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
 private: