diff options
-rw-r--r-- | src/core/SkPictureFlat.cpp | 52 | ||||
-rw-r--r-- | src/core/SkPictureFlat.h | 175 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 12 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.h | 1 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 7 | ||||
-rw-r--r-- | src/core/SkPictureRecord.h | 3 | ||||
-rw-r--r-- | src/pipe/SkGPipeWrite.cpp | 17 | ||||
-rw-r--r-- | tests/FlatDataTest.cpp | 18 |
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); } |