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