• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "SkFlattenable.h"
2 #include "SkTypeface.h"
3 
4 #include "SkMatrix.h"
5 #include "SkRegion.h"
6 
SkReadMatrix(SkReader32 * reader,SkMatrix * matrix)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 
SkWriteMatrix(SkWriter32 * writer,const SkMatrix & matrix)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 
SkReadRegion(SkReader32 * reader,SkRegion * rgn)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 
SkWriteRegion(SkWriter32 * writer,const SkRegion & rgn)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 
flatten(SkFlattenableWriteBuffer &)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 
SkFlattenableReadBuffer()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 
SkFlattenableReadBuffer(const void * data)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 
SkFlattenableReadBuffer(const void * data,size_t size)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 
readTypeface()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 
readRefCnt()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 
readFlattenable()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 
readFunctionPtr()138 void* SkFlattenableReadBuffer::readFunctionPtr() {
139     void* proc;
140     this->read(&proc, sizeof(proc));
141     return proc;
142 }
143 
144 ///////////////////////////////////////////////////////////////////////////////
145 
SkFlattenableWriteBuffer(size_t minSize)146 SkFlattenableWriteBuffer::SkFlattenableWriteBuffer(size_t minSize) :
147         INHERITED(minSize) {
148     fFlags = (Flags)0;
149     fRCSet = NULL;
150     fTFSet = NULL;
151     fFactorySet = NULL;
152 }
153 
~SkFlattenableWriteBuffer()154 SkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() {
155     SkSafeUnref(fRCSet);
156     SkSafeUnref(fTFSet);
157     SkSafeUnref(fFactorySet);
158 }
159 
setRefCntRecorder(SkRefCntSet * rec)160 SkRefCntSet* SkFlattenableWriteBuffer::setRefCntRecorder(SkRefCntSet* rec) {
161     SkRefCnt_SafeAssign(fRCSet, rec);
162     return rec;
163 }
164 
setTypefaceRecorder(SkRefCntSet * rec)165 SkRefCntSet* SkFlattenableWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) {
166     SkRefCnt_SafeAssign(fTFSet, rec);
167     return rec;
168 }
169 
setFactoryRecorder(SkFactorySet * rec)170 SkFactorySet* SkFlattenableWriteBuffer::setFactoryRecorder(SkFactorySet* rec) {
171     SkRefCnt_SafeAssign(fFactorySet, rec);
172     return rec;
173 }
174 
writeTypeface(SkTypeface * obj)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 
writeRefCnt(SkRefCnt * obj)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 
writeFlattenable(SkFlattenable * flattenable)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 
writeFunctionPtr(void * proc)216 void SkFlattenableWriteBuffer::writeFunctionPtr(void* proc) {
217     *(void**)this->reserve(sizeof(void*)) = proc;
218 }
219 
220 ///////////////////////////////////////////////////////////////////////////////
221 
~SkRefCntSet()222 SkRefCntSet::~SkRefCntSet() {
223     // call this now, while our decPtr() is sill in scope
224     this->reset();
225 }
226 
incPtr(void * ptr)227 void SkRefCntSet::incPtr(void* ptr) {
228     ((SkRefCnt*)ptr)->ref();
229 }
230 
decPtr(void * ptr)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 
Register(const char name[],Factory factory)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 
NameToFactory(const char name[])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 
FactoryToName(Factory fact)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 
toDumpString(SkString * str) const286 bool SkFlattenable::toDumpString(SkString* str) const {
287     return false;
288 }
289 
290