Store more behavior of SkFlatDictionary in SkFlatController.
authorscroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 2 Aug 2012 18:49:49 +0000 (18:49 +0000)
committerscroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 2 Aug 2012 18:49:49 +0000 (18:49 +0000)
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

src/core/SkPictureFlat.cpp
src/core/SkPictureFlat.h
src/core/SkPicturePlayback.cpp
src/core/SkPicturePlayback.h
src/core/SkPictureRecord.cpp
src/core/SkPictureRecord.h
src/pipe/SkGPipeWrite.cpp
tests/FlatDataTest.cpp

index b0c02cc..fa65ca4 100644 (file)
@@ -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();
index ddcb100..dbec5c9 100644 (file)
@@ -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>;
     }
index 06eae58..c4c40c1 100644 (file)
@@ -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);
index c0c61e4..2110c71 100644 (file)
@@ -178,7 +178,6 @@ private:
     SkPicture** fPictureRefs;
     int fPictureCount;
 
-    SkRefCntPlayback fRCPlayback;
     SkTypefacePlayback fTFPlayback;
     SkFactoryPlayback*   fFactoryPlayback;
 #ifdef SK_BUILD_FOR_ANDROID
index 8b3e9fd..c3f3ad1 100644 (file)
@@ -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) {
index 3dda39b..cd429da 100644 (file)
@@ -201,9 +201,6 @@ public:
 private:
     SkChunkFlatController fHeap;
 
-    SkRefCntSet fRCSet;
-    SkRefCntSet fTFSet;
-    
     SkTDArray<BitmapIndexCacheEntry> fBitmapIndexCache;
     SkBitmapDictionary fBitmaps;
     SkMatrixDictionary fMatrices;
index 75f1aff..2ea642e 100644 (file)
@@ -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
index 755d8cd..9d9f390 100644 (file)
@@ -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);
 }