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