OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "SkWriteBuffer.h" | 9 #include "SkWriteBuffer.h" |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
11 #include "SkBitmapHeap.h" | 11 #include "SkBitmapHeap.h" |
12 #include "SkData.h" | 12 #include "SkData.h" |
13 #include "SkPixelRef.h" | 13 #include "SkPixelRef.h" |
14 #include "SkPtrRecorder.h" | 14 #include "SkPtrRecorder.h" |
15 #include "SkStream.h" | 15 #include "SkStream.h" |
16 #include "SkTypeface.h" | 16 #include "SkTypeface.h" |
17 | 17 |
18 SkWriteBuffer::SkWriteBuffer(uint32_t flags) | 18 SkWriteBuffer::SkWriteBuffer(uint32_t flags) |
19 : fFlags(flags) | 19 : fFlags(flags) |
20 , fFactorySet(NULL) | 20 , fFactorySet(NULL) |
21 , fNamedFactorySet(NULL) | 21 , fNamedFactorySet(NULL) |
22 , fBitmapHeap(NULL) | 22 , fBitmapHeap(NULL) |
23 , fTFSet(NULL) | 23 , fTFSet(NULL) { |
24 , fBitmapEncoder(NULL) { | |
25 } | 24 } |
26 | 25 |
27 SkWriteBuffer::SkWriteBuffer(void* storage, size_t storageSize, uint32_t flags) | 26 SkWriteBuffer::SkWriteBuffer(void* storage, size_t storageSize, uint32_t flags) |
28 : fFlags(flags) | 27 : fFlags(flags) |
29 , fFactorySet(NULL) | 28 , fFactorySet(NULL) |
30 , fNamedFactorySet(NULL) | 29 , fNamedFactorySet(NULL) |
31 , fWriter(storage, storageSize) | 30 , fWriter(storage, storageSize) |
32 , fBitmapHeap(NULL) | 31 , fBitmapHeap(NULL) |
33 , fTFSet(NULL) | 32 , fTFSet(NULL) { |
34 , fBitmapEncoder(NULL) { | |
35 } | 33 } |
36 | 34 |
37 SkWriteBuffer::~SkWriteBuffer() { | 35 SkWriteBuffer::~SkWriteBuffer() { |
38 SkSafeUnref(fFactorySet); | 36 SkSafeUnref(fFactorySet); |
39 SkSafeUnref(fNamedFactorySet); | 37 SkSafeUnref(fNamedFactorySet); |
40 SkSafeUnref(fBitmapHeap); | 38 SkSafeUnref(fBitmapHeap); |
41 SkSafeUnref(fTFSet); | 39 SkSafeUnref(fTFSet); |
42 } | 40 } |
43 | 41 |
44 void SkWriteBuffer::writeByteArray(const void* data, size_t size) { | 42 void SkWriteBuffer::writeByteArray(const void* data, size_t size) { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 // 2. If there is a function for encoding bitmaps, use it to write an encode
d version of the | 163 // 2. If there is a function for encoding bitmaps, use it to write an encode
d version of the |
166 // bitmap. After writing a boolean value of false, signifying that a heap
was not used, write | 164 // bitmap. After writing a boolean value of false, signifying that a heap
was not used, write |
167 // the size of the encoded data. A non-zero size signifies that encoded d
ata was written. | 165 // the size of the encoded data. A non-zero size signifies that encoded d
ata was written. |
168 // 3. Call SkBitmap::flatten. After writing a boolean value of false, signif
ying that a heap was | 166 // 3. Call SkBitmap::flatten. After writing a boolean value of false, signif
ying that a heap was |
169 // not used, write a zero to signify that the data was not encoded. | 167 // not used, write a zero to signify that the data was not encoded. |
170 bool useBitmapHeap = fBitmapHeap != NULL; | 168 bool useBitmapHeap = fBitmapHeap != NULL; |
171 // Write a bool: true if the SkBitmapHeap is to be used, in which case the r
eader must use an | 169 // Write a bool: true if the SkBitmapHeap is to be used, in which case the r
eader must use an |
172 // SkBitmapHeapReader to read the SkBitmap. False if the bitmap was serializ
ed another way. | 170 // SkBitmapHeapReader to read the SkBitmap. False if the bitmap was serializ
ed another way. |
173 this->writeBool(useBitmapHeap); | 171 this->writeBool(useBitmapHeap); |
174 if (useBitmapHeap) { | 172 if (useBitmapHeap) { |
175 SkASSERT(NULL == fBitmapEncoder); | 173 SkASSERT(NULL == fPixelSerializer); |
176 int32_t slot = fBitmapHeap->insert(bitmap); | 174 int32_t slot = fBitmapHeap->insert(bitmap); |
177 fWriter.write32(slot); | 175 fWriter.write32(slot); |
178 // crbug.com/155875 | 176 // crbug.com/155875 |
179 // The generation ID is not required information. We write it to prevent
collisions | 177 // The generation ID is not required information. We write it to prevent
collisions |
180 // in SkFlatDictionary. It is possible to get a collision when a previo
usly | 178 // in SkFlatDictionary. It is possible to get a collision when a previo
usly |
181 // unflattened (i.e. stale) instance of a similar flattenable is in the
dictionary | 179 // unflattened (i.e. stale) instance of a similar flattenable is in the
dictionary |
182 // and the instance currently being written is re-using the same slot fr
om the | 180 // and the instance currently being written is re-using the same slot fr
om the |
183 // bitmap heap. | 181 // bitmap heap. |
184 fWriter.write32(bitmap.getGenerationID()); | 182 fWriter.write32(bitmap.getGenerationID()); |
185 return; | 183 return; |
186 } | 184 } |
187 | 185 |
188 // see if the pixelref already has an encoded version | 186 SkPixelRef* pixelRef = bitmap.pixelRef(); |
189 if (bitmap.pixelRef()) { | 187 if (pixelRef) { |
190 SkAutoDataUnref data(bitmap.pixelRef()->refEncodedData()); | 188 // see if the pixelref already has an encoded version |
191 if (data.get() != NULL) { | 189 SkAutoDataUnref existingData(pixelRef->refEncodedData()); |
192 write_encoded_bitmap(this, data, bitmap.pixelRefOrigin()); | 190 if (existingData.get() != NULL) { |
193 return; | 191 // Assumes that if the client did not set a serializer, they are |
| 192 // happy to get the encoded data. |
| 193 if (!fPixelSerializer || fPixelSerializer->useEncodedData(existingDa
ta->data(), |
| 194 existingDa
ta->size())) { |
| 195 write_encoded_bitmap(this, existingData, bitmap.pixelRefOrigin()
); |
| 196 return; |
| 197 } |
| 198 } |
| 199 |
| 200 // see if the caller wants to manually encode |
| 201 if (fPixelSerializer) { |
| 202 SkASSERT(NULL == fBitmapHeap); |
| 203 SkAutoLockPixels alp(bitmap); |
| 204 SkAutoDataUnref data(fPixelSerializer->encodePixels(bitmap.info(), |
| 205 bitmap.getPixels
(), |
| 206 bitmap.rowBytes(
))); |
| 207 if (data.get() != NULL) { |
| 208 // if we have to "encode" the bitmap, then we assume there is no |
| 209 // offset to share, since we are effectively creating a new pixe
lref |
| 210 write_encoded_bitmap(this, data, SkIPoint::Make(0, 0)); |
| 211 return; |
| 212 } |
194 } | 213 } |
195 } | 214 } |
196 | 215 |
197 // see if the caller wants to manually encode | |
198 if (fBitmapEncoder != NULL) { | |
199 SkASSERT(NULL == fBitmapHeap); | |
200 size_t offset = 0; // this parameter is deprecated/ignored | |
201 // if we have to "encode" the bitmap, then we assume there is no | |
202 // offset to share, since we are effectively creating a new pixelref | |
203 SkAutoDataUnref data(fBitmapEncoder(&offset, bitmap)); | |
204 if (data.get() != NULL) { | |
205 write_encoded_bitmap(this, data, SkIPoint::Make(0, 0)); | |
206 return; | |
207 } | |
208 } | |
209 | |
210 this->writeUInt(0); // signal raw pixels | 216 this->writeUInt(0); // signal raw pixels |
211 SkBitmap::WriteRawPixels(this, bitmap); | 217 SkBitmap::WriteRawPixels(this, bitmap); |
212 } | 218 } |
213 | 219 |
214 void SkWriteBuffer::writeTypeface(SkTypeface* obj) { | 220 void SkWriteBuffer::writeTypeface(SkTypeface* obj) { |
215 if (NULL == obj || NULL == fTFSet) { | 221 if (NULL == obj || NULL == fTFSet) { |
216 fWriter.write32(0); | 222 fWriter.write32(0); |
217 } else { | 223 } else { |
218 fWriter.write32(fTFSet->add(obj)); | 224 fWriter.write32(fTFSet->add(obj)); |
219 } | 225 } |
(...skipping 18 matching lines...) Expand all Loading... |
238 } | 244 } |
239 | 245 |
240 SkRefCntSet* SkWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) { | 246 SkRefCntSet* SkWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) { |
241 SkRefCnt_SafeAssign(fTFSet, rec); | 247 SkRefCnt_SafeAssign(fTFSet, rec); |
242 return rec; | 248 return rec; |
243 } | 249 } |
244 | 250 |
245 void SkWriteBuffer::setBitmapHeap(SkBitmapHeap* bitmapHeap) { | 251 void SkWriteBuffer::setBitmapHeap(SkBitmapHeap* bitmapHeap) { |
246 SkRefCnt_SafeAssign(fBitmapHeap, bitmapHeap); | 252 SkRefCnt_SafeAssign(fBitmapHeap, bitmapHeap); |
247 if (bitmapHeap != NULL) { | 253 if (bitmapHeap != NULL) { |
248 SkASSERT(NULL == fBitmapEncoder); | 254 SkASSERT(NULL == fPixelSerializer); |
249 fBitmapEncoder = NULL; | 255 fPixelSerializer.reset(NULL); |
250 } | 256 } |
251 } | 257 } |
252 | 258 |
253 void SkWriteBuffer::setBitmapEncoder(SkPicture::EncodeBitmap bitmapEncoder) { | 259 void SkWriteBuffer::setPixelSerializer(SkPixelSerializer* serializer) { |
254 fBitmapEncoder = bitmapEncoder; | 260 fPixelSerializer.reset(serializer); |
255 if (bitmapEncoder != NULL) { | 261 if (serializer) { |
| 262 serializer->ref(); |
256 SkASSERT(NULL == fBitmapHeap); | 263 SkASSERT(NULL == fBitmapHeap); |
257 SkSafeUnref(fBitmapHeap); | 264 SkSafeUnref(fBitmapHeap); |
258 fBitmapHeap = NULL; | 265 fBitmapHeap = NULL; |
259 } | 266 } |
260 } | 267 } |
261 | 268 |
262 void SkWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) { | 269 void SkWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) { |
263 /* | 270 /* |
264 * If we have a factoryset, then the first 32bits tell us... | 271 * If we have a factoryset, then the first 32bits tell us... |
265 * 0: failure to write the flattenable | 272 * 0: failure to write the flattenable |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 // make room for the size of the flattened object | 320 // make room for the size of the flattened object |
314 (void)fWriter.reserve(sizeof(uint32_t)); | 321 (void)fWriter.reserve(sizeof(uint32_t)); |
315 // record the current size, so we can subtract after the object writes. | 322 // record the current size, so we can subtract after the object writes. |
316 size_t offset = fWriter.bytesWritten(); | 323 size_t offset = fWriter.bytesWritten(); |
317 // now flatten the object | 324 // now flatten the object |
318 flattenable->flatten(*this); | 325 flattenable->flatten(*this); |
319 size_t objSize = fWriter.bytesWritten() - offset; | 326 size_t objSize = fWriter.bytesWritten() - offset; |
320 // record the obj's size | 327 // record the obj's size |
321 fWriter.overwriteTAt(offset - sizeof(uint32_t), SkToU32(objSize)); | 328 fWriter.overwriteTAt(offset - sizeof(uint32_t), SkToU32(objSize)); |
322 } | 329 } |
OLD | NEW |