From 29dfaa80f5776904f42b72b387a99e75f8dc5f5f Mon Sep 17 00:00:00 2001 From: mtklein Date: Thu, 4 Sep 2014 14:12:44 -0700 Subject: Implement all SkCanvas overrides that SkPictureRecord does. Primarily this is for isDrawingToLayer(). drawData() and onNewSurface() are for completeness. BUG=409138 R=robertphillips@google.com, mtklein@google.com, reed@google.com Author: mtklein@chromium.org Review URL: https://codereview.chromium.org/545613002 --- src/core/SkRecordDraw.cpp | 2 ++ src/core/SkRecorder.cpp | 20 +++++++++++++++++++- src/core/SkRecorder.h | 9 +++++++++ src/core/SkRecords.h | 5 ++++- tests/RecorderTest.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index 67402dd808..3845a5c3dc 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -108,6 +108,7 @@ DRAW(DrawTextBlob, drawTextBlob(r.blob, r.x, r.y, r.paint)); DRAW(DrawTextOnPath, drawTextOnPath(r.text, r.byteLength, r.path, r.matrix, r.paint)); DRAW(DrawVertices, drawVertices(r.vmode, r.vertexCount, r.vertices, r.texs, r.colors, r.xmode.get(), r.indices, r.indexCount, r.paint)); +DRAW(DrawData, drawData(r.data, r.length)); #undef DRAW @@ -212,6 +213,7 @@ private: void trackBounds(const BeginCommentGroup&) { this->pushControl(); } void trackBounds(const AddComment&) { this->pushControl(); } void trackBounds(const EndCommentGroup&) { this->pushControl(); } + void trackBounds(const DrawData&) { this->pushControl(); } // For all other ops, we can calculate and store the bounds directly now. template void trackBounds(const T& op) { diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index df3e1d8fa5..86578a53b8 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -11,7 +11,9 @@ // SkCanvas will fail in mysterious ways if it doesn't know the real width and height. SkRecorder::SkRecorder(SkRecord* record, int width, int height) - : SkCanvas(width, height), fRecord(record) {} + : SkCanvas(width, height) + , fRecord(record) + , fSaveLayerCount(0) {} void SkRecorder::forgetRecord() { fRecord = NULL; @@ -229,17 +231,25 @@ void SkRecorder::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], } void SkRecorder::willSave() { + fSaveIsSaveLayer.push(false); APPEND(Save); } SkCanvas::SaveLayerStrategy SkRecorder::willSaveLayer(const SkRect* bounds, const SkPaint* paint, SkCanvas::SaveFlags flags) { + fSaveLayerCount++; + fSaveIsSaveLayer.push(true); APPEND(SaveLayer, this->copy(bounds), this->copy(paint), flags); return SkCanvas::kNoLayer_SaveLayerStrategy; } void SkRecorder::didRestore() { + SkBool8 saveLayer; + fSaveIsSaveLayer.pop(&saveLayer); + if (saveLayer) { + fSaveLayerCount--; + } APPEND(Restore, this->devBounds(), this->getTotalMatrix()); } @@ -295,3 +305,11 @@ void SkRecorder::addComment(const char* key, const char* value) { void SkRecorder::endCommentGroup() { APPEND(EndCommentGroup); } + +bool SkRecorder::isDrawingToLayer() const { + return fSaveLayerCount > 0; +} + +void SkRecorder::drawData(const void* data, size_t length) { + APPEND(DrawData, copy((const char*)data), length); +} diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index 683d29b411..db57eb0702 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -11,6 +11,7 @@ #include "SkCanvas.h" #include "SkRecord.h" #include "SkRecords.h" +#include "SkTDArray.h" // SkRecorder provides an SkCanvas interface for recording into an SkRecord. @@ -64,6 +65,7 @@ public: void willSave() SK_OVERRIDE; SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SkCanvas::SaveFlags) SK_OVERRIDE; + void willRestore() SK_OVERRIDE {} void didRestore() SK_OVERRIDE; void didConcat(const SkMatrix&) SK_OVERRIDE; @@ -110,6 +112,10 @@ public: void beginCommentGroup(const char*) SK_OVERRIDE; void addComment(const char*, const char*) SK_OVERRIDE; void endCommentGroup() SK_OVERRIDE; + void drawData(const void*, size_t) SK_OVERRIDE; + + bool isDrawingToLayer() const SK_OVERRIDE; + SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE { return NULL; } private: template @@ -125,6 +131,9 @@ private: } SkRecord* fRecord; + + int fSaveLayerCount; + SkTDArray fSaveIsSaveLayer; }; #endif//SkRecorder_DEFINED diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h index bd65fc5cb6..c1c5596b15 100644 --- a/src/core/SkRecords.h +++ b/src/core/SkRecords.h @@ -58,7 +58,8 @@ namespace SkRecords { M(DrawRRect) \ M(DrawRect) \ M(DrawSprite) \ - M(DrawTextBlob) \ + M(DrawTextBlob) \ + M(DrawData) \ M(DrawVertices) // Defines SkRecords::Type, an enum of all record types. @@ -270,6 +271,8 @@ RECORD5(DrawTextOnPath, SkPaint, paint, SkPath, path, Optional, matrix); +RECORD2(DrawData, PODArray, data, size_t, length); + // This guy is so ugly we just write it manually. struct DrawVertices { static const Type kType = DrawVertices_Type; diff --git a/tests/RecorderTest.cpp b/tests/RecorderTest.cpp index 21a897ca8b..aced54f7a9 100644 --- a/tests/RecorderTest.cpp +++ b/tests/RecorderTest.cpp @@ -68,6 +68,20 @@ DEF_TEST(Recorder_CommentGroups, r) { REPORTER_ASSERT(r, 1 == tally.count()); } +// DrawData is similar to comment groups. It doesn't affect drawing, but +// it's a pass-through we provide to the client. Again, a simple reg. test. +DEF_TEST(Recorder_DrawData, r) { + SkRecord record; + SkRecorder recorder(&record, 100, 100); + + const char* data = "This sure is some data, eh?"; + recorder.drawData(data, strlen(data)); + + Tally tally; + tally.apply(record); + REPORTER_ASSERT(r, 1 == tally.count()); +} + // Regression test for leaking refs held by optional arguments. DEF_TEST(Recorder_RefLeaking, r) { // We use SaveLayer to test: @@ -109,3 +123,30 @@ DEF_TEST(Recorder_RefPictures, r) { // the recorder destructor should have released us (back to unique) REPORTER_ASSERT(r, pic->unique()); } + +DEF_TEST(Recorder_IsDrawingToLayer, r) { + SkRecord record; + SkRecorder recorder(&record, 100, 100); + + // We'll save, saveLayer, save, and saveLayer, then restore them all, + // checking that isDrawingToLayer() is correct at each step. + + REPORTER_ASSERT(r, !recorder.isDrawingToLayer()); + recorder.save(); + REPORTER_ASSERT(r, !recorder.isDrawingToLayer()); + recorder.saveLayer(NULL, NULL); + REPORTER_ASSERT(r, recorder.isDrawingToLayer()); + recorder.save(); + REPORTER_ASSERT(r, recorder.isDrawingToLayer()); + recorder.saveLayer(NULL, NULL); + REPORTER_ASSERT(r, recorder.isDrawingToLayer()); + recorder.restore(); + REPORTER_ASSERT(r, recorder.isDrawingToLayer()); + recorder.restore(); + REPORTER_ASSERT(r, recorder.isDrawingToLayer()); + recorder.restore(); + REPORTER_ASSERT(r, !recorder.isDrawingToLayer()); + recorder.restore(); + REPORTER_ASSERT(r, !recorder.isDrawingToLayer()); +} + -- cgit v1.2.3