First pass at Comment API
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 29 May 2013 13:24:23 +0000 (13:24 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 29 May 2013 13:24:23 +0000 (13:24 +0000)
https://codereview.chromium.org/13957009/

git-svn-id: http://skia.googlecode.com/svn/trunk@9310 2bbb7eff-a529-9590-31e7-b0007b416f81

18 files changed:
debugger/QT/SkDebuggerGUI.cpp
debugger/SkDebugCanvas.cpp
debugger/SkDebugCanvas.h
debugger/SkDrawCommand.cpp
debugger/SkDrawCommand.h
gm/rects.cpp
include/core/SkCanvas.h
include/utils/SkDumpCanvas.h
include/utils/SkProxyCanvas.h
src/core/SkCanvas.cpp
src/core/SkPictureFlat.h
src/core/SkPicturePlayback.cpp
src/core/SkPictureRecord.cpp
src/core/SkPictureRecord.h
src/pipe/SkGPipeWrite.cpp
src/utils/SkDumpCanvas.cpp
src/utils/SkProxyCanvas.cpp
tests/CanvasTest.cpp

index a64870d..60ef7e9 100644 (file)
@@ -959,14 +959,16 @@ void SkDebuggerGUI::setupListWidget(SkTArray<SkString>* command) {
         item->setData(Qt::DisplayRole, (*command)[i].c_str());
         item->setData(Qt::UserRole + 1, counter++);
 
-        if (0 == strcmp("Restore", (*command)[i].c_str())) {
+        if (0 == strcmp("Restore", (*command)[i].c_str()) ||
+            0 == strcmp("EndCommentGroup", (*command)[i].c_str())) {
             indent -= 10;
         }
 
         item->setData(Qt::UserRole + 3, indent);
 
         if (0 == strcmp("Save", (*command)[i].c_str()) ||
-            0 == strcmp("Save Layer", (*command)[i].c_str())) {
+            0 == strcmp("Save Layer", (*command)[i].c_str()) ||
+            0 == strcmp("BeginCommentGroup", (*command)[i].c_str())) {
             indent += 10;
         }
 
index 5d67953..9d34063 100644 (file)
@@ -389,6 +389,18 @@ void SkDebugCanvas::drawData(const void* data, size_t length) {
     addDrawCommand(new DrawData(data, length));
 }
 
+void SkDebugCanvas::beginCommentGroup(const char* description) {
+    addDrawCommand(new BeginCommentGroup(description));
+}
+
+void SkDebugCanvas::addComment(const char* kywd, const char* value) {
+    addDrawCommand(new Comment(kywd, value));
+}
+
+void SkDebugCanvas::endCommentGroup() {
+    addDrawCommand(new EndCommentGroup());
+}
+
 void SkDebugCanvas::drawOval(const SkRect& oval, const SkPaint& paint) {
     addDrawCommand(new DrawOval(oval, paint));
 }
index 841d3c9..bcb2bbf 100644 (file)
@@ -171,6 +171,12 @@ public:
 
     virtual void drawData(const void*, size_t) SK_OVERRIDE;
 
+    virtual void beginCommentGroup(const char* description) SK_OVERRIDE;
+
+    virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE;
+
+    virtual void endCommentGroup() SK_OVERRIDE;
+
     virtual void drawOval(const SkRect& oval, const SkPaint&) SK_OVERRIDE;
 
     virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
index 8489397..0504fb5 100644 (file)
 
 // TODO(chudy): Refactor into non subclass model.
 
+SkDrawCommand::SkDrawCommand(DrawType type) 
+    : fDrawType(type)
+    , fVisible(true) {
+}
+
 SkDrawCommand::SkDrawCommand() {
     fVisible = true;
 }
@@ -56,6 +61,9 @@ const char* SkDrawCommand::GetCommandString(DrawType type) {
         case SKEW: return "Skew";
         case TRANSLATE: return "Translate";
         case NOOP: return "NoOp";
+        case BEGIN_COMMENT_GROUP: return "BeginCommentGroup";
+        case COMMENT: return "Comment";
+        case END_COMMENT_GROUP: return "EndCommentGroup";
         default:
             SkDebugf("DrawType error 0x%08x\n", type);
             SkASSERT(0);
@@ -298,6 +306,26 @@ void DrawData::execute(SkCanvas* canvas) {
     canvas->drawData(fData, fLength);
 }
 
+BeginCommentGroup::BeginCommentGroup(const char* description) 
+    : INHERITED(BEGIN_COMMENT_GROUP)
+    , fDescription(description) {
+    SkString* temp = new SkString;
+    temp->appendf("Description: %s", description);
+    fInfo.push(temp);
+}
+
+Comment::Comment(const char* kywd, const char* value)
+    : INHERITED(COMMENT)
+    , fKywd(kywd)
+    , fValue(value) {
+    SkString* temp = new SkString;
+    temp->appendf("%s: %s", kywd, value);
+    fInfo.push(temp);
+}
+
+EndCommentGroup::EndCommentGroup() : INHERITED(END_COMMENT_GROUP) {
+}
+
 DrawOval::DrawOval(const SkRect& oval, const SkPaint& paint) {
     fOval = oval;
     fPaint = paint;
index 02a4afe..e73295a 100644 (file)
 
 #include "SkPictureFlat.h"
 #include "SkCanvas.h"
+#include "SkString.h"
 
 class SkDrawCommand {
 public:
     /* TODO(chudy): Remove subclasses. */
+    SkDrawCommand(DrawType drawType);
     SkDrawCommand();
 
     virtual ~SkDrawCommand();
@@ -240,6 +242,41 @@ private:
     typedef SkDrawCommand INHERITED;
 };
 
+class BeginCommentGroup : public SkDrawCommand {
+public:
+    BeginCommentGroup(const char* description);
+    virtual void execute(SkCanvas* canvas) SK_OVERRIDE {
+        canvas->beginCommentGroup(fDescription.c_str());
+    };
+private:
+    SkString fDescription;
+
+    typedef SkDrawCommand INHERITED;
+};
+
+class Comment : public SkDrawCommand {
+public:
+    Comment(const char* kywd, const char* value);
+    virtual void execute(SkCanvas* canvas) SK_OVERRIDE {
+        canvas->addComment(fKywd.c_str(), fValue.c_str());
+    };
+private:
+    SkString fKywd;
+    SkString fValue;
+
+    typedef SkDrawCommand INHERITED;
+};
+
+class EndCommentGroup : public SkDrawCommand {
+public:
+    EndCommentGroup();
+    virtual void execute(SkCanvas* canvas) SK_OVERRIDE {
+        canvas->endCommentGroup();
+    };
+private:
+    typedef SkDrawCommand INHERITED;
+};
+
 class DrawOval : public SkDrawCommand {
 public:
     DrawOval(const SkRect& oval, const SkPaint& paint);
index 3816f9e..eee92b3 100644 (file)
@@ -207,10 +207,14 @@ protected:
     }
 
     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        SkAutoCommentBlock acb(canvas, "onDraw");
+
         canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1);
 
         int testCount = 0;
 
+        canvas->addComment("Test", "Various Paints");
+
         for (int i = 0; i < fPaints.count(); ++i) {
             for (int j = 0; j < fRects.count(); ++j, ++testCount) {
                 canvas->save();
@@ -220,6 +224,8 @@ protected:
             }
         }
 
+        canvas->addComment("Test", "Matrices");
+
         SkPaint paint;
         paint.setColor(SK_ColorWHITE);
         paint.setAntiAlias(true);
index 2bf5a54..821f86b 100644 (file)
@@ -852,7 +852,24 @@ public:
         subclasses like SkPicture's recording canvas, that can store the data
         and then play it back later (via another call to drawData).
      */
-    virtual void drawData(const void* data, size_t length);
+    virtual void drawData(const void* data, size_t length) {
+        // do nothing. Subclasses may do something with the data
+    }
+
+    /** Add comments. beginCommentGroup/endCommentGroup open/close a new group. 
+        Each comment added via addComment is notionally attached to its 
+        enclosing group. Top-level comments simply belong to no group.
+     */
+    virtual void beginCommentGroup(const char* description) {
+        // do nothing. Subclasses may do something
+    }
+    virtual void addComment(const char* kywd, const char* value) {
+        // do nothing. Subclasses may do something
+    }
+    virtual void endCommentGroup() {
+        // do nothing. Subclasses may do something
+    }
+
 
     //////////////////////////////////////////////////////////////////////////
 
@@ -1138,4 +1155,25 @@ private:
     int         fSaveCount;
 };
 
+/** Stack helper class to automatically open and close a comment block
+ */
+class SkAutoCommentBlock : SkNoncopyable {
+public:
+    SkAutoCommentBlock(SkCanvas* canvas, const char* description) {
+        fCanvas = canvas;
+        if (NULL != fCanvas) {
+            fCanvas->beginCommentGroup(description);
+        }
+    }
+
+    ~SkAutoCommentBlock() {
+        if (NULL != fCanvas) {
+            fCanvas->endCommentGroup();
+        }
+    }
+
+private:
+    SkCanvas* fCanvas;
+};
+
 #endif
index 8d9c67d..cdb1f19 100644 (file)
@@ -45,7 +45,11 @@ public:
         kDrawText_Verb,
         kDrawPicture_Verb,
         kDrawVertices_Verb,
-        kDrawData_Verb
+        kDrawData_Verb,
+
+        kBeginCommentGroup_Verb,
+        kAddComment_Verb,
+        kEndCommentGroup_Verb
     };
 
     /** Subclasses of this are installed on the DumpCanvas, and then called for
@@ -117,6 +121,9 @@ public:
                               const uint16_t indices[], int indexCount,
                               const SkPaint& paint) SK_OVERRIDE;
     virtual void drawData(const void*, size_t) SK_OVERRIDE;
+    virtual void beginCommentGroup(const char* description) SK_OVERRIDE;
+    virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE;
+    virtual void endCommentGroup() SK_OVERRIDE;
 
 private:
     Dumper* fDumper;
index bd260c7..71187d1 100644 (file)
@@ -77,6 +77,10 @@ public:
                               const SkPaint& paint) SK_OVERRIDE;
     virtual void drawData(const void* data, size_t length) SK_OVERRIDE;
 
+    virtual void beginCommentGroup(const char* description) SK_OVERRIDE;
+    virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE;
+    virtual void endCommentGroup() SK_OVERRIDE;
+
     virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE;
     virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
 
index df2a0f9..e26007f 100644 (file)
@@ -2010,10 +2010,6 @@ void SkCanvas::drawVertices(VertexMode vmode, int vertexCount,
     LOOPER_END
 }
 
-void SkCanvas::drawData(const void* data, size_t length) {
-    // do nothing. Subclasses may do something with the data
-}
-
 //////////////////////////////////////////////////////////////////////////////
 // These methods are NOT virtual, and therefore must call back into virtual
 // methods, rather than actually drawing themselves.
index b513271..0a147de 100644 (file)
@@ -62,8 +62,11 @@ enum DrawType {
     SKEW,
     TRANSLATE,
     NOOP,
+    BEGIN_COMMENT_GROUP,
+    COMMENT,
+    END_COMMENT_GROUP,
 
-    LAST_DRAWTYPE_ENUM = NOOP
+    LAST_DRAWTYPE_ENUM = END_COMMENT_GROUP
 };
 
 // In the 'match' method, this constant will match any flavor of DRAW_BITMAP*
index e4f041f..898d379 100644 (file)
@@ -858,6 +858,18 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback)
                 canvas.drawData(reader.skip(length), length);
                 // skip handles padding the read out to a multiple of 4
             } break;
+            case BEGIN_COMMENT_GROUP: {
+                const char* desc = reader.readString();
+                canvas.beginCommentGroup(desc);
+            } break;
+            case COMMENT: {
+                const char* kywd = reader.readString();
+                const char* value = reader.readString();
+                canvas.addComment(kywd, value);
+            } break;
+            case END_COMMENT_GROUP: {
+                canvas.endCommentGroup();
+            } break;
             case DRAW_OVAL: {
                 const SkPaint& paint = *getPaint(reader);
                 canvas.drawOval(reader.skipT<SkRect>(), paint);
index f405c3a..fc85028 100644 (file)
@@ -106,6 +106,9 @@ static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) {
         0,  // SKEW - no paint
         0,  // TRANSLATE - no paint
         0,  // NOOP - no paint
+        0,  // BEGIN_GROUP - no paint
+        0,  // COMMENT - no paint
+        0,  // END_GROUP - no paint
     };
 
     SkASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1);
@@ -1276,6 +1279,33 @@ void SkPictureRecord::drawData(const void* data, size_t length) {
     validate(initialOffset, size);
 }
 
+void SkPictureRecord::beginCommentGroup(const char* description) {
+    // op/size + length of string + \0 terminated chars
+    int length = strlen(description);
+    uint32_t size = 2 * kUInt32Size + SkAlign4(length + 1);
+    uint32_t initialOffset = this->addDraw(BEGIN_COMMENT_GROUP, &size);
+    fWriter.writeString(description, length);
+    validate(initialOffset, size);
+}
+
+void SkPictureRecord::addComment(const char* kywd, const char* value) {
+    // op/size + 2x length of string + 2x \0 terminated chars
+    int kywdLen = strlen(kywd);
+    int valueLen = strlen(value);
+    uint32_t size = 3 * kUInt32Size + SkAlign4(kywdLen + 1) + SkAlign4(valueLen + 1);
+    uint32_t initialOffset = this->addDraw(COMMENT, &size);
+    fWriter.writeString(kywd, kywdLen);
+    fWriter.writeString(value, valueLen);
+    validate(initialOffset, size);
+}
+
+void SkPictureRecord::endCommentGroup() {
+    // op/size
+    uint32_t size = 1 * kUInt32Size;
+    uint32_t initialOffset = this->addDraw(END_COMMENT_GROUP, &size);
+    validate(initialOffset, size);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) {
index 6245b78..95ce5d2 100644 (file)
@@ -82,6 +82,9 @@ public:
                           const uint16_t indices[], int indexCount,
                               const SkPaint&) SK_OVERRIDE;
     virtual void drawData(const void*, size_t) SK_OVERRIDE;
+    virtual void beginCommentGroup(const char* description) SK_OVERRIDE;
+    virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE;
+    virtual void endCommentGroup() SK_OVERRIDE;
     virtual bool isDrawingToLayer() const SK_OVERRIDE;
 
     void addFontMetricsTopBottom(const SkPaint& paint, const SkFlatData&,
index 32786fd..3b22a5e 100644 (file)
@@ -255,6 +255,9 @@ public:
                           const uint16_t indices[], int indexCount,
                               const SkPaint&) SK_OVERRIDE;
     virtual void drawData(const void*, size_t) SK_OVERRIDE;
+    virtual void beginCommentGroup(const char* description) SK_OVERRIDE;
+    virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE;
+    virtual void endCommentGroup() SK_OVERRIDE;
 
     /**
      * Flatten an SkBitmap to send to the reader, where it will be referenced
@@ -970,6 +973,18 @@ void SkGPipeCanvas::drawData(const void* ptr, size_t size) {
     }
 }
 
+void SkGPipeCanvas::beginCommentGroup(const char* description) {
+    // ignore for now
+}
+
+void SkGPipeCanvas::addComment(const char* kywd, const char* value) {
+    // ignore for now
+}
+
+void SkGPipeCanvas::endCommentGroup() {
+    // ignore for now
+}
+
 void SkGPipeCanvas::flushRecording(bool detachCurrentBlock) {
     doNotify();
     if (detachCurrentBlock) {
index 46c4141..87ddd31 100644 (file)
@@ -442,6 +442,18 @@ void SkDumpCanvas::drawData(const void* data, size_t length) {
                SkMin32(length, 64), data);
 }
 
+void SkDumpCanvas::beginCommentGroup(const char* description) {
+    this->dump(kBeginCommentGroup_Verb, NULL, "beginCommentGroup(%s)", description);
+}
+
+void SkDumpCanvas::addComment(const char* kywd, const char* value) {
+    this->dump(kAddComment_Verb, NULL, "addComment(%s, %s)", kywd, value);
+}
+
+void SkDumpCanvas::endCommentGroup() {
+    this->dump(kEndCommentGroup_Verb, NULL, "endCommentGroup()");
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
index 057f1df..053a757 100644 (file)
@@ -158,6 +158,18 @@ void SkProxyCanvas::drawData(const void* data, size_t length) {
     fProxy->drawData(data, length);
 }
 
+void SkProxyCanvas::beginCommentGroup(const char* description) {
+    fProxy->beginCommentGroup(description);
+}
+
+void SkProxyCanvas::addComment(const char* kywd, const char* value) {
+    fProxy->addComment(kywd, value);
+}
+
+void SkProxyCanvas::endCommentGroup() {
+    fProxy->endCommentGroup();
+}
+
 SkBounder* SkProxyCanvas::setBounder(SkBounder* bounder) {
     return fProxy->setBounder(bounder);
 }
index e692de1..e45efa6 100644 (file)
@@ -339,6 +339,9 @@ SIMPLE_TEST_STEP(DrawTextOnPath, drawTextOnPath(kTestText.c_str(),
 SIMPLE_TEST_STEP(DrawTextOnPathMatrix, drawTextOnPath(kTestText.c_str(),
     kTestText.size(), kTestPath, &kTestMatrix, kTestPaint));
 SIMPLE_TEST_STEP(DrawData, drawData(kTestText.c_str(), kTestText.size()));
+SIMPLE_TEST_STEP(BeginGroup, beginCommentGroup(kTestText.c_str()));
+SIMPLE_TEST_STEP(AddComment, addComment(kTestText.c_str(), kTestText.c_str()));
+SIMPLE_TEST_STEP(EndGroup, endCommentGroup());
 
 ///////////////////////////////////////////////////////////////////////////////
 // Complex test steps