aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkPictureFlat.cpp52
-rw-r--r--src/core/SkPictureFlat.h175
-rw-r--r--src/core/SkPicturePlayback.cpp12
-rw-r--r--src/core/SkPicturePlayback.h1
-rw-r--r--src/core/SkPictureRecord.cpp7
-rw-r--r--src/core/SkPictureRecord.h3
-rw-r--r--src/pipe/SkGPipeWrite.cpp17
-rw-r--r--tests/FlatDataTest.cpp18
8 files changed, 199 insertions, 86 deletions
diff --git a/src/core/SkPictureFlat.cpp b/src/core/SkPictureFlat.cpp
index b0c02cc728..fa65ca44ea 100644
--- a/src/core/SkPictureFlat.cpp
+++ b/src/core/SkPictureFlat.cpp
@@ -31,7 +31,7 @@ void SkRefCntPlayback::reset(const SkRefCntSet* rec) {
}
SkDELETE_ARRAY(fArray);
- if (rec) {
+ if (rec!= NULL && rec->count() > 0) {
fCount = rec->count();
fArray = SkNEW_ARRAY(SkRefCnt*, fCount);
rec->copyToArray(fArray);
@@ -60,22 +60,54 @@ SkRefCnt* SkRefCntPlayback::set(int index, SkRefCnt* obj) {
///////////////////////////////////////////////////////////////////////////////
+SkFlatController::SkFlatController()
+: fPixelRefSet(NULL)
+, fTypefaceSet(NULL)
+, fPixelRefPlayback(NULL)
+, fTypefacePlayback(NULL)
+, fFactorySet(NULL) {}
+
+SkFlatController::~SkFlatController() {
+ SkSafeUnref(fPixelRefSet);
+ SkSafeUnref(fTypefaceSet);
+ SkSafeUnref(fFactorySet);
+}
+
+void SkFlatController::setPixelRefSet(SkRefCntSet *set) {
+ SkRefCnt_SafeAssign(fPixelRefSet, set);
+}
+
+void SkFlatController::setTypefaceSet(SkRefCntSet *set) {
+ SkRefCnt_SafeAssign(fTypefaceSet, set);
+}
+
+void SkFlatController::setPixelRefPlayback(SkRefCntPlayback* playback) {
+ fPixelRefPlayback = playback;
+}
+
+void SkFlatController::setTypefacePlayback(SkTypefacePlayback* playback) {
+ fTypefacePlayback = playback;
+}
+
+SkNamedFactorySet* SkFlatController::setNamedFactorySet(SkNamedFactorySet* set) {
+ SkRefCnt_SafeAssign(fFactorySet, set);
+ return set;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
SkFlatData* SkFlatData::Create(SkFlatController* controller, const void* obj,
int index, void (*flattenProc)(SkOrderedWriteBuffer&, const void*),
- SkRefCntSet* refCntRecorder, SkRefCntSet* faceRecorder,
- uint32_t writeBufferflags, SkNamedFactorySet* fset) {
+ uint32_t writeBufferflags) {
// a buffer of 256 bytes should be sufficient for most paints, regions,
// and matrices.
intptr_t storage[256];
SkOrderedWriteBuffer buffer(256, storage, sizeof(storage));
- if (refCntRecorder) {
- buffer.setRefCntRecorder(refCntRecorder);
- }
- if (faceRecorder) {
- buffer.setTypefaceRecorder(faceRecorder);
- }
+
+ buffer.setRefCntRecorder(controller->getPixelRefSet());
+ buffer.setTypefaceRecorder(controller->getTypefaceSet());
+ buffer.setNamedFactoryRecorder(controller->getNamedFactorySet());
buffer.setFlags(writeBufferflags);
- buffer.setNamedFactoryRecorder(fset);
flattenProc(buffer, obj);
uint32_t size = buffer.size();
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index ddcb100d6c..dbec5c9284 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -146,7 +146,8 @@ private:
// SkFlatDictionary: is an abstract templated dictionary that maintains a
// searchable set of SkFlataData objects of type T.
// SkFlatController: is an interface provided to SkFlatDictionary which handles
-// allocation and unallocation in some cases
+// allocation and unallocation in some cases. It also holds
+// ref count recorders and the like.
//
// NOTE: any class that wishes to be used in conjunction with SkFlatDictionary
// must subclass the dictionary and provide the necessary flattening procs.
@@ -162,6 +163,8 @@ class SkFlatData;
class SkFlatController : public SkRefCnt {
public:
+ SkFlatController();
+ virtual ~SkFlatController();
/**
* Provide a new block of memory for the SkFlatDictionary to use.
*/
@@ -176,6 +179,81 @@ public:
*/
virtual void unalloc(void* ptr) = 0;
+ /**
+ * Used during creation of SkFlatData objects. Only used for storing refs to
+ * SkPixelRefs. If the objects being flattened have SkPixelRefs (i.e.
+ * SkBitmaps or SkPaints, which may have SkBitmapShaders), this should be
+ * set by the protected setPixelRefSet.
+ */
+ SkRefCntSet* getPixelRefSet() { return fPixelRefSet; }
+
+ /**
+ * Used during unflattening of the SkFlatData objects in the
+ * SkFlatDictionary. Needs to be set by the protected setPixelRefPlayback
+ * and needs to be reset to the SkRefCntSet passed to setPixelRefSet.
+ */
+ SkRefCntPlayback* getPixelRefPlayback() { return fPixelRefPlayback; }
+
+ /**
+ * Used during creation of SkFlatData objects. If a typeface recorder is
+ * required to flatten the objects being flattened (i.e. for SkPaints), this
+ * should be set by the protected setTypefaceSet.
+ */
+ SkRefCntSet* getTypefaceSet() { return fTypefaceSet; }
+
+ /**
+ * Used during unflattening of the SkFlatData objects in the
+ * SkFlatDictionary. Needs to be set by the protected setTypefacePlayback
+ * and needs to be reset to the SkRefCntSet passed to setTypefaceSet.
+ */
+ SkTypefacePlayback* getTypefacePlayback() { return fTypefacePlayback; }
+
+ /**
+ * Optional factory recorder used during creation of SkFlatData objects. Set
+ * using the protected method setNamedFactorySet.
+ */
+ SkNamedFactorySet* getNamedFactorySet() { return fFactorySet; }
+
+protected:
+ /**
+ * Set an SkRefCntSet to be used to store SkPixelRefs during flattening. Ref
+ * counted.
+ */
+ void setPixelRefSet(SkRefCntSet*);
+
+ /**
+ * Set an SkRefCntSet to be used to store SkTypefaces during flattening. Ref
+ * counted.
+ */
+ void setTypefaceSet(SkRefCntSet*);
+
+ /**
+ * Set an SkRefCntPlayback to be used to find references to SkPixelRefs
+ * during unflattening. Should be reset to the set provided to
+ * setPixelRefSet.
+ */
+ void setPixelRefPlayback(SkRefCntPlayback*);
+
+ /**
+ * Set an SkTypefacePlayback to be used to find references to SkTypefaces
+ * during unflattening. Should be reset to the set provided to
+ * setTypefaceSet.
+ */
+ void setTypefacePlayback(SkTypefacePlayback*);
+
+ /**
+ * Set an SkNamedFactorySet to be used to store Factorys and their
+ * corresponding names during flattening. Ref counted. Returns the same
+ * set as a convenience.
+ */
+ SkNamedFactorySet* setNamedFactorySet(SkNamedFactorySet*);
+
+private:
+ SkRefCntSet* fPixelRefSet;
+ SkRefCntSet* fTypefaceSet;
+ SkRefCntPlayback* fPixelRefPlayback;
+ SkTypefacePlayback* fTypefacePlayback;
+ SkNamedFactorySet* fFactorySet;
};
class SkFlatData {
@@ -239,10 +317,7 @@ public:
static SkFlatData* Create(SkFlatController* controller, const void* obj, int index,
void (*flattenProc)(SkOrderedWriteBuffer&, const void*),
- SkRefCntSet* refCntRecorder = NULL,
- SkRefCntSet* faceRecorder = NULL,
- uint32_t writeBufferflags = 0,
- SkNamedFactorySet* fset = NULL);
+ uint32_t writeBufferflags);
void unflatten(void* result,
void (*unflattenProc)(SkOrderedReadBuffer&, void*),
@@ -290,18 +365,12 @@ private:
template <class T>
class SkFlatDictionary {
public:
- SkFlatDictionary(SkFlatController* controller, SkRefCntSet* refSet = NULL,
- SkRefCntSet* typeFaceSet = NULL,
- SkNamedFactorySet* factorySet = NULL)
- : fController(controller), fRefSet(refSet), fTypefaceSet(typeFaceSet)
- , fFactorySet(factorySet) {
+ SkFlatDictionary(SkFlatController* controller)
+ : fController(controller) {
fFlattenProc = NULL;
fUnflattenProc = NULL;
SkASSERT(controller);
fController->ref();
- SkSafeRef(refSet);
- SkSafeRef(typeFaceSet);
- SkSafeRef(factorySet);
// set to 1 since returning a zero from find() indicates failure
fNextIndex = 1;
sk_bzero(fHash, sizeof(fHash));
@@ -309,9 +378,6 @@ public:
virtual ~SkFlatDictionary() {
fController->unref();
- SkSafeUnref(fRefSet);
- SkSafeUnref(fTypefaceSet);
- SkSafeUnref(fFactorySet);
}
int count() const { return fData.count(); }
@@ -393,13 +459,11 @@ 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) const {
int elementCount = fData.count();
if (elementCount > 0) {
array = SkNEW_ARRAY(T, elementCount);
- this->unflattenIntoArray(array, refCntPlayback, facePlayback);
+ this->unflattenIntoArray(array);
}
return elementCount;
}
@@ -408,14 +472,12 @@ public:
* 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 {
+ SkTRefArray<T>* unflattenToArray() const {
int count = fData.count();
SkTRefArray<T>* array = NULL;
if (count > 0) {
array = SkTRefArray<T>::Create(count);
- this->unflattenIntoArray(&array->writableAt(0),
- refCntPlayback, facePlayback);
+ this->unflattenIntoArray(&array->writableAt(0));
}
return array;
}
@@ -425,9 +487,7 @@ protected:
void (*fUnflattenProc)(SkOrderedReadBuffer&, void*);
private:
- void unflattenIntoArray(T* array,
- SkRefCntPlayback* refCntPlayback,
- SkTypefacePlayback* facePlayback) const {
+ void unflattenIntoArray(T* array) const {
const int count = fData.count();
const SkFlatData** iter = fData.begin();
for (int i = 0; i < count; ++i) {
@@ -435,7 +495,9 @@ private:
int index = element->index() - 1;
SkASSERT((unsigned)index < (unsigned)count);
element->unflatten(&array[index], fUnflattenProc,
- refCntPlayback, facePlayback);
+ fController->getPixelRefPlayback(),
+ fController->getTypefacePlayback());
+
}
}
@@ -443,16 +505,11 @@ private:
SkFlatController * const fController;
int fNextIndex;
SkTDArray<const SkFlatData*> fData;
- SkRefCntSet* fRefSet;
- SkRefCntSet* fTypefaceSet;
- SkNamedFactorySet* fFactorySet;
const SkFlatData* findAndReturnFlat(const T& element,
uint32_t writeBufferflags) {
SkFlatData* flat = SkFlatData::Create(fController, &element, fNextIndex,
- fFlattenProc, fRefSet,
- fTypefaceSet, writeBufferflags,
- fFactorySet);
+ fFlattenProc, writeBufferflags);
int hashIndex = ChecksumToHashIndex(flat->checksum());
const SkFlatData* candidate = fHash[hashIndex];
@@ -523,26 +580,53 @@ static void SkUnflattenObjectProc(SkOrderedReadBuffer& buffer, void* obj) {
class SkChunkFlatController : public SkFlatController {
public:
SkChunkFlatController(size_t minSize)
- : fHeap(minSize) {}
+ : fHeap(minSize)
+ , fRefSet(SkNEW(SkRefCntSet))
+ , fTypefaceSet(SkNEW(SkRefCntSet)) {
+ this->setPixelRefSet(fRefSet);
+ this->setTypefaceSet(fTypefaceSet);
+ this->setPixelRefPlayback(&fRefPlayback);
+ this->setTypefacePlayback(&fTypefacePlayback);
+ }
- virtual void* allocThrow(size_t bytes) {
+ ~SkChunkFlatController() {
+ fRefSet->unref();
+ fTypefaceSet->unref();
+ }
+
+ virtual void* allocThrow(size_t bytes) SK_OVERRIDE {
return fHeap.allocThrow(bytes);
}
- virtual void unalloc(void* ptr) {
+ virtual void unalloc(void* ptr) SK_OVERRIDE {
(void) fHeap.unalloc(ptr);
}
- void reset() { fHeap.reset(); }
+
+ void reset() {
+ fHeap.reset();
+ fRefSet->reset();
+ fTypefaceSet->reset();
+ fRefPlayback.reset(NULL);
+ fTypefacePlayback.reset(NULL);
+ }
+
+ void setupPlaybacks() const {
+ fRefPlayback.reset(fRefSet);
+ fTypefacePlayback.reset(fTypefaceSet);
+ }
+
private:
- SkChunkAlloc fHeap;
+ SkChunkAlloc fHeap;
+ SkRefCntSet* fRefSet;
+ SkRefCntSet* fTypefaceSet;
+ mutable SkRefCntPlayback fRefPlayback;
+ mutable SkTypefacePlayback fTypefacePlayback;
};
class SkBitmapDictionary : public SkFlatDictionary<SkBitmap> {
public:
- SkBitmapDictionary(SkFlatController* controller, SkRefCntSet* refSet = NULL,
- SkRefCntSet* typefaceSet = NULL,
- SkNamedFactorySet* factorySet = NULL)
- : SkFlatDictionary<SkBitmap>(controller, refSet, typefaceSet, factorySet) {
+ SkBitmapDictionary(SkFlatController* controller)
+ : SkFlatDictionary<SkBitmap>(controller) {
fFlattenProc = &SkFlattenObjectProc<SkBitmap>;
fUnflattenProc = &SkUnflattenObjectProc<SkBitmap>;
}
@@ -567,9 +651,8 @@ class SkMatrixDictionary : public SkFlatDictionary<SkMatrix> {
class SkPaintDictionary : public SkFlatDictionary<SkPaint> {
public:
- SkPaintDictionary(SkFlatController* controller, SkRefCntSet* refSet,
- SkRefCntSet* typefaceSet)
- : SkFlatDictionary<SkPaint>(controller, refSet, typefaceSet) {
+ SkPaintDictionary(SkFlatController* controller)
+ : SkFlatDictionary<SkPaint>(controller) {
fFlattenProc = &SkFlattenObjectProc<SkPaint>;
fUnflattenProc = &SkUnflattenObjectProc<SkPaint>;
}
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 06eae58bc6..c4c40c14c0 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -79,13 +79,11 @@ SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record) {
// copy over the refcnt dictionary to our reader
//
- fRCPlayback.reset(&record.fRCSet);
- fTFPlayback.reset(&record.fTFSet);
-
- fBitmaps = record.getBitmaps().unflattenToArray(&fRCPlayback, NULL);
- fMatrices = record.getMatrices().unflattenToArray(NULL, NULL);
- fPaints = record.getPaints().unflattenToArray(&fRCPlayback, &fTFPlayback);
- fRegions = record.getRegions().unflattenToArray(NULL, NULL);
+ record.fHeap.setupPlaybacks();
+ fBitmaps = record.getBitmaps().unflattenToArray();
+ fMatrices = record.getMatrices().unflattenToArray();
+ fPaints = record.getPaints().unflattenToArray();
+ fRegions = record.getRegions().unflattenToArray();
fPathHeap = record.fPathHeap;
SkSafeRef(fPathHeap);
diff --git a/src/core/SkPicturePlayback.h b/src/core/SkPicturePlayback.h
index c0c61e4e79..2110c71962 100644
--- a/src/core/SkPicturePlayback.h
+++ b/src/core/SkPicturePlayback.h
@@ -178,7 +178,6 @@ private:
SkPicture** fPictureRefs;
int fPictureCount;
- SkRefCntPlayback fRCPlayback;
SkTypefacePlayback fTFPlayback;
SkFactoryPlayback* fFactoryPlayback;
#ifdef SK_BUILD_FOR_ANDROID
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 8b3e9fdab6..c3f3ad12cf 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -18,9 +18,9 @@ enum {
SkPictureRecord::SkPictureRecord(uint32_t flags) :
fHeap(HEAP_BLOCK_SIZE),
- fBitmaps(&fHeap, &fRCSet),
+ fBitmaps(&fHeap),
fMatrices(&fHeap),
- fPaints(&fHeap, &fRCSet, &fTFSet),
+ fPaints(&fHeap),
fRegions(&fHeap),
fWriter(MIN_WRITER_SIZE),
fRecordFlags(flags) {
@@ -533,9 +533,6 @@ void SkPictureRecord::reset() {
fRestoreOffsetStack.setCount(1);
fRestoreOffsetStack.top() = 0;
-
- fRCSet.reset();
- fTFSet.reset();
}
void SkPictureRecord::addBitmap(const SkBitmap& bitmap) {
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 3dda39bfa9..cd429da919 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -201,9 +201,6 @@ public:
private:
SkChunkFlatController fHeap;
- SkRefCntSet fRCSet;
- SkRefCntSet fTFSet;
-
SkTDArray<BitmapIndexCacheEntry> fBitmapIndexCache;
SkBitmapDictionary fBitmaps;
SkMatrixDictionary fMatrices;
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index 75f1affa54..2ea642e30a 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -65,8 +65,9 @@ static size_t writeTypeface(SkWriter32* writer, SkTypeface* typeface) {
class FlattenableHeap : public SkFlatController {
public:
- FlattenableHeap(int numFlatsToKeep)
- : fNumFlatsToKeep(numFlatsToKeep) {
+ FlattenableHeap(int numFlatsToKeep, SkNamedFactorySet* fset)
+ : fNumFlatsToKeep(numFlatsToKeep) {
+ this->setNamedFactorySet(fset);
}
~FlattenableHeap() {
@@ -138,8 +139,8 @@ const SkFlatData* FlattenableHeap::flatToReplace() const {
class FlatDictionary : public SkFlatDictionary<SkFlattenable> {
public:
- FlatDictionary(FlattenableHeap* heap, SkNamedFactorySet* factorySet)
- : SkFlatDictionary<SkFlattenable>(heap, NULL, NULL, factorySet) {
+ FlatDictionary(FlattenableHeap* heap)
+ : SkFlatDictionary<SkFlattenable>(heap) {
fFlattenProc = &flattenFlattenableProc;
// No need to define fUnflattenProc since the writer will never
// unflatten the data.
@@ -597,10 +598,10 @@ SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
, fSharedHeap(!isCrossProcess(flags), controller->numberOfReaders())
, fWriter(*writer)
, fFlags(flags)
-, fBitmapHeap(BITMAPS_TO_KEEP)
-, fBitmapDictionary(&fBitmapHeap, NULL, NULL, fFactorySet)
-, fFlattenableHeap(FLATTENABLES_TO_KEEP)
-, fFlatDictionary(&fFlattenableHeap, fFactorySet) {
+, fBitmapHeap(BITMAPS_TO_KEEP, fFactorySet)
+, fBitmapDictionary(&fBitmapHeap)
+, fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet)
+, fFlatDictionary(&fFlattenableHeap) {
fController = controller;
fDone = false;
fBlockSize = 0; // need first block from controller
diff --git a/tests/FlatDataTest.cpp b/tests/FlatDataTest.cpp
index 755d8cd944..9d9f390d98 100644
--- a/tests/FlatDataTest.cpp
+++ b/tests/FlatDataTest.cpp
@@ -22,6 +22,15 @@ static void flattenFlattenableProc(SkOrderedWriteBuffer& buffer,
buffer.writeFlattenable((SkFlattenable*)obj);
}
+class Controller : public SkChunkFlatController {
+public:
+ Controller() : INHERITED(1024) {
+ this->INHERITED::setNamedFactorySet(SkNEW(SkNamedFactorySet))->unref();
+ }
+private:
+ typedef SkChunkFlatController INHERITED;
+};
+
/**
* Verify that two SkFlatData objects that created from the same object are
* identical when using an SkNamedFactorySet.
@@ -31,15 +40,12 @@ static void flattenFlattenableProc(SkOrderedWriteBuffer& buffer,
*/
static void testCreate(skiatest::Reporter* reporter, const void* obj,
void (*flattenProc)(SkOrderedWriteBuffer&, const void*)) {
- SkChunkFlatController controller(1024);
- SkNamedFactorySet factorySet;
+ Controller controller;
// No need to delete data because that will be taken care of by the
// controller.
- SkFlatData* data1 = SkFlatData::Create(&controller, obj, 0, flattenProc,
- NULL, NULL, 0, &factorySet);
+ SkFlatData* data1 = SkFlatData::Create(&controller, obj, 0, flattenProc, 0);
data1->setSentinelInCache();
- SkFlatData* data2 = SkFlatData::Create(&controller, obj, 0, flattenProc,
- NULL, NULL, 0, &factorySet);
+ SkFlatData* data2 = SkFlatData::Create(&controller, obj, 1, flattenProc, 0);
data2->setSentinelAsCandidate();
REPORTER_ASSERT(reporter, SkFlatData::Compare(data1, data2) == 0);
}