aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-23 15:04:45 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-23 15:04:45 +0000
commitf4cc18726b52a76ba18c07a6490851c4a5e38835 (patch)
tree3a5ff28e5f2e96512d1ec7e3a24671cbbc78b001
parentf79430350d9f06a72b307af879d7f3bdec7ff706 (diff)
use SkTRefArray to share readonly data between pictures
Review URL: https://codereview.appspot.com/6351121 git-svn-id: http://skia.googlecode.com/svn/trunk@4720 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--src/core/SkPictureFlat.h45
-rw-r--r--src/core/SkPicturePlayback.cpp255
-rw-r--r--src/core/SkPicturePlayback.h24
3 files changed, 105 insertions, 219 deletions
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index c746c01251..bd3c4f89a6 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -19,6 +19,7 @@
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRegion.h"
+#include "SkTRefArray.h"
#include "SkTSearch.h"
enum DrawType {
@@ -391,27 +392,53 @@ public:
* with the unflattened dictionary contents. The return value is the size of
* the allocated array.
*/
- int unflattenDictionary(T*& array, SkRefCntPlayback* refCntPlayback = NULL,
- SkTypefacePlayback* facePlayback = NULL) const {
+ int unflattenDictionary(T*& array,
+ SkRefCntPlayback* refCntPlayback = NULL,
+ SkTypefacePlayback* facePlayback = NULL) const {
int elementCount = fData.count();
if (elementCount > 0) {
array = SkNEW_ARRAY(T, elementCount);
- for (const SkFlatData** elementPtr = fData.begin();
- elementPtr != fData.end(); elementPtr++) {
- const SkFlatData* element = *elementPtr;
- int index = element->index() - 1;
- element->unflatten(&array[index], fUnflattenProc,
- refCntPlayback, facePlayback);
- }
+ this->unflattenIntoArray(array, refCntPlayback, facePlayback);
}
return elementCount;
}
+ /**
+ * Unflatten the objects and return them in SkTRefArray, or return NULL
+ * if there no objects (instead of an empty array).
+ */
+ SkTRefArray<T>* unflattenToArray(SkRefCntPlayback* refCntPlayback,
+ SkTypefacePlayback* facePlayback) const {
+ int count = fData.count();
+ SkTRefArray<T>* array = NULL;
+ if (count > 0) {
+ array = SkTRefArray<T>::Create(count);
+ this->unflattenIntoArray(&array->writableAt(0),
+ refCntPlayback, facePlayback);
+ }
+ return array;
+ }
+
protected:
void (*fFlattenProc)(SkOrderedWriteBuffer&, const void*);
void (*fUnflattenProc)(SkOrderedReadBuffer&, void*);
private:
+ void unflattenIntoArray(T* array,
+ SkRefCntPlayback* refCntPlayback,
+ SkTypefacePlayback* facePlayback) const {
+ const int count = fData.count();
+ const SkFlatData** iter = fData.begin();
+ for (int i = 0; i < count; ++i) {
+ const SkFlatData* element = iter[i];
+ int index = element->index() - 1;
+ SkASSERT((unsigned)index < (unsigned)count);
+ element->unflatten(&array[index], fUnflattenProc,
+ refCntPlayback, facePlayback);
+ }
+ }
+
+
SkFlatController * const fController;
int fNextIndex;
SkTDArray<const SkFlatData*> fData;
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 114d190761..06eae58bc6 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -12,6 +12,10 @@
#include "SkOrderedWriteBuffer.h"
#include <new>
+template <typename T> int SafeCount(const T* obj) {
+ return obj ? obj->count() : 0;
+}
+
/* Define this to spew out a debug statement whenever we skip the remainder of
a save/restore block because a clip... command returned false (empty).
*/
@@ -78,15 +82,10 @@ SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record) {
fRCPlayback.reset(&record.fRCSet);
fTFPlayback.reset(&record.fTFSet);
- fBitmapCount = record.getBitmaps().unflattenDictionary(fBitmaps, &fRCPlayback);
- fMatrixCount = record.getMatrices().unflattenDictionary(fMatrices);
- fPaintCount = record.getPaints().unflattenDictionary(fPaints, &fRCPlayback, &fTFPlayback);
- fRegionCount = record.getRegions().unflattenDictionary(fRegions);
-
- SkASSERT(fBitmapCount == record.getBitmaps().count());
- SkASSERT(fMatrixCount == record.getMatrices().count());
- SkASSERT(fPaintCount == record.getPaints().count());
- SkASSERT(fRegionCount == record.getRegions().count());
+ fBitmaps = record.getBitmaps().unflattenToArray(&fRCPlayback, NULL);
+ fMatrices = record.getMatrices().unflattenToArray(NULL, NULL);
+ fPaints = record.getPaints().unflattenToArray(&fRCPlayback, &fTFPlayback);
+ fRegions = record.getRegions().unflattenToArray(NULL, NULL);
fPathHeap = record.fPathHeap;
SkSafeRef(fPathHeap);
@@ -123,31 +122,22 @@ SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record) {
#endif
}
+template <typename T> T* SafeRefReturn(T* obj) {
+ if (obj) {
+ obj->ref();
+ }
+ return obj;
+}
+
SkPicturePlayback::SkPicturePlayback(const SkPicturePlayback& src) {
this->init();
- SkASSERT(!fOpData);
- fOpData = src.fOpData;
- fOpData->ref();
-
- fBitmapCount = src.fBitmapCount;
- fBitmaps = SkNEW_ARRAY(SkBitmap, fBitmapCount);
- for (int i = 0; i < fBitmapCount; i++) {
- fBitmaps[i] = src.fBitmaps[i];
- }
-
- fMatrixCount = src.fMatrixCount;
- fMatrices = SkNEW_ARRAY(SkMatrix, fMatrixCount);
- memcpy(fMatrices, src.fMatrices, fMatrixCount * sizeof(SkMatrix));
-
- fPaintCount = src.fPaintCount;
- fPaints = SkNEW_ARRAY(SkPaint, fPaintCount);
- for (int i = 0; i < fPaintCount; i++) {
- fPaints[i] = src.fPaints[i];
- }
-
- fPathHeap = src.fPathHeap;
- SkSafeRef(fPathHeap);
+ fPathHeap = SafeRefReturn(src.fPathHeap);
+ fBitmaps = SafeRefReturn(src.fBitmaps);
+ fMatrices = SafeRefReturn(src.fMatrices);
+ fPaints = SafeRefReturn(src.fPaints);
+ fRegions = SafeRefReturn(src.fRegions);
+ fOpData = SafeRefReturn(src.fOpData);
fPictureCount = src.fPictureCount;
fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
@@ -155,12 +145,6 @@ SkPicturePlayback::SkPicturePlayback(const SkPicturePlayback& src) {
fPictureRefs[i] = src.fPictureRefs[i];
fPictureRefs[i]->ref();
}
-
- fRegionCount = src.fRegionCount;
- fRegions = SkNEW_ARRAY(SkRegion, fRegionCount);
- for (int i = 0; i < fRegionCount; i++) {
- fRegions[i] = src.fRegions[i];
- }
}
void SkPicturePlayback::init() {
@@ -170,8 +154,7 @@ void SkPicturePlayback::init() {
fPathHeap = NULL;
fPictureRefs = NULL;
fRegions = NULL;
- fBitmapCount = fMatrixCount = fPaintCount = fPictureCount =
- fRegionCount = 0;
+ fPictureCount = 0;
fOpData = NULL;
fFactoryPlayback = NULL;
}
@@ -179,11 +162,10 @@ void SkPicturePlayback::init() {
SkPicturePlayback::~SkPicturePlayback() {
fOpData->unref();
- SkDELETE_ARRAY(fBitmaps);
- SkDELETE_ARRAY(fMatrices);
- SkDELETE_ARRAY(fPaints);
- SkDELETE_ARRAY(fRegions);
-
+ SkSafeUnref(fBitmaps);
+ SkSafeUnref(fMatrices);
+ SkSafeUnref(fPaints);
+ SkSafeUnref(fRegions);
SkSafeUnref(fPathHeap);
for (int i = 0; i < fPictureCount; i++) {
@@ -197,11 +179,11 @@ SkPicturePlayback::~SkPicturePlayback() {
void SkPicturePlayback::dumpSize() const {
SkDebugf("--- picture size: ops=%d bitmaps=%d [%d] matrices=%d [%d] paints=%d [%d] paths=%d regions=%d\n",
fOpData->size(),
- fBitmapCount, fBitmapCount * sizeof(SkBitmap),
- fMatrixCount, fMatrixCount * sizeof(SkMatrix),
- fPaintCount, fPaintCount * sizeof(SkPaint),
- fPathHeap ? fPathHeap->count() : 0,
- fRegionCount);
+ SafeCount(fBitmaps), SafeCount(fBitmaps) * sizeof(SkBitmap),
+ SafeCount(fMatrices), SafeCount(fMatrices) * sizeof(SkMatrix),
+ SafeCount(fPaints), SafeCount(fPaints) * sizeof(SkPaint),
+ SafeCount(fPathHeap),
+ SafeCount(fRegions));
}
///////////////////////////////////////////////////////////////////////////////
@@ -275,39 +257,36 @@ static void writeTypefaces(SkWStream* stream, const SkRefCntSet& rec) {
}
void SkPicturePlayback::flattenToBuffer(SkOrderedWriteBuffer& buffer) const {
- int i;
+ int i, n;
- if (fBitmapCount > 0) {
- writeTagSize(buffer, PICT_BITMAP_BUFFER_TAG, fBitmapCount);
- for (i = 0; i < fBitmapCount; i++) {
- fBitmaps[i].flatten(buffer);
+ if ((n = SafeCount(fBitmaps)) > 0) {
+ writeTagSize(buffer, PICT_BITMAP_BUFFER_TAG, n);
+ for (i = 0; i < n; i++) {
+ (*fBitmaps)[i].flatten(buffer);
}
}
- if (fMatrixCount > 0) {
- writeTagSize(buffer, PICT_MATRIX_BUFFER_TAG, fMatrixCount);
- buffer.writeMul4(fMatrices, fMatrixCount * sizeof(SkMatrix));
+ if ((n = SafeCount(fMatrices)) > 0) {
+ writeTagSize(buffer, PICT_MATRIX_BUFFER_TAG, n);
+ buffer.writeMul4(fMatrices->begin(), n * sizeof(SkMatrix));
}
- if (fPaintCount > 0) {
- writeTagSize(buffer, PICT_PAINT_BUFFER_TAG, fPaintCount);
- for (i = 0; i < fPaintCount; i++) {
- fPaints[i].flatten(buffer);
+ if ((n = SafeCount(fPaints)) > 0) {
+ writeTagSize(buffer, PICT_PAINT_BUFFER_TAG, n);
+ for (i = 0; i < n; i++) {
+ (*fPaints)[i].flatten(buffer);
}
}
- if (fPathHeap && fPathHeap->count() > 0) {
- int count = fPathHeap->count();
- writeTagSize(buffer, PICT_PATH_BUFFER_TAG, count);
- if (count > 0) {
- fPathHeap->flatten(buffer);
- }
+ if ((n = SafeCount(fPathHeap)) > 0) {
+ writeTagSize(buffer, PICT_PATH_BUFFER_TAG, n);
+ fPathHeap->flatten(buffer);
}
- if (fRegionCount > 0) {
- writeTagSize(buffer, PICT_REGION_BUFFER_TAG, fRegionCount);
- for (i = 0; i < fRegionCount; i++) {
- buffer.getWriter32()->writeRegion(fRegions[i]);
+ if ((n = SafeCount(fRegions)) > 0) {
+ writeTagSize(buffer, PICT_REGION_BUFFER_TAG, n);
+ for (i = 0; i < n; i++) {
+ buffer.getWriter32()->writeRegion((*fRegions)[i]);
}
}
}
@@ -447,22 +426,19 @@ bool SkPicturePlayback::parseBufferTag(SkOrderedReadBuffer& buffer,
uint32_t tag, size_t size) {
switch (tag) {
case PICT_BITMAP_BUFFER_TAG: {
- fBitmapCount = size;
- fBitmaps = SkNEW_ARRAY(SkBitmap, fBitmapCount);
- for (int i = 0; i < fBitmapCount; i++) {
- fBitmaps[i].unflatten(buffer);
+ fBitmaps = SkTRefArray<SkBitmap>::Create(size);
+ for (size_t i = 0; i < size; ++i) {
+ fBitmaps->writableAt(i).unflatten(buffer);
}
} break;
case PICT_MATRIX_BUFFER_TAG:
- fMatrixCount = size;
- fMatrices = SkNEW_ARRAY(SkMatrix, fMatrixCount);
- buffer.read(fMatrices, fMatrixCount * sizeof(SkMatrix));
+ fMatrices = SkTRefArray<SkMatrix>::Create(size);
+ buffer.read(&fMatrices->writableAt(0), size * sizeof(SkMatrix));
break;
case PICT_PAINT_BUFFER_TAG: {
- fPaintCount = size;
- fPaints = SkNEW_ARRAY(SkPaint, fPaintCount);
- for (int i = 0; i < fPaintCount; i++) {
- fPaints[i].unflatten(buffer);
+ fPaints = SkTRefArray<SkPaint>::Create(size);
+ for (size_t i = 0; i < size; ++i) {
+ fPaints->writableAt(i).unflatten(buffer);
}
} break;
case PICT_PATH_BUFFER_TAG:
@@ -471,10 +447,9 @@ bool SkPicturePlayback::parseBufferTag(SkOrderedReadBuffer& buffer,
}
break;
case PICT_REGION_BUFFER_TAG: {
- fRegionCount = size;
- fRegions = SkNEW_ARRAY(SkRegion, fRegionCount);
- for (int i = 0; i < fRegionCount; i++) {
- buffer.getReader32()->readRegion(&fRegions[i]);
+ fRegions = SkTRefArray<SkRegion>::Create(size);
+ for (size_t i = 0; i < size; ++i) {
+ buffer.getReader32()->readRegion(&fRegions->writableAt(i));
}
} break;
}
@@ -798,114 +773,6 @@ void SkPicturePlayback::abort() {
///////////////////////////////////////////////////////////////////////////////
-#if 0
-uint32_t SkPicturePlayback::flatten(void* storage) const {
- SkWBuffer buffer(storage);
- buffer.write32(fBitmapCount);
- int index;
- for (index = 0; index < fBitmapCount; index++) {
- const SkBitmap& bitmap = fBitmaps[index];
- uint32_t size = bitmap.flatten(NULL, true);
- buffer.write32(size);
- void* local = buffer.skip(size);
- bitmap.flatten(local, true);
- }
- buffer.write32(fPaintCount);
- for (index = 0; index < fPaintCount; index++) {
- SkFlattenableWriteBuffer flatWrite;
- const SkPaint& paint = fPaints[index];
- SkFlatPaint::Write(&flatWrite, paint);
- uint32_t size = flatWrite.pos();
- buffer.write32(size);
- void* local = buffer.skip(size);
- flatWrite.reset(local);
- SkFlatPaint::Write(&flatWrite, paint);
- }
- buffer.write32(fPathCount);
- for (index = 0; index < fPathCount; index++) {
- const SkPath& path = fPaths[index];
- uint32_t size = path.flatten(NULL);
- buffer.write32(size);
- void* local = buffer.skip(size);
- path.flatten(local);
- }
-
-#if 0
- buffer.write32(fPictureCount);
- for (index = 0; index < fPictureCount; index++) {
- const SkPicture& picture = fPictures[index];
- uint32_t size = picture.flatten(NULL);
- buffer.write32(size);
- void* local = buffer.skip(size);
- picture.flatten(local);
- }
-#endif
-
- buffer.write32(fRegionCount);
- for (index = 0; index < fRegionCount; index++) {
- const SkRegion& region = fRegions[index];
- size_t size = region.computeBufferSize();
- buffer.write32(size);
- void* local = buffer.skip(size);
- region.writeToBuffer(local);
- }
- fReader.rewind();
- size_t length = fReader.size();
- buffer.write32(length);
- memcpy(buffer.skip(length), fReader.base(), length);
- return (uint32_t) buffer.pos();
-}
-
-void SkPicturePlayback::unflatten(const void* storage) {
- SkRBuffer buffer(storage);
- int index;
- fBitmapCount = buffer.readU32();
- fBitmaps = new SkBitmap[fBitmapCount];
- for (index = 0; index < fBitmapCount; index++) {
- uint32_t size = buffer.readU32();
- const void* local = buffer.skip(size);
- fBitmaps[index].unflatten(local);
- }
- fPaintCount = buffer.readU32();
- fPaints = new SkPaint[fPaintCount];
- for (index = 0; index < fPaintCount; index++) {
- uint32_t size = buffer.readU32();
- const void* local = buffer.skip(size);
- SkFlatPaint::Read(local, &fPaints[index]);
- }
- fPathCount = buffer.readU32();
- fPaths = new SkPath[fPathCount];
- for (index = 0; index < fPathCount; index++) {
- uint32_t size = buffer.readU32();
- const void* local = buffer.skip(size);
- fPaths[index].unflatten(local);
- }
-
-#if 0
- fPictureCount = buffer.readU32();
- fPictures = new SkPicture[fPictureCount];
- for (index = 0; index < fPictureCount; index++) {
- uint32_t size = buffer.readU32();
- const void* local = buffer.skip(size);
- fPictures[index].unflatten(local);
- }
-#endif
-
- fRegionCount = buffer.readU32();
- fRegions = new SkRegion[fRegionCount];
- for (index = 0; index < fRegionCount; index++) {
- uint32_t size = buffer.readU32();
- const void* local = buffer.skip(size);
- fRegions[index].readFromBuffer(local);
- }
- int32_t length = buffer.readS32();
- const void* stream = buffer.skip(length);
- fReader.setMemory(stream, length);
-}
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-
#ifdef SK_DEBUG_SIZE
int SkPicturePlayback::size(size_t* sizePtr) {
int objects = bitmaps(sizePtr);
diff --git a/src/core/SkPicturePlayback.h b/src/core/SkPicturePlayback.h
index ecbc6a72dc..c0c61e4e79 100644
--- a/src/core/SkPicturePlayback.h
+++ b/src/core/SkPicturePlayback.h
@@ -72,8 +72,7 @@ private:
const SkBitmap& getBitmap(SkReader32& reader) {
int index = reader.readInt();
- SkASSERT(index > 0);
- return fBitmaps[index - 1];
+ return (*fBitmaps)[index - 1];
}
const SkMatrix* getMatrix(SkReader32& reader) {
@@ -81,8 +80,7 @@ private:
if (index == 0) {
return NULL;
}
- SkASSERT(index > 0 && index <= fMatrixCount);
- return &fMatrices[index - 1];
+ return &(*fMatrices)[index - 1];
}
const SkPath& getPath(SkReader32& reader) {
@@ -100,8 +98,7 @@ private:
if (index == 0) {
return NULL;
}
- SkASSERT(index > 0 && index <= fPaintCount);
- return &fPaints[index - 1];
+ return &(*fPaints)[index - 1];
}
const SkRect* getRectPtr(SkReader32& reader) {
@@ -122,8 +119,7 @@ private:
const SkRegion& getRegion(SkReader32& reader) {
int index = reader.readInt();
- SkASSERT(index > 0);
- return fRegions[index - 1];
+ return (*fRegions)[index - 1];
}
void getText(SkReader32& reader, TextContainer* text) {
@@ -172,14 +168,10 @@ private: // these help us with reading/writing
private:
SkPathHeap* fPathHeap; // reference counted
- SkBitmap* fBitmaps;
- int fBitmapCount;
- SkMatrix* fMatrices;
- int fMatrixCount;
- SkPaint* fPaints;
- int fPaintCount;
- SkRegion* fRegions;
- int fRegionCount;
+ SkTRefArray<SkBitmap>* fBitmaps;
+ SkTRefArray<SkMatrix>* fMatrices;
+ SkTRefArray<SkPaint>* fPaints;
+ SkTRefArray<SkRegion>* fRegions;
SkData* fOpData; // opcodes and parameters