From 0a4805e33f8ddb445a2fd061462e715e1707f049 Mon Sep 17 00:00:00 2001 From: "robertphillips@google.com" Date: Wed, 29 May 2013 13:24:23 +0000 Subject: [PATCH] First pass at Comment API https://codereview.chromium.org/13957009/ git-svn-id: http://skia.googlecode.com/svn/trunk@9310 2bbb7eff-a529-9590-31e7-b0007b416f81 --- debugger/QT/SkDebuggerGUI.cpp | 6 +++-- debugger/SkDebugCanvas.cpp | 12 ++++++++++ debugger/SkDebugCanvas.h | 6 +++++ debugger/SkDrawCommand.cpp | 28 ++++++++++++++++++++++++ debugger/SkDrawCommand.h | 37 +++++++++++++++++++++++++++++++ gm/rects.cpp | 6 +++++ include/core/SkCanvas.h | 40 +++++++++++++++++++++++++++++++++- include/utils/SkDumpCanvas.h | 9 +++++++- include/utils/SkProxyCanvas.h | 4 ++++ src/core/SkCanvas.cpp | 4 ---- src/core/SkPictureFlat.h | 5 ++++- src/core/SkPicturePlayback.cpp | 12 ++++++++++ src/core/SkPictureRecord.cpp | 30 +++++++++++++++++++++++++ src/core/SkPictureRecord.h | 3 +++ src/pipe/SkGPipeWrite.cpp | 15 +++++++++++++ src/utils/SkDumpCanvas.cpp | 12 ++++++++++ src/utils/SkProxyCanvas.cpp | 12 ++++++++++ tests/CanvasTest.cpp | 3 +++ 18 files changed, 235 insertions(+), 9 deletions(-) diff --git a/debugger/QT/SkDebuggerGUI.cpp b/debugger/QT/SkDebuggerGUI.cpp index a64870d12f..60ef7e9717 100644 --- a/debugger/QT/SkDebuggerGUI.cpp +++ b/debugger/QT/SkDebuggerGUI.cpp @@ -959,14 +959,16 @@ void SkDebuggerGUI::setupListWidget(SkTArray* 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; } diff --git a/debugger/SkDebugCanvas.cpp b/debugger/SkDebugCanvas.cpp index 5d6795313b..9d34063cfd 100644 --- a/debugger/SkDebugCanvas.cpp +++ b/debugger/SkDebugCanvas.cpp @@ -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)); } diff --git a/debugger/SkDebugCanvas.h b/debugger/SkDebugCanvas.h index 841d3c9b77..bcb2bbf028 100644 --- a/debugger/SkDebugCanvas.h +++ b/debugger/SkDebugCanvas.h @@ -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; diff --git a/debugger/SkDrawCommand.cpp b/debugger/SkDrawCommand.cpp index 8489397551..0504fb5174 100644 --- a/debugger/SkDrawCommand.cpp +++ b/debugger/SkDrawCommand.cpp @@ -12,6 +12,11 @@ // 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; diff --git a/debugger/SkDrawCommand.h b/debugger/SkDrawCommand.h index 02a4afed5d..e73295aa7e 100644 --- a/debugger/SkDrawCommand.h +++ b/debugger/SkDrawCommand.h @@ -11,10 +11,12 @@ #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); diff --git a/gm/rects.cpp b/gm/rects.cpp index 3816f9e700..eee92b35af 100644 --- a/gm/rects.cpp +++ b/gm/rects.cpp @@ -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); diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 2bf5a54a51..821f86b5ad 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -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 diff --git a/include/utils/SkDumpCanvas.h b/include/utils/SkDumpCanvas.h index 8d9c67d50d..cdb1f19b42 100644 --- a/include/utils/SkDumpCanvas.h +++ b/include/utils/SkDumpCanvas.h @@ -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; diff --git a/include/utils/SkProxyCanvas.h b/include/utils/SkProxyCanvas.h index bd260c77d2..71187d1eb1 100644 --- a/include/utils/SkProxyCanvas.h +++ b/include/utils/SkProxyCanvas.h @@ -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; diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index df2a0f9e87..e26007fa28 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -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. diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h index b513271f20..0a147defe8 100644 --- a/src/core/SkPictureFlat.h +++ b/src/core/SkPictureFlat.h @@ -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* diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index e4f041f3bb..898d379578 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -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(), paint); diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index f405c3aba7..fc8502823d 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -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) { diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index 6245b78f3d..95ce5d26cb 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -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&, diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp index 32786fdc80..3b22a5e1dc 100644 --- a/src/pipe/SkGPipeWrite.cpp +++ b/src/pipe/SkGPipeWrite.cpp @@ -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) { diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp index 46c414144c..87ddd3153d 100644 --- a/src/utils/SkDumpCanvas.cpp +++ b/src/utils/SkDumpCanvas.cpp @@ -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()"); +} + /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// diff --git a/src/utils/SkProxyCanvas.cpp b/src/utils/SkProxyCanvas.cpp index 057f1df35a..053a75775c 100644 --- a/src/utils/SkProxyCanvas.cpp +++ b/src/utils/SkProxyCanvas.cpp @@ -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); } diff --git a/tests/CanvasTest.cpp b/tests/CanvasTest.cpp index e692de1fda..e45efa6972 100644 --- a/tests/CanvasTest.cpp +++ b/tests/CanvasTest.cpp @@ -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