Store more behavior of SkFlatDictionary in SkFlatController.

Code refactoring for simplicity.

Review URL: https://codereview.appspot.com/6427046

git-svn-id: http://skia.googlecode.com/svn/trunk@4929 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
scroggo@google.com 2012-08-02 18:49:49 +00:00
Родитель c3841b927b
Коммит 1554360a95
8 изменённых файлов: 199 добавлений и 86 удалений

Просмотреть файл

@ -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();

Просмотреть файл

@ -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>;
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -178,7 +178,6 @@ private:
SkPicture** fPictureRefs;
int fPictureCount;
SkRefCntPlayback fRCPlayback;
SkTypefacePlayback fTFPlayback;
SkFactoryPlayback* fFactoryPlayback;
#ifdef SK_BUILD_FOR_ANDROID

Просмотреть файл

@ -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) {

Просмотреть файл

@ -201,9 +201,6 @@ public:
private:
SkChunkFlatController fHeap;
SkRefCntSet fRCSet;
SkRefCntSet fTFSet;
SkTDArray<BitmapIndexCacheEntry> fBitmapIndexCache;
SkBitmapDictionary fBitmaps;
SkMatrixDictionary fMatrices;

Просмотреть файл

@ -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

Просмотреть файл

@ -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);
}