diff options
-rw-r--r-- | include/core/SkMatrix.h | 6 | ||||
-rw-r--r-- | include/core/SkOrderedReadBuffer.h | 3 | ||||
-rw-r--r-- | include/core/SkOrderedWriteBuffer.h | 2 | ||||
-rw-r--r-- | include/core/SkPath.h | 12 | ||||
-rw-r--r-- | include/core/SkReader32.h | 11 | ||||
-rw-r--r-- | include/core/SkRegion.h | 4 | ||||
-rw-r--r-- | include/core/SkWriter32.h | 15 | ||||
-rw-r--r-- | samplecode/SampleRegion.cpp | 6 | ||||
-rw-r--r-- | src/core/SkMatrix.cpp | 4 | ||||
-rw-r--r-- | src/core/SkPath.cpp | 26 | ||||
-rw-r--r-- | src/core/SkRegion.cpp | 4 | ||||
-rw-r--r-- | src/pipe/SkGPipeRead.cpp | 6 | ||||
-rw-r--r-- | src/pipe/SkGPipeWrite.cpp | 36 | ||||
-rw-r--r-- | tests/MatrixTest.cpp | 12 | ||||
-rw-r--r-- | tests/PathTest.cpp | 21 |
15 files changed, 102 insertions, 66 deletions
diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h index 0f148a71d2..05fd132a29 100644 --- a/include/core/SkMatrix.h +++ b/include/core/SkMatrix.h @@ -507,13 +507,13 @@ public: } enum { - // flatten/unflatten will never return a value larger than this + // writeTo/readFromMemory will never return a value larger than this kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t) }; // return the number of bytes written, whether or not buffer is null - uint32_t flatten(void* buffer) const; + uint32_t writeToMemory(void* buffer) const; // return the number of bytes read - uint32_t unflatten(const void* buffer); + uint32_t readFromMemory(const void* buffer); void dump() const; void toDumpString(SkString*) const; diff --git a/include/core/SkOrderedReadBuffer.h b/include/core/SkOrderedReadBuffer.h index c1dbc7e251..12b74d1cdc 100644 --- a/include/core/SkOrderedReadBuffer.h +++ b/include/core/SkOrderedReadBuffer.h @@ -40,7 +40,8 @@ public: virtual const void* skip(size_t size) { return fReader.skip(size); } virtual void readMatrix(SkMatrix* m) { fReader.readMatrix(m); } - virtual void readPath(SkPath* p) { p->unflatten(fReader); } + virtual void readPath(SkPath* p) { fReader.readPath(p); } + virtual void readPoint(SkPoint* p) { p->fX = fReader.readScalar(); p->fY = fReader.readScalar(); diff --git a/include/core/SkOrderedWriteBuffer.h b/include/core/SkOrderedWriteBuffer.h index 947877ba4e..64687197cf 100644 --- a/include/core/SkOrderedWriteBuffer.h +++ b/include/core/SkOrderedWriteBuffer.h @@ -41,7 +41,7 @@ public: virtual size_t readFromStream(SkStream* s, size_t length) { return fWriter.readFromStream(s, length); } virtual void writeMatrix(const SkMatrix& matrix) { fWriter.writeMatrix(matrix); } - virtual void writePath(const SkPath& path) { path.flatten(fWriter); }; + virtual void writePath(const SkPath& path) { fWriter.writePath(path); }; virtual void writePoint(const SkPoint& point) { fWriter.writeScalar(point.fX); fWriter.writeScalar(point.fY); diff --git a/include/core/SkPath.h b/include/core/SkPath.h index e6989f2838..8440df3f02 100644 --- a/include/core/SkPath.h +++ b/include/core/SkPath.h @@ -784,8 +784,16 @@ public: void dump(bool forceClose, const char title[] = NULL) const; void dump() const; - void flatten(SkWriter32&) const; - void unflatten(SkReader32&); + /** + * Write the region to the buffer, and return the number of bytes written. + * If buffer is NULL, it still returns the number of bytes. + */ + uint32_t writeToMemory(void* buffer) const; + /** + * Initialized the region from the buffer, returning the number + * of bytes actually read. + */ + uint32_t readFromMemory(const void* buffer); #ifdef SK_BUILD_FOR_ANDROID uint32_t getGenerationID() const; diff --git a/include/core/SkReader32.h b/include/core/SkReader32.h index 98385e430a..9e25e84a55 100644 --- a/include/core/SkReader32.h +++ b/include/core/SkReader32.h @@ -11,6 +11,7 @@ #define SkReader32_DEFINED #include "SkMatrix.h" +#include "SkPath.h" #include "SkRegion.h" #include "SkScalar.h" @@ -92,14 +93,20 @@ public: int32_t readS32() { return this->readInt(); } uint32_t readU32() { return this->readInt(); } + void readPath(SkPath* path) { + size_t size = path->readFromMemory(this->peek()); + SkASSERT(SkAlign4(size) == size); + (void)this->skip(size); + } + void readMatrix(SkMatrix* matrix) { - size_t size = matrix->unflatten(this->peek()); + size_t size = matrix->readFromMemory(this->peek()); SkASSERT(SkAlign4(size) == size); (void)this->skip(size); } void readRegion(SkRegion* rgn) { - size_t size = rgn->unflatten(this->peek()); + size_t size = rgn->readFromMemory(this->peek()); SkASSERT(SkAlign4(size) == size); (void)this->skip(size); } diff --git a/include/core/SkRegion.h b/include/core/SkRegion.h index e83e19782f..2aab42385b 100644 --- a/include/core/SkRegion.h +++ b/include/core/SkRegion.h @@ -351,13 +351,13 @@ public: * Write the region to the buffer, and return the number of bytes written. * If buffer is NULL, it still returns the number of bytes. */ - uint32_t flatten(void* buffer) const; + uint32_t writeToMemory(void* buffer) const; /** * Initialized the region from the buffer, returning the number * of bytes actually read. */ - uint32_t unflatten(const void* buffer); + uint32_t readFromMemory(const void* buffer); /** * Returns a reference to a global empty region. Just a convenience for diff --git a/include/core/SkWriter32.h b/include/core/SkWriter32.h index c140850b9c..9abaa467d2 100644 --- a/include/core/SkWriter32.h +++ b/include/core/SkWriter32.h @@ -13,6 +13,7 @@ #include "SkTypes.h" #include "SkScalar.h" +#include "SkPath.h" #include "SkPoint.h" #include "SkRect.h" #include "SkMatrix.h" @@ -88,16 +89,22 @@ public: *(SkRect*)this->reserve(sizeof(rect)) = rect; } + void writePath(const SkPath& path) { + size_t size = path.writeToMemory(NULL); + SkASSERT(SkAlign4(size) == size); + path.writeToMemory(this->reserve(size)); + } + void writeMatrix(const SkMatrix& matrix) { - size_t size = matrix.flatten(NULL); + size_t size = matrix.writeToMemory(NULL); SkASSERT(SkAlign4(size) == size); - matrix.flatten(this->reserve(size)); + matrix.writeToMemory(this->reserve(size)); } void writeRegion(const SkRegion& rgn) { - size_t size = rgn.flatten(NULL); + size_t size = rgn.writeToMemory(NULL); SkASSERT(SkAlign4(size) == size); - rgn.flatten(this->reserve(size)); + rgn.writeToMemory(this->reserve(size)); } // write count bytes (must be a multiple of 4) diff --git a/samplecode/SampleRegion.cpp b/samplecode/SampleRegion.cpp index 5eed81eb61..0525f466f7 100644 --- a/samplecode/SampleRegion.cpp +++ b/samplecode/SampleRegion.cpp @@ -274,13 +274,13 @@ protected: { char buffer[1000]; - size_t size = tmp.flatten(NULL); + size_t size = tmp.writeToMemory(NULL); SkASSERT(size <= sizeof(buffer)); - size_t size2 = tmp.flatten(buffer); + size_t size2 = tmp.writeToMemory(buffer); SkASSERT(size == size2); SkRegion tmp3; - size2 = tmp3.unflatten(buffer); + size2 = tmp3.readFromMemory(buffer); SkASSERT(size == size2); SkASSERT(tmp3 == tmp); diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp index 9a0147d1db..7133658dad 100644 --- a/src/core/SkMatrix.cpp +++ b/src/core/SkMatrix.cpp @@ -1737,7 +1737,7 @@ const SkMatrix& SkMatrix::InvalidMatrix() { /////////////////////////////////////////////////////////////////////////////// -uint32_t SkMatrix::flatten(void* buffer) const { +uint32_t SkMatrix::writeToMemory(void* buffer) const { // TODO write less for simple matrices if (buffer) { memcpy(buffer, fMat, 9 * sizeof(SkScalar)); @@ -1745,7 +1745,7 @@ uint32_t SkMatrix::flatten(void* buffer) const { return 9 * sizeof(SkScalar); } -uint32_t SkMatrix::unflatten(const void* buffer) { +uint32_t SkMatrix::readFromMemory(const void* buffer) { if (buffer) { memcpy(fMat, buffer, 9 * sizeof(SkScalar)); this->setTypeMask(kUnknown_Mask); diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp index 4dab6042a2..034a515b50 100644 --- a/src/core/SkPath.cpp +++ b/src/core/SkPath.cpp @@ -8,8 +8,7 @@ #include "SkPath.h" -#include "SkReader32.h" -#include "SkWriter32.h" +#include "SkBuffer.h" #include "SkMath.h" // This value is just made-up for now. When count is 4, calling memset was much @@ -1685,20 +1684,31 @@ SkPath::Verb SkPath::RawIter::next(SkPoint pts[4]) { /////////////////////////////////////////////////////////////////////////////// /* - Format in flattened buffer: [ptCount, verbCount, pts[], verbs[]] + Format in compressed buffer: [ptCount, verbCount, pts[], verbs[]] */ -void SkPath::flatten(SkWriter32& buffer) const { +uint32_t SkPath::writeToMemory(void* storage) const { SkDEBUGCODE(this->validate();) + if (NULL == storage) { + const int byteCount = 3 * sizeof(int32_t) + + sizeof(SkPoint) * fPts.count() + + sizeof(uint8_t) * fVerbs.count(); + return SkAlign4(byteCount); + } + + SkWBuffer buffer(storage); buffer.write32(fPts.count()); buffer.write32(fVerbs.count()); buffer.write32((fFillType << 8) | fSegmentMask); - buffer.writeMul4(fPts.begin(), sizeof(SkPoint) * fPts.count()); - buffer.writePad(fVerbs.begin(), fVerbs.count()); + buffer.write(fPts.begin(), sizeof(SkPoint) * fPts.count()); + buffer.write(fVerbs.begin(), fVerbs.count()); + buffer.padToAlign4(); + return buffer.pos(); } -void SkPath::unflatten(SkReader32& buffer) { +uint32_t SkPath::readFromMemory(const void* storage) { + SkRBuffer buffer(storage); fPts.setCount(buffer.readS32()); fVerbs.setCount(buffer.readS32()); uint32_t packed = buffer.readS32(); @@ -1706,11 +1716,13 @@ void SkPath::unflatten(SkReader32& buffer) { fSegmentMask = packed & 0xFF; buffer.read(fPts.begin(), sizeof(SkPoint) * fPts.count()); buffer.read(fVerbs.begin(), fVerbs.count()); + buffer.skipToAlign4(); GEN_ID_INC; DIRTY_AFTER_EDIT; SkDEBUGCODE(this->validate();) + return buffer.pos(); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkRegion.cpp b/src/core/SkRegion.cpp index e403b1956a..ce5ed8af2d 100644 --- a/src/core/SkRegion.cpp +++ b/src/core/SkRegion.cpp @@ -1076,7 +1076,7 @@ bool SkRegion::op(const SkRegion& rgna, const SkRegion& rgnb, Op op) { #include "SkBuffer.h" -uint32_t SkRegion::flatten(void* storage) const { +uint32_t SkRegion::writeToMemory(void* storage) const { if (NULL == storage) { uint32_t size = sizeof(int32_t); // -1 (empty), 0 (rect), runCount if (!this->isEmpty()) { @@ -1109,7 +1109,7 @@ uint32_t SkRegion::flatten(void* storage) const { return buffer.pos(); } -uint32_t SkRegion::unflatten(const void* storage) { +uint32_t SkRegion::readFromMemory(const void* storage) { SkRBuffer buffer(storage); SkRegion tmp; int32_t count; diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp index ddc0cc41d9..85f46fd944 100644 --- a/src/pipe/SkGPipeRead.cpp +++ b/src/pipe/SkGPipeRead.cpp @@ -142,7 +142,7 @@ template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) { static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { SkPath path; - path.unflatten(*reader); + reader->readPath(&path); canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32), reader->readBool()); } @@ -260,7 +260,7 @@ static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { SkPath path; - path.unflatten(*reader); + reader->readPath(&path); canvas->drawPath(path, state->paint()); } @@ -331,7 +331,7 @@ static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op3 const void* text = reader->skip(SkAlign4(len)); SkPath path; - path.unflatten(*reader); + reader->readPath(&path); SkMatrix matrixStorage; const SkMatrix* matrix = NULL; diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp index 5d359889a2..24ca0eac49 100644 --- a/src/pipe/SkGPipeWrite.cpp +++ b/src/pipe/SkGPipeWrite.cpp @@ -43,22 +43,6 @@ static SkFlattenable* get_paintflat(const SkPaint& paint, unsigned paintFlat) { return NULL; } -static size_t estimateFlattenSize(const SkPath& path) { - int n = path.countPoints(); - size_t bytes = 3 * sizeof(int32_t); - bytes += n * sizeof(SkPoint); - bytes += SkAlign4(n + 2); // verbs: add 2 for move/close extras - -#ifdef SK_DEBUG - { - SkWriter32 writer(1024); - path.flatten(writer); - SkASSERT(writer.size() <= bytes); - } -#endif - return bytes; -} - static size_t writeTypeface(SkWriter32* writer, SkTypeface* typeface) { SkASSERT(typeface); SkDynamicMemoryWStream stream; @@ -449,7 +433,7 @@ bool SkGPipeCanvas::skew(SkScalar sx, SkScalar sy) { bool SkGPipeCanvas::concat(const SkMatrix& matrix) { if (!matrix.isIdentity()) { NOTIFY_SETUP(this); - if (this->needOpBytes(matrix.flatten(NULL))) { + if (this->needOpBytes(matrix.writeToMemory(NULL))) { this->writeOp(kConcat_DrawOp); fWriter.writeMatrix(matrix); } @@ -459,7 +443,7 @@ bool SkGPipeCanvas::concat(const SkMatrix& matrix) { void SkGPipeCanvas::setMatrix(const SkMatrix& matrix) { NOTIFY_SETUP(this); - if (this->needOpBytes(matrix.flatten(NULL))) { + if (this->needOpBytes(matrix.writeToMemory(NULL))) { this->writeOp(kSetMatrix_DrawOp); fWriter.writeMatrix(matrix); } @@ -480,9 +464,9 @@ bool SkGPipeCanvas::clipRect(const SkRect& rect, SkRegion::Op rgnOp, bool SkGPipeCanvas::clipPath(const SkPath& path, SkRegion::Op rgnOp, bool doAntiAlias) { NOTIFY_SETUP(this); - if (this->needOpBytes(estimateFlattenSize(path)) + sizeof(bool)) { + if (this->needOpBytes(path.writeToMemory(NULL)) + sizeof(bool)) { this->writeOp(kClipPath_DrawOp, 0, rgnOp); - path.flatten(fWriter); + fWriter.writePath(path); fWriter.writeBool(doAntiAlias); } // we just pass on the bounds of the path @@ -491,7 +475,7 @@ bool SkGPipeCanvas::clipPath(const SkPath& path, SkRegion::Op rgnOp, bool SkGPipeCanvas::clipRegion(const SkRegion& region, SkRegion::Op rgnOp) { NOTIFY_SETUP(this); - if (this->needOpBytes(region.flatten(NULL))) { + if (this->needOpBytes(region.writeToMemory(NULL))) { this->writeOp(kClipRegion_DrawOp, 0, rgnOp); fWriter.writeRegion(region); } @@ -547,9 +531,9 @@ void SkGPipeCanvas::drawRect(const SkRect& rect, const SkPaint& paint) { void SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) { NOTIFY_SETUP(this); this->writePaint(paint); - if (this->needOpBytes(estimateFlattenSize(path))) { + if (this->needOpBytes(path.writeToMemory(NULL))) { this->writeOp(kDrawPath_DrawOp); - path.flatten(fWriter); + fWriter.writePath(path); } } @@ -696,10 +680,10 @@ void SkGPipeCanvas::drawTextOnPath(const void* text, size_t byteLength, if (byteLength) { NOTIFY_SETUP(this); unsigned flags = 0; - size_t size = 4 + SkAlign4(byteLength) + estimateFlattenSize(path); + size_t size = 4 + SkAlign4(byteLength) + path.writeToMemory(NULL); if (matrix) { flags |= kDrawTextOnPath_HasMatrix_DrawOpFlag; - size += matrix->flatten(NULL); + size += matrix->writeToMemory(NULL); } this->writePaint(paint); if (this->needOpBytes(size)) { @@ -708,7 +692,7 @@ void SkGPipeCanvas::drawTextOnPath(const void* text, size_t byteLength, fWriter.write32(byteLength); fWriter.writePad(text, byteLength); - path.flatten(fWriter); + fWriter.writePath(path); if (matrix) { fWriter.writeMatrix(*matrix); } diff --git a/tests/MatrixTest.cpp b/tests/MatrixTest.cpp index 979f6ce76e..60f4831762 100644 --- a/tests/MatrixTest.cpp +++ b/tests/MatrixTest.cpp @@ -84,19 +84,19 @@ static bool is_identity(const SkMatrix& m) { static void test_flatten(skiatest::Reporter* reporter, const SkMatrix& m) { // add 100 in case we have a bug, I don't want to kill my stack in the test char buffer[SkMatrix::kMaxFlattenSize + 100]; - uint32_t size1 = m.flatten(NULL); - uint32_t size2 = m.flatten(buffer); + uint32_t size1 = m.writeToMemory(NULL); + uint32_t size2 = m.writeToMemory(buffer); REPORTER_ASSERT(reporter, size1 == size2); REPORTER_ASSERT(reporter, size1 <= SkMatrix::kMaxFlattenSize); SkMatrix m2; - uint32_t size3 = m2.unflatten(buffer); - REPORTER_ASSERT(reporter, size1 == size2); + uint32_t size3 = m2.readFromMemory(buffer); + REPORTER_ASSERT(reporter, size1 == size3); REPORTER_ASSERT(reporter, are_equal(reporter, m, m2)); char buffer2[SkMatrix::kMaxFlattenSize + 100]; - size3 = m2.flatten(buffer2); - REPORTER_ASSERT(reporter, size1 == size2); + size3 = m2.writeToMemory(buffer2); + REPORTER_ASSERT(reporter, size1 == size3); REPORTER_ASSERT(reporter, memcmp(buffer, buffer2, size1) == 0); } diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp index 21f78bf2ce..ff12e8eb53 100644 --- a/tests/PathTest.cpp +++ b/tests/PathTest.cpp @@ -700,7 +700,7 @@ static void test_flattening(skiatest::Reporter* reporter) { p.cubicTo(pts[4], pts[5], pts[6]); SkWriter32 writer(100); - p.flatten(writer); + writer.writePath(p); size_t size = writer.size(); SkAutoMalloc storage(size); writer.flatten(storage.get()); @@ -708,8 +708,25 @@ static void test_flattening(skiatest::Reporter* reporter) { SkPath p1; REPORTER_ASSERT(reporter, p1 != p); - p1.unflatten(reader); + reader.readPath(&p1); REPORTER_ASSERT(reporter, p1 == p); + + // create a buffer that should be much larger than the path so we don't + // kill our stack if writer goes too far. + char buffer[1024]; + uint32_t size1 = p.writeToMemory(NULL); + uint32_t size2 = p.writeToMemory(buffer); + REPORTER_ASSERT(reporter, size1 == size2); + + SkPath p2; + uint32_t size3 = p2.readFromMemory(buffer); + REPORTER_ASSERT(reporter, size1 == size3); + REPORTER_ASSERT(reporter, p == p2); + + char buffer2[1024]; + size3 = p2.writeToMemory(buffer2); + REPORTER_ASSERT(reporter, size1 == size3); + REPORTER_ASSERT(reporter, memcmp(buffer, buffer2, size1) == 0); } static void test_transform(skiatest::Reporter* reporter) { |