| 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(nullptr) |
| 21 , fNamedFactorySet(NULL) | 21 , fNamedFactorySet(nullptr) |
| 22 , fBitmapHeap(NULL) | 22 , fBitmapHeap(nullptr) |
| 23 , fTFSet(NULL) { | 23 , fTFSet(nullptr) { |
| 24 } | 24 } |
| 25 | 25 |
| 26 SkWriteBuffer::SkWriteBuffer(void* storage, size_t storageSize, uint32_t flags) | 26 SkWriteBuffer::SkWriteBuffer(void* storage, size_t storageSize, uint32_t flags) |
| 27 : fFlags(flags) | 27 : fFlags(flags) |
| 28 , fFactorySet(NULL) | 28 , fFactorySet(nullptr) |
| 29 , fNamedFactorySet(NULL) | 29 , fNamedFactorySet(nullptr) |
| 30 , fWriter(storage, storageSize) | 30 , fWriter(storage, storageSize) |
| 31 , fBitmapHeap(NULL) | 31 , fBitmapHeap(nullptr) |
| 32 , fTFSet(NULL) { | 32 , fTFSet(nullptr) { |
| 33 } | 33 } |
| 34 | 34 |
| 35 SkWriteBuffer::~SkWriteBuffer() { | 35 SkWriteBuffer::~SkWriteBuffer() { |
| 36 SkSafeUnref(fFactorySet); | 36 SkSafeUnref(fFactorySet); |
| 37 SkSafeUnref(fNamedFactorySet); | 37 SkSafeUnref(fNamedFactorySet); |
| 38 SkSafeUnref(fBitmapHeap); | 38 SkSafeUnref(fBitmapHeap); |
| 39 SkSafeUnref(fTFSet); | 39 SkSafeUnref(fTFSet); |
| 40 } | 40 } |
| 41 | 41 |
| 42 void SkWriteBuffer::writeByteArray(const void* data, size_t size) { | 42 void SkWriteBuffer::writeByteArray(const void* data, size_t size) { |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 | 158 |
| 159 // Record information about the bitmap in one of three ways, in order of pri
ority: | 159 // Record information about the bitmap in one of three ways, in order of pri
ority: |
| 160 // 1. If there is an SkBitmapHeap, store it in the heap. The client can avoi
d serializing the | 160 // 1. If there is an SkBitmapHeap, store it in the heap. The client can avoi
d serializing the |
| 161 // bitmap entirely or serialize it later as desired. A boolean value of t
rue will be written | 161 // bitmap entirely or serialize it later as desired. A boolean value of t
rue will be written |
| 162 // to the stream to signify that a heap was used. | 162 // to the stream to signify that a heap was used. |
| 163 // 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 |
| 164 // 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 |
| 165 // 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. |
| 166 // 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 |
| 167 // 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. |
| 168 bool useBitmapHeap = fBitmapHeap != NULL; | 168 bool useBitmapHeap = fBitmapHeap != nullptr; |
| 169 // 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 |
| 170 // 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. |
| 171 this->writeBool(useBitmapHeap); | 171 this->writeBool(useBitmapHeap); |
| 172 if (useBitmapHeap) { | 172 if (useBitmapHeap) { |
| 173 SkASSERT(NULL == fPixelSerializer); | 173 SkASSERT(nullptr == fPixelSerializer); |
| 174 int32_t slot = fBitmapHeap->insert(bitmap); | 174 int32_t slot = fBitmapHeap->insert(bitmap); |
| 175 fWriter.write32(slot); | 175 fWriter.write32(slot); |
| 176 // crbug.com/155875 | 176 // crbug.com/155875 |
| 177 // 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 |
| 178 // 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 |
| 179 // 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 |
| 180 // 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 |
| 181 // bitmap heap. | 181 // bitmap heap. |
| 182 fWriter.write32(bitmap.getGenerationID()); | 182 fWriter.write32(bitmap.getGenerationID()); |
| 183 return; | 183 return; |
| 184 } | 184 } |
| 185 | 185 |
| 186 SkPixelRef* pixelRef = bitmap.pixelRef(); | 186 SkPixelRef* pixelRef = bitmap.pixelRef(); |
| 187 if (pixelRef) { | 187 if (pixelRef) { |
| 188 // see if the pixelref already has an encoded version | 188 // see if the pixelref already has an encoded version |
| 189 SkAutoDataUnref existingData(pixelRef->refEncodedData()); | 189 SkAutoDataUnref existingData(pixelRef->refEncodedData()); |
| 190 if (existingData.get() != NULL) { | 190 if (existingData.get() != nullptr) { |
| 191 // Assumes that if the client did not set a serializer, they are | 191 // Assumes that if the client did not set a serializer, they are |
| 192 // happy to get the encoded data. | 192 // happy to get the encoded data. |
| 193 if (!fPixelSerializer || fPixelSerializer->useEncodedData(existingDa
ta->data(), | 193 if (!fPixelSerializer || fPixelSerializer->useEncodedData(existingDa
ta->data(), |
| 194 existingDa
ta->size())) { | 194 existingDa
ta->size())) { |
| 195 write_encoded_bitmap(this, existingData, bitmap.pixelRefOrigin()
); | 195 write_encoded_bitmap(this, existingData, bitmap.pixelRefOrigin()
); |
| 196 return; | 196 return; |
| 197 } | 197 } |
| 198 } | 198 } |
| 199 | 199 |
| 200 // see if the caller wants to manually encode | 200 // see if the caller wants to manually encode |
| 201 SkAutoPixmapUnlock result; | 201 SkAutoPixmapUnlock result; |
| 202 if (fPixelSerializer && bitmap.requestLock(&result)) { | 202 if (fPixelSerializer && bitmap.requestLock(&result)) { |
| 203 const SkPixmap& pmap = result.pixmap(); | 203 const SkPixmap& pmap = result.pixmap(); |
| 204 SkASSERT(NULL == fBitmapHeap); | 204 SkASSERT(nullptr == fBitmapHeap); |
| 205 SkAutoDataUnref data(fPixelSerializer->encodePixels(pmap.info(), | 205 SkAutoDataUnref data(fPixelSerializer->encodePixels(pmap.info(), |
| 206 pmap.addr(), | 206 pmap.addr(), |
| 207 pmap.rowBytes())
); | 207 pmap.rowBytes())
); |
| 208 if (data.get() != NULL) { | 208 if (data.get() != nullptr) { |
| 209 // if we have to "encode" the bitmap, then we assume there is no | 209 // if we have to "encode" the bitmap, then we assume there is no |
| 210 // offset to share, since we are effectively creating a new pixe
lref | 210 // offset to share, since we are effectively creating a new pixe
lref |
| 211 write_encoded_bitmap(this, data, SkIPoint::Make(0, 0)); | 211 write_encoded_bitmap(this, data, SkIPoint::Make(0, 0)); |
| 212 return; | 212 return; |
| 213 } | 213 } |
| 214 } | 214 } |
| 215 } | 215 } |
| 216 | 216 |
| 217 this->writeUInt(0); // signal raw pixels | 217 this->writeUInt(0); // signal raw pixels |
| 218 SkBitmap::WriteRawPixels(this, bitmap); | 218 SkBitmap::WriteRawPixels(this, bitmap); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 240 | 240 |
| 241 encoded.reset(image->encode(SkImageEncoder::kPNG_Type, 100)); | 241 encoded.reset(image->encode(SkImageEncoder::kPNG_Type, 100)); |
| 242 if (encoded && try_write_encoded(this, encoded)) { | 242 if (encoded && try_write_encoded(this, encoded)) { |
| 243 return; | 243 return; |
| 244 } | 244 } |
| 245 | 245 |
| 246 this->writeUInt(0); // signal no pixels (in place of the size of the encoded
data) | 246 this->writeUInt(0); // signal no pixels (in place of the size of the encoded
data) |
| 247 } | 247 } |
| 248 | 248 |
| 249 void SkWriteBuffer::writeTypeface(SkTypeface* obj) { | 249 void SkWriteBuffer::writeTypeface(SkTypeface* obj) { |
| 250 if (NULL == obj || NULL == fTFSet) { | 250 if (nullptr == obj || nullptr == fTFSet) { |
| 251 fWriter.write32(0); | 251 fWriter.write32(0); |
| 252 } else { | 252 } else { |
| 253 fWriter.write32(fTFSet->add(obj)); | 253 fWriter.write32(fTFSet->add(obj)); |
| 254 } | 254 } |
| 255 } | 255 } |
| 256 | 256 |
| 257 SkFactorySet* SkWriteBuffer::setFactoryRecorder(SkFactorySet* rec) { | 257 SkFactorySet* SkWriteBuffer::setFactoryRecorder(SkFactorySet* rec) { |
| 258 SkRefCnt_SafeAssign(fFactorySet, rec); | 258 SkRefCnt_SafeAssign(fFactorySet, rec); |
| 259 if (fNamedFactorySet != NULL) { | 259 if (fNamedFactorySet != nullptr) { |
| 260 fNamedFactorySet->unref(); | 260 fNamedFactorySet->unref(); |
| 261 fNamedFactorySet = NULL; | 261 fNamedFactorySet = nullptr; |
| 262 } | 262 } |
| 263 return rec; | 263 return rec; |
| 264 } | 264 } |
| 265 | 265 |
| 266 SkNamedFactorySet* SkWriteBuffer::setNamedFactoryRecorder(SkNamedFactorySet* rec
) { | 266 SkNamedFactorySet* SkWriteBuffer::setNamedFactoryRecorder(SkNamedFactorySet* rec
) { |
| 267 SkRefCnt_SafeAssign(fNamedFactorySet, rec); | 267 SkRefCnt_SafeAssign(fNamedFactorySet, rec); |
| 268 if (fFactorySet != NULL) { | 268 if (fFactorySet != nullptr) { |
| 269 fFactorySet->unref(); | 269 fFactorySet->unref(); |
| 270 fFactorySet = NULL; | 270 fFactorySet = nullptr; |
| 271 } | 271 } |
| 272 return rec; | 272 return rec; |
| 273 } | 273 } |
| 274 | 274 |
| 275 SkRefCntSet* SkWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) { | 275 SkRefCntSet* SkWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) { |
| 276 SkRefCnt_SafeAssign(fTFSet, rec); | 276 SkRefCnt_SafeAssign(fTFSet, rec); |
| 277 return rec; | 277 return rec; |
| 278 } | 278 } |
| 279 | 279 |
| 280 void SkWriteBuffer::setBitmapHeap(SkBitmapHeap* bitmapHeap) { | 280 void SkWriteBuffer::setBitmapHeap(SkBitmapHeap* bitmapHeap) { |
| 281 SkRefCnt_SafeAssign(fBitmapHeap, bitmapHeap); | 281 SkRefCnt_SafeAssign(fBitmapHeap, bitmapHeap); |
| 282 if (bitmapHeap != NULL) { | 282 if (bitmapHeap != nullptr) { |
| 283 SkASSERT(NULL == fPixelSerializer); | 283 SkASSERT(nullptr == fPixelSerializer); |
| 284 fPixelSerializer.reset(NULL); | 284 fPixelSerializer.reset(nullptr); |
| 285 } | 285 } |
| 286 } | 286 } |
| 287 | 287 |
| 288 void SkWriteBuffer::setPixelSerializer(SkPixelSerializer* serializer) { | 288 void SkWriteBuffer::setPixelSerializer(SkPixelSerializer* serializer) { |
| 289 fPixelSerializer.reset(serializer); | 289 fPixelSerializer.reset(serializer); |
| 290 if (serializer) { | 290 if (serializer) { |
| 291 serializer->ref(); | 291 serializer->ref(); |
| 292 SkASSERT(NULL == fBitmapHeap); | 292 SkASSERT(nullptr == fBitmapHeap); |
| 293 SkSafeUnref(fBitmapHeap); | 293 SkSafeUnref(fBitmapHeap); |
| 294 fBitmapHeap = NULL; | 294 fBitmapHeap = nullptr; |
| 295 } | 295 } |
| 296 } | 296 } |
| 297 | 297 |
| 298 void SkWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) { | 298 void SkWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) { |
| 299 /* | 299 /* |
| 300 * If we have a factoryset, then the first 32bits tell us... | 300 * If we have a factoryset, then the first 32bits tell us... |
| 301 * 0: failure to write the flattenable | 301 * 0: failure to write the flattenable |
| 302 * >0: (1-based) index into the SkFactorySet or SkNamedFactorySet | 302 * >0: (1-based) index into the SkFactorySet or SkNamedFactorySet |
| 303 * If we don't have a factoryset, then the first "ptr" is either the | 303 * If we don't have a factoryset, then the first "ptr" is either the |
| 304 * factory, or null for failure. | 304 * factory, or null for failure. |
| 305 * | 305 * |
| 306 * The distinction is important, since 0-index is 32bits (always), but a | 306 * The distinction is important, since 0-index is 32bits (always), but a |
| 307 * 0-functionptr might be 32 or 64 bits. | 307 * 0-functionptr might be 32 or 64 bits. |
| 308 */ | 308 */ |
| 309 if (NULL == flattenable) { | 309 if (nullptr == flattenable) { |
| 310 if (this->isValidating()) { | 310 if (this->isValidating()) { |
| 311 this->writeString(""); | 311 this->writeString(""); |
| 312 } else if (fFactorySet != NULL || fNamedFactorySet != NULL) { | 312 } else if (fFactorySet != nullptr || fNamedFactorySet != nullptr) { |
| 313 this->write32(0); | 313 this->write32(0); |
| 314 } else { | 314 } else { |
| 315 this->writeFunctionPtr(NULL); | 315 this->writeFunctionPtr(nullptr); |
| 316 } | 316 } |
| 317 return; | 317 return; |
| 318 } | 318 } |
| 319 | 319 |
| 320 SkFlattenable::Factory factory = flattenable->getFactory(); | 320 SkFlattenable::Factory factory = flattenable->getFactory(); |
| 321 SkASSERT(factory != NULL); | 321 SkASSERT(factory != nullptr); |
| 322 | 322 |
| 323 /* | 323 /* |
| 324 * We can write 1 of 3 versions of the flattenable: | 324 * We can write 1 of 3 versions of the flattenable: |
| 325 * 1. function-ptr : this is the fastest for the reader, but assumes that | 325 * 1. function-ptr : this is the fastest for the reader, but assumes that |
| 326 * the writer and reader are in the same process. | 326 * the writer and reader are in the same process. |
| 327 * 2. index into fFactorySet : This is assumes the writer will later | 327 * 2. index into fFactorySet : This is assumes the writer will later |
| 328 * resolve the function-ptrs into strings for its reader. SkPicture | 328 * resolve the function-ptrs into strings for its reader. SkPicture |
| 329 * does exactly this, by writing a table of names (matching the indices
) | 329 * does exactly this, by writing a table of names (matching the indices
) |
| 330 * up front in its serialized form. | 330 * up front in its serialized form. |
| 331 * 3. index into fNamedFactorySet. fNamedFactorySet will also store the | 331 * 3. index into fNamedFactorySet. fNamedFactorySet will also store the |
| (...skipping 17 matching lines...) Expand all Loading... |
| 349 // make room for the size of the flattened object | 349 // make room for the size of the flattened object |
| 350 (void)fWriter.reserve(sizeof(uint32_t)); | 350 (void)fWriter.reserve(sizeof(uint32_t)); |
| 351 // record the current size, so we can subtract after the object writes. | 351 // record the current size, so we can subtract after the object writes. |
| 352 size_t offset = fWriter.bytesWritten(); | 352 size_t offset = fWriter.bytesWritten(); |
| 353 // now flatten the object | 353 // now flatten the object |
| 354 flattenable->flatten(*this); | 354 flattenable->flatten(*this); |
| 355 size_t objSize = fWriter.bytesWritten() - offset; | 355 size_t objSize = fWriter.bytesWritten() - offset; |
| 356 // record the obj's size | 356 // record the obj's size |
| 357 fWriter.overwriteTAt(offset - sizeof(uint32_t), SkToU32(objSize)); | 357 fWriter.overwriteTAt(offset - sizeof(uint32_t), SkToU32(objSize)); |
| 358 } | 358 } |
| OLD | NEW |