}
SkDELETE_ARRAY(fArray);
- if (rec) {
+ if (rec!= NULL && rec->count() > 0) {
fCount = rec->count();
fArray = SkNEW_ARRAY(SkRefCnt*, fCount);
rec->copyToArray(fArray);
///////////////////////////////////////////////////////////////////////////////
+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();
// 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.
class SkFlatController : public SkRefCnt {
public:
+ SkFlatController();
+ virtual ~SkFlatController();
/**
* Provide a new block of memory for the SkFlatDictionary to use.
*/
*/
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 {
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*),
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));
virtual ~SkFlatDictionary() {
fController->unref();
- SkSafeUnref(fRefSet);
- SkSafeUnref(fTypefaceSet);
- SkSafeUnref(fFactorySet);
}
int count() const { return fData.count(); }
* 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;
}
* 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;
}
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) {
int index = element->index() - 1;
SkASSERT((unsigned)index < (unsigned)count);
element->unflatten(&array[index], fUnflattenProc,
- refCntPlayback, facePlayback);
+ fController->getPixelRefPlayback(),
+ fController->getTypefacePlayback());
+
}
}
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];
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>;
}
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>;
}