From 0ad336f8c6f6f0325eee309c9cd501ea432cc33e Mon Sep 17 00:00:00 2001 From: "reed@android.com" Date: Mon, 29 Jun 2009 16:02:20 +0000 Subject: add shape flatten so they work properly in pictures add flatten/unflatten to matrix git-svn-id: http://skia.googlecode.com/svn/trunk@242 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gm/shapes.cpp | 7 +------ include/core/SkMatrix.h | 5 +++++ include/core/SkShape.h | 12 ++++++++---- include/effects/SkGroupShape.h | 5 +++-- include/effects/SkRectShape.h | 5 +++-- samplecode/SampleShapes.cpp | 20 +++++++++++++++++-- src/core/SkMatrix.cpp | 14 ++++++++++++++ src/core/SkPicturePlayback.cpp | 31 +++++++++++++++++------------ src/core/SkPictureRecord.cpp | 1 + src/core/SkShape.cpp | 44 +++++++++++++++++++++++++++++++++++++++++- src/effects/SkGroupShape.cpp | 36 ++++++++++++++++++++++++++-------- src/effects/SkRectShape.cpp | 2 ++ 12 files changed, 145 insertions(+), 37 deletions(-) diff --git a/gm/shapes.cpp b/gm/shapes.cpp index 2cf3f5e01d..b3d48638a4 100644 --- a/gm/shapes.cpp +++ b/gm/shapes.cpp @@ -57,8 +57,6 @@ public: for (size_t i = 0; i < SK_ARRAY_COUNT(fMatrixRefs); i++) { SkSafeRef(fMatrixRefs[i] = fGroup.getShapeMatrixRef(i)); } - - fAngle = 0; } virtual ~ShapesGM() { @@ -80,15 +78,12 @@ protected: canvas->drawColor(0xFFDDDDDD); } - int fAngle; - virtual void onDraw(SkCanvas* canvas) { this->drawBG(canvas); SkMatrix saveM = *fMatrixRefs[3]; - fAngle = (fAngle + 5) % 360; SkScalar c = SkIntToScalar(50); - fMatrixRefs[3]->preRotate(SkIntToScalar(fAngle), c, c); + fMatrixRefs[3]->preRotate(SkIntToScalar(30), c, c); SkMatrix matrix; diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h index aa008cb2d9..9dd4fc9c5c 100644 --- a/include/core/SkMatrix.h +++ b/include/core/SkMatrix.h @@ -399,6 +399,11 @@ public: friend bool operator!=(const SkMatrix& a, const SkMatrix& b) { return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) != 0; } + + // return the number of bytes written, whether or not buffer is null + uint32_t flatten(void* buffer) const; + // return the number of bytes read + uint32_t unflatten(const void* buffer); void dump() const; void toDumpString(SkString*) const; diff --git a/include/core/SkShape.h b/include/core/SkShape.h index abe4e268af..6cee70e751 100644 --- a/include/core/SkShape.h +++ b/include/core/SkShape.h @@ -9,7 +9,8 @@ class SkWStream; class SkShape : public SkFlattenable { public: - SkShape() {} + SkShape(); + virtual ~SkShape(); void draw(SkCanvas*); @@ -24,15 +25,18 @@ public: void drawMatrix(SkCanvas*, const SkMatrix&); // overrides + virtual Factory getFactory(); virtual void flatten(SkFlattenableWriteBuffer&); + // public for Registrar + static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); + protected: - virtual void onDraw(SkCanvas*) = 0; + virtual void onDraw(SkCanvas*); - SkShape(SkFlattenableReadBuffer&) {} + SkShape(SkFlattenableReadBuffer&); private: - static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); typedef SkFlattenable INHERITED; }; diff --git a/include/effects/SkGroupShape.h b/include/effects/SkGroupShape.h index 58ebeccf9e..2c851fac66 100644 --- a/include/effects/SkGroupShape.h +++ b/include/effects/SkGroupShape.h @@ -128,6 +128,9 @@ public: virtual Factory getFactory(); virtual void flatten(SkFlattenableWriteBuffer&); + // public for Registrar + static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); + protected: // overrides virtual void onDraw(SkCanvas*); @@ -141,8 +144,6 @@ private: }; SkTDArray fList; - static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); - typedef SkShape INHERITED; }; diff --git a/include/effects/SkRectShape.h b/include/effects/SkRectShape.h index dfc07e95c7..9b8cfc175c 100644 --- a/include/effects/SkRectShape.h +++ b/include/effects/SkRectShape.h @@ -37,6 +37,9 @@ public: virtual Factory getFactory(); virtual void flatten(SkFlattenableWriteBuffer&); + // public for Registrar + static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); + protected: SkRectShape(SkFlattenableReadBuffer&); @@ -47,8 +50,6 @@ private: SkRect fBounds; SkSize fRadii; - static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); - typedef SkPaintShape INHERITED; }; diff --git a/samplecode/SampleShapes.cpp b/samplecode/SampleShapes.cpp index 81f6e4f6b1..95efd0fb48 100644 --- a/samplecode/SampleShapes.cpp +++ b/samplecode/SampleShapes.cpp @@ -2,6 +2,7 @@ #include "SkCanvas.h" #include "SkPaint.h" #include "SkPicture.h" +#include "SkStream.h" #include "SkView.h" #include "SkRectShape.h" @@ -83,6 +84,20 @@ protected: canvas->drawColor(0xFFDDDDDD); } + void drawpicture(SkCanvas* canvas, SkPicture& pict) { +#if 1 + SkDynamicMemoryWStream ostream; + pict.serialize(&ostream); + + SkMemoryStream istream(ostream.getStream(), ostream.getOffset()); + SkPicture newPict(&istream); + + canvas->drawPicture(newPict); +#else + canvas->drawPicture(pict); +#endif + } + int fAngle; virtual void onDraw(SkCanvas* canvas) { @@ -105,7 +120,7 @@ protected: matrix.preScale(SK_Scalar1*2, SK_Scalar1*2); gs->appendShape(&fGroup, matrix); -#if 0 +#if 0 canvas->drawShape(gs); #else SkPicture pict; @@ -116,7 +131,8 @@ protected: cv->scale(-SK_Scalar1, SK_Scalar1); cv->drawShape(gs); pict.endRecording(); - canvas->drawPicture(pict); + + drawpicture(canvas, pict); #endif *fMatrixRefs[3] = saveM; diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp index ac5ae926e0..48fa804d9b 100644 --- a/src/core/SkMatrix.cpp +++ b/src/core/SkMatrix.cpp @@ -1582,6 +1582,20 @@ bool SkMatrix::setPolyToPoly(const SkPoint src[], const SkPoint dst[], /////////////////////////////////////////////////////////////////////////////// +uint32_t SkMatrix::flatten(void* buffer) const { + // TODO write less for simple matrices + if (buffer) { + memcpy(buffer, fMat, 9 * sizeof(SkScalar)); + } + return 9 * sizeof(SkScalar); +} + +uint32_t SkMatrix::unflatten(const void* buffer) { + memcpy(fMat, buffer, 9 * sizeof(SkScalar)); + this->setTypeMask(kUnknown_Mask); + return 9 * sizeof(SkScalar); +} + void SkMatrix::dump() const { SkString str; this->toDumpString(&str); diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index 24fcd8e57d..77ac9122a7 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -246,7 +246,7 @@ SkPicturePlayback::~SkPicturePlayback() { SkDELETE_ARRAY(fPictureRefs); for (int i = 0; i < fShapeCount; i++) { - fShapes[i]->unref(); + SkSafeUnref(fShapes[i]); } SkDELETE_ARRAY(fShapes); @@ -279,7 +279,7 @@ void SkPicturePlayback::dumpSize() const { #define PICT_PAINT_TAG SkSetFourByteTag('p', 'n', 't', ' ') #define PICT_PATH_TAG SkSetFourByteTag('p', 't', 'h', ' ') #define PICT_REGION_TAG SkSetFourByteTag('r', 'g', 'n', ' ') - +#define PICT_SHAPE_TAG SkSetFourByteTag('s', 'h', 'p', ' ') #include "SkStream.h" @@ -376,6 +376,11 @@ void SkPicturePlayback::serialize(SkWStream* stream) const { buffer.writePad(storage.get(), size); } + writeTagSize(buffer, PICT_SHAPE_TAG, fShapeCount); + for (i = 0; i < fShapeCount; i++) { + buffer.writeFlattenable(fShapes[i]); + } + // now we can write to the stream again writeFactories(stream, factRecorder); @@ -386,13 +391,6 @@ void SkPicturePlayback::serialize(SkWStream* stream) const { fPictureRefs[i]->serialize(stream); } -#if 0 - writeTagSize(stream, PICT_SHAPE_TAG, fShapeCount); - for (i = 0; i < fShapeCount; i++) { - fShapes[i]->serialize(stream); - } -#endif - writeTagSize(stream, PICT_ARRAYS_TAG, buffer.size()); buffer.writeToStream(stream); } @@ -491,6 +489,12 @@ SkPicturePlayback::SkPicturePlayback(SkStream* stream) { SkDEBUGCODE(uint32_t bytes =) fRegions[i].unflatten(buffer.skip(size)); SkASSERT(size == bytes); } + + fShapeCount = readTagSize(buffer, PICT_SHAPE_TAG); + fShapes = SkNEW_ARRAY(SkShape*, fShapeCount); + for (i = 0; i < fShapeCount; i++) { + fShapes[i] = reinterpret_cast(buffer.readFlattenable()); + } } /////////////////////////////////////////////////////////////////////////////// @@ -633,9 +637,12 @@ void SkPicturePlayback::draw(SkCanvas& canvas) { const SkPaint& paint = *getPaint(); canvas.drawRect(*fReader.skipRect(), paint); } break; - case DRAW_SHAPE: - canvas.drawShape(getShape()); - break; + case DRAW_SHAPE: { + SkShape* shape = getShape(); + if (shape) { + canvas.drawShape(shape); + } + } break; case DRAW_SPRITE: { const SkPaint* paint = getPaint(); const SkBitmap& bitmap = getBitmap(); diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index f0f3402790..4778726943 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -413,6 +413,7 @@ void SkPictureRecord::reset() { fPaints.reset(); fPictureRefs.unrefAll(); fRegions.reset(); + fShapes.unrefAll(); fWriter.reset(); fHeap.reset(); diff --git a/src/core/SkShape.cpp b/src/core/SkShape.cpp index e5fa8ff487..cd405dbf61 100644 --- a/src/core/SkShape.cpp +++ b/src/core/SkShape.cpp @@ -2,6 +2,23 @@ #include "SkShape.h" #include "SkMatrix.h" +#if 0 +static int gShapeCounter; +static void inc_shape(const SkShape* s) { + SkDebugf("inc %d\n", gShapeCounter); + gShapeCounter += 1; +} +static void dec_shape(const SkShape* s) { + --gShapeCounter; + SkDebugf("dec %d\n", gShapeCounter); +} +#else +#define inc_shape(s) +#define dec_shape(s) +#endif + +/////////////////////////////////////////////////////////////////////////////// + void SkShape::draw(SkCanvas* canvas) { int saveCount = canvas->getSaveCount(); this->onDraw(canvas); @@ -24,5 +41,30 @@ void SkShape::drawMatrix(SkCanvas* canvas, const SkMatrix& matrix) { /////////////////////////////////////////////////////////////////////////////// -void SkShape::flatten(SkFlattenableWriteBuffer& buffer) {} +SkShape::SkShape() { + inc_shape(this); +} + +SkShape::~SkShape() { + dec_shape(this); +} + +SkShape::SkShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { + inc_shape(this); +} + +SkFlattenable* SkShape::CreateProc(SkFlattenableReadBuffer& buffer) { + return SkNEW_ARGS(SkShape, (buffer)); +} + +SkFlattenable::Factory SkShape::getFactory() { + return CreateProc; +} + +void SkShape::flatten(SkFlattenableWriteBuffer& buffer) { + this->INHERITED::flatten(buffer); +} + +void SkShape::onDraw(SkCanvas*) {} +static SkFlattenable::Registrar gReg("SkShape", SkShape::CreateProc); diff --git a/src/effects/SkGroupShape.cpp b/src/effects/SkGroupShape.cpp index 3baa3152ed..0e7640f105 100644 --- a/src/effects/SkGroupShape.cpp +++ b/src/effects/SkGroupShape.cpp @@ -80,6 +80,8 @@ SkFlattenable::Factory SkGroupShape::getFactory() { return CreateProc; } +#define SAFE_MATRIX_STORAGE_SIZE (sizeof(SkMatrix)*2) + void SkGroupShape::flatten(SkFlattenableWriteBuffer& buffer) { this->INHERITED::flatten(buffer); @@ -88,20 +90,36 @@ void SkGroupShape::flatten(SkFlattenableWriteBuffer& buffer) { const Rec* rec = fList.begin(); const Rec* stop = fList.end(); while (rec < stop) { - SkShape* shape = rec->fShape; - buffer.writeFunctionPtr((void*)shape->getFactory()); - shape->flatten(buffer); - // todo: flatten the matrixref if present + buffer.writeFlattenable(rec->fShape); + if (rec->fMatrixRef) { + char storage[SAFE_MATRIX_STORAGE_SIZE]; + uint32_t size = rec->fMatrixRef->flatten(storage); + buffer.write32(size); + buffer.writePad(storage, size); + } else { + buffer.write32(0); + } + rec += 1; } } SkGroupShape::SkGroupShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer){ int count = buffer.readS32(); for (int i = 0; i < count; i++) { - SkFlattenable::Factory fact = - (SkFlattenable::Factory)buffer.readFunctionPtr(); - this->appendShape((SkShape*)fact(buffer))->unref(); - // todo: unflatten the matrixref if present + SkShape* shape = reinterpret_cast(buffer.readFlattenable()); + SkMatrixRef* mr = NULL; + uint32_t size = buffer.readS32(); + if (size) { + char storage[SAFE_MATRIX_STORAGE_SIZE]; + SkASSERT(size <= SAFE_MATRIX_STORAGE_SIZE); + buffer.read(storage, SkAlign4(size)); + mr = SkNEW(SkMatrixRef); + mr->unflatten(storage); + } + if (shape) { + this->appendShape(shape, mr)->unref(); + } + SkSafeUnref(mr); } } @@ -109,3 +127,5 @@ SkFlattenable* SkGroupShape::CreateProc(SkFlattenableReadBuffer& buffer) { return SkNEW_ARGS(SkGroupShape, (buffer)); } +static SkFlattenable::Registrar gReg("SkGroupShape", SkGroupShape::CreateProc); + diff --git a/src/effects/SkRectShape.cpp b/src/effects/SkRectShape.cpp index 16886d4806..8a38a1ebe8 100644 --- a/src/effects/SkRectShape.cpp +++ b/src/effects/SkRectShape.cpp @@ -83,3 +83,5 @@ SkPaintShape::SkPaintShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) fPaint.unflatten(buffer); } +static SkFlattenable::Registrar gReg("SkRectShape", SkRectShape::CreateProc); + -- cgit v1.2.3