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