Home | History | Annotate | Download | only in core
      1 #include "SkFlattenable.h"
      2 #include "SkTypeface.h"
      3 
      4 void SkFlattenable::flatten(SkFlattenableWriteBuffer&)
      5 {
      6     /*  we don't write anything at the moment, but this allows our subclasses
      7         to not know that, since we want them to always call INHERITED::flatten()
      8         in their code.
      9     */
     10 }
     11 
     12 ///////////////////////////////////////////////////////////////////////////////
     13 ///////////////////////////////////////////////////////////////////////////////
     14 
     15 SkFlattenableReadBuffer::SkFlattenableReadBuffer() {
     16     fRCArray = NULL;
     17     fRCCount = 0;
     18 
     19     fTFArray = NULL;
     20     fTFCount = 0;
     21 
     22     fFactoryArray = NULL;
     23     fFactoryCount = 0;
     24 }
     25 
     26 SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data) :
     27         INHERITED(data, 1024 * 1024) {
     28     fRCArray = NULL;
     29     fRCCount = 0;
     30 
     31     fTFArray = NULL;
     32     fTFCount = 0;
     33 
     34     fFactoryArray = NULL;
     35     fFactoryCount = 0;
     36 }
     37 
     38 SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data, size_t size)
     39         : INHERITED(data, size) {
     40     fRCArray = NULL;
     41     fRCCount = 0;
     42 
     43     fTFArray = NULL;
     44     fTFCount = 0;
     45 
     46     fFactoryArray = NULL;
     47     fFactoryCount = 0;
     48 }
     49 
     50 SkTypeface* SkFlattenableReadBuffer::readTypeface() {
     51     uint32_t index = this->readU32();
     52     if (0 == index || index > (unsigned)fTFCount) {
     53         if (index) {
     54             SkDebugf("====== typeface index %d\n", index);
     55         }
     56         return NULL;
     57     } else {
     58         SkASSERT(fTFArray);
     59         return fTFArray[index - 1];
     60     }
     61 }
     62 
     63 SkRefCnt* SkFlattenableReadBuffer::readRefCnt() {
     64     uint32_t index = this->readU32();
     65     if (0 == index || index > (unsigned)fRCCount) {
     66         return NULL;
     67     } else {
     68         SkASSERT(fRCArray);
     69         return fRCArray[index - 1];
     70     }
     71 }
     72 
     73 SkFlattenable* SkFlattenableReadBuffer::readFlattenable() {
     74     SkFlattenable::Factory factory = NULL;
     75 
     76     if (fFactoryCount > 0) {
     77         uint32_t index = this->readU32();
     78         if (index > 0) {
     79             index -= 1;
     80             SkASSERT(index < (unsigned)fFactoryCount);
     81             factory = fFactoryArray[index];
     82             // if we recorded an index, but failed to get a factory, we need
     83             // to skip the flattened data in the buffer
     84             if (NULL == factory) {
     85                 uint32_t size = this->readU32();
     86                 this->skip(size);
     87                 // fall through and return NULL for the object
     88             }
     89         }
     90     } else {
     91         factory = (SkFlattenable::Factory)readFunctionPtr();
     92     }
     93 
     94     SkFlattenable* obj = NULL;
     95     if (factory) {
     96         uint32_t sizeRecorded = this->readU32();
     97         uint32_t offset = this->offset();
     98         obj = (*factory)(*this);
     99         // check that we read the amount we expected
    100         uint32_t sizeRead = this->offset() - offset;
    101         if (sizeRecorded != sizeRead) {
    102             // we could try to fix up the offset...
    103             sk_throw();
    104         }
    105     }
    106     return obj;
    107 }
    108 
    109 void* SkFlattenableReadBuffer::readFunctionPtr() {
    110     void* proc;
    111     this->read(&proc, sizeof(proc));
    112     return proc;
    113 }
    114 
    115 ///////////////////////////////////////////////////////////////////////////////
    116 
    117 SkFlattenableWriteBuffer::SkFlattenableWriteBuffer(size_t minSize) :
    118         INHERITED(minSize) {
    119     fFlags = (Flags)0;
    120     fRCRecorder = NULL;
    121     fTFRecorder = NULL;
    122     fFactoryRecorder = NULL;
    123 }
    124 
    125 SkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() {
    126     fRCRecorder->safeUnref();
    127     fTFRecorder->safeUnref();
    128     fFactoryRecorder->safeUnref();
    129 }
    130 
    131 SkRefCntRecorder* SkFlattenableWriteBuffer::setRefCntRecorder(
    132                                                     SkRefCntRecorder* rec) {
    133     SkRefCnt_SafeAssign(fRCRecorder, rec);
    134     return rec;
    135 }
    136 
    137 SkRefCntRecorder* SkFlattenableWriteBuffer::setTypefaceRecorder(
    138                                                     SkRefCntRecorder* rec) {
    139     SkRefCnt_SafeAssign(fTFRecorder, rec);
    140     return rec;
    141 }
    142 
    143 SkFactoryRecorder* SkFlattenableWriteBuffer::setFactoryRecorder(
    144                                                     SkFactoryRecorder* rec) {
    145     SkRefCnt_SafeAssign(fFactoryRecorder, rec);
    146     return rec;
    147 }
    148 
    149 void SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) {
    150     if (NULL == obj || NULL == fTFRecorder) {
    151         this->write32(0);
    152     } else {
    153         this->write32(fTFRecorder->record(obj));
    154     }
    155 }
    156 
    157 void SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) {
    158     if (NULL == obj || NULL == fRCRecorder) {
    159         this->write32(0);
    160     } else {
    161         this->write32(fRCRecorder->record(obj));
    162     }
    163 }
    164 
    165 void SkFlattenableWriteBuffer::writeFlattenable(SkFlattenable* flattenable) {
    166     SkFlattenable::Factory factory = NULL;
    167     if (flattenable) {
    168         factory = flattenable->getFactory();
    169     }
    170 
    171     if (fFactoryRecorder) {
    172         this->write32(fFactoryRecorder->record(factory));
    173     } else {
    174         this->writeFunctionPtr((void*)factory);
    175     }
    176 
    177     if (factory) {
    178         // make room for the size of the flatttened object
    179         (void)this->reserve(sizeof(uint32_t));
    180         // record the current size, so we can subtract after the object writes.
    181         uint32_t offset = this->size();
    182         // now flatten the object
    183         flattenable->flatten(*this);
    184         uint32_t objSize = this->size() - offset;
    185         // record the obj's size
    186         *this->peek32(offset - sizeof(uint32_t)) = objSize;
    187     }
    188 }
    189 
    190 void SkFlattenableWriteBuffer::writeFunctionPtr(void* proc) {
    191     *(void**)this->reserve(sizeof(void*)) = proc;
    192 }
    193 
    194 ///////////////////////////////////////////////////////////////////////////////
    195 
    196 SkRefCntRecorder::~SkRefCntRecorder() {
    197     // call this now, while our decPtr() is sill in scope
    198     this->reset();
    199 }
    200 
    201 void SkRefCntRecorder::incPtr(void* ptr) {
    202     ((SkRefCnt*)ptr)->ref();
    203 }
    204 
    205 void SkRefCntRecorder::decPtr(void* ptr) {
    206     ((SkRefCnt*)ptr)->unref();
    207 }
    208 
    209 ///////////////////////////////////////////////////////////////////////////////
    210 ///////////////////////////////////////////////////////////////////////////////
    211 ///////////////////////////////////////////////////////////////////////////////
    212 
    213 #define MAX_PAIR_COUNT  64
    214 
    215 struct Pair {
    216     const char*             fName;
    217     SkFlattenable::Factory  fFactory;
    218 };
    219 
    220 static int gCount;
    221 static Pair gPairs[MAX_PAIR_COUNT];
    222 
    223 void SkFlattenable::Register(const char name[], Factory factory) {
    224     SkASSERT(name);
    225     SkASSERT(factory);
    226 
    227     static bool gOnce;
    228     if (!gOnce) {
    229         gCount = 0;
    230         gOnce = true;
    231     }
    232 
    233     SkASSERT(gCount < MAX_PAIR_COUNT);
    234 
    235     gPairs[gCount].fName = name;
    236     gPairs[gCount].fFactory = factory;
    237     gCount += 1;
    238 }
    239 
    240 SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
    241     const Pair* pairs = gPairs;
    242     for (int i = gCount - 1; i >= 0; --i) {
    243         if (strcmp(pairs[i].fName, name) == 0) {
    244             return pairs[i].fFactory;
    245         }
    246     }
    247     return NULL;
    248 }
    249 
    250 const char* SkFlattenable::FactoryToName(Factory fact) {
    251     const Pair* pairs = gPairs;
    252     for (int i = gCount - 1; i >= 0; --i) {
    253         if (pairs[i].fFactory == fact) {
    254             return pairs[i].fName;
    255         }
    256     }
    257     return NULL;
    258 }
    259 
    260 bool SkFlattenable::toDumpString(SkString* str) const {
    261     return false;
    262 }
    263 
    264