| 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 "SkOrderedWriteBuffer.h" | 9 #include "SkOrderedWriteBuffer.h" |
| 10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
| 11 #include "SkData.h" | 11 #include "SkData.h" |
| 12 #include "SkPixelRef.h" | |
| 13 #include "SkPtrRecorder.h" | 12 #include "SkPtrRecorder.h" |
| 14 #include "SkStream.h" | 13 #include "SkStream.h" |
| 15 #include "SkTypeface.h" | 14 #include "SkTypeface.h" |
| 16 | 15 |
| 17 SkOrderedWriteBuffer::SkOrderedWriteBuffer(size_t minSize) | 16 SkOrderedWriteBuffer::SkOrderedWriteBuffer(size_t minSize) |
| 18 : INHERITED() | 17 : INHERITED() |
| 19 , fFactorySet(NULL) | 18 , fFactorySet(NULL) |
| 20 , fNamedFactorySet(NULL) | 19 , fNamedFactorySet(NULL) |
| 21 , fWriter(minSize) | 20 , fWriter(minSize) |
| 22 , fBitmapHeap(NULL) | 21 , fBitmapHeap(NULL) |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 if (bytesWritten < length) { | 136 if (bytesWritten < length) { |
| 138 fWriter.reservePad(length - bytesWritten); | 137 fWriter.reservePad(length - bytesWritten); |
| 139 } | 138 } |
| 140 return bytesWritten; | 139 return bytesWritten; |
| 141 } | 140 } |
| 142 | 141 |
| 143 bool SkOrderedWriteBuffer::writeToStream(SkWStream* stream) { | 142 bool SkOrderedWriteBuffer::writeToStream(SkWStream* stream) { |
| 144 return fWriter.writeToStream(stream); | 143 return fWriter.writeToStream(stream); |
| 145 } | 144 } |
| 146 | 145 |
| 146 // Defined in SkBitmap.cpp |
| 147 bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t r
owBytes, |
| 148 int32_t* x, int32_t* y); |
| 149 |
| 147 void SkOrderedWriteBuffer::writeBitmap(const SkBitmap& bitmap) { | 150 void SkOrderedWriteBuffer::writeBitmap(const SkBitmap& bitmap) { |
| 148 // Record the width and height. This way if readBitmap fails a dummy bitmap
can be drawn at the | 151 // Record the width and height. This way if readBitmap fails a dummy bitmap
can be drawn at the |
| 149 // right size. | 152 // right size. |
| 150 this->writeInt(bitmap.width()); | 153 this->writeInt(bitmap.width()); |
| 151 this->writeInt(bitmap.height()); | 154 this->writeInt(bitmap.height()); |
| 152 | 155 |
| 153 // Record information about the bitmap in one of three ways, in order of pri
ority: | 156 // Record information about the bitmap in one of three ways, in order of pri
ority: |
| 154 // 1. If there is an SkBitmapHeap, store it in the heap. The client can avoi
d serializing the | 157 // 1. If there is an SkBitmapHeap, store it in the heap. The client can avoi
d serializing the |
| 155 // bitmap entirely or serialize it later as desired. A boolean value of t
rue will be written | 158 // bitmap entirely or serialize it later as desired. A boolean value of t
rue will be written |
| 156 // to the stream to signify that a heap was used. | 159 // to the stream to signify that a heap was used. |
| 157 // 2. Write an encoded version of the bitmap. After writing a boolean value
of false, signifying | 160 // 2. If there is a function for encoding bitmaps, use it to write an encode
d version of the |
| 158 // that a heap was not used, write the size of the encoded data. A non-ze
ro size signifies | 161 // bitmap. After writing a boolean value of false, signifying that a heap
was not used, write |
| 159 // that encoded data was written. | 162 // the size of the encoded data. A non-zero size signifies that encoded d
ata was written. |
| 160 // A. If the bitmap has an encoded representation, write it to the stream
. | |
| 161 // B. If there is a function for encoding bitmaps, use it. | |
| 162 // 3. Call SkBitmap::flatten. After writing a boolean value of false, signif
ying that a heap was | 163 // 3. Call SkBitmap::flatten. After writing a boolean value of false, signif
ying that a heap was |
| 163 // not used, write a zero to signify that the data was not encoded. | 164 // not used, write a zero to signify that the data was not encoded. |
| 164 bool useBitmapHeap = fBitmapHeap != NULL; | 165 bool useBitmapHeap = fBitmapHeap != NULL; |
| 165 // Write a bool: true if the SkBitmapHeap is to be used, in which case the r
eader must use an | 166 // Write a bool: true if the SkBitmapHeap is to be used, in which case the r
eader must use an |
| 166 // SkBitmapHeapReader to read the SkBitmap. False if the bitmap was serializ
ed another way. | 167 // SkBitmapHeapReader to read the SkBitmap. False if the bitmap was serializ
ed another way. |
| 167 this->writeBool(useBitmapHeap); | 168 this->writeBool(useBitmapHeap); |
| 168 if (useBitmapHeap) { | 169 if (useBitmapHeap) { |
| 169 SkASSERT(NULL == fBitmapEncoder); | 170 SkASSERT(NULL == fBitmapEncoder); |
| 170 int32_t slot = fBitmapHeap->insert(bitmap); | 171 int32_t slot = fBitmapHeap->insert(bitmap); |
| 171 fWriter.write32(slot); | 172 fWriter.write32(slot); |
| 172 // crbug.com/155875 | 173 // crbug.com/155875 |
| 173 // The generation ID is not required information. We write it to prevent
collisions | 174 // The generation ID is not required information. We write it to prevent
collisions |
| 174 // in SkFlatDictionary. It is possible to get a collision when a previo
usly | 175 // in SkFlatDictionary. It is possible to get a collision when a previo
usly |
| 175 // unflattened (i.e. stale) instance of a similar flattenable is in the
dictionary | 176 // unflattened (i.e. stale) instance of a similar flattenable is in the
dictionary |
| 176 // and the instance currently being written is re-using the same slot fr
om the | 177 // and the instance currently being written is re-using the same slot fr
om the |
| 177 // bitmap heap. | 178 // bitmap heap. |
| 178 fWriter.write32(bitmap.getGenerationID()); | 179 fWriter.write32(bitmap.getGenerationID()); |
| 179 return; | 180 return; |
| 180 } | 181 } |
| 181 bool encoded = false; | 182 if (fBitmapEncoder != NULL) { |
| 182 // Before attempting to encode the SkBitmap, check to see if there is alread
y an encoded | 183 SkASSERT(NULL == fBitmapHeap); |
| 183 // version. | 184 size_t offset; |
| 184 SkPixelRef* ref = bitmap.pixelRef(); | 185 SkAutoDataUnref data(fBitmapEncoder(&offset, bitmap)); |
| 185 if (ref != NULL) { | |
| 186 SkAutoDataUnref data(ref->refEncodedData()); | |
| 187 if (data.get() != NULL) { | 186 if (data.get() != NULL) { |
| 188 // Write the length to indicate that the bitmap was encoded successf
ully, followed | 187 // Write the length to indicate that the bitmap was encoded successf
ully, followed |
| 189 // by the actual data. This must match the case where fBitmapEncoder
is used so the | 188 // by the actual data. |
| 190 // reader need not know the difference. | |
| 191 this->writeUInt(SkToU32(data->size())); | 189 this->writeUInt(SkToU32(data->size())); |
| 192 fWriter.writePad(data->data(), data->size()); | 190 fWriter.writePad(data->data(), data->size()); |
| 193 encoded = true; | 191 #ifdef BUMP_PICTURE_VERSION |
| 192 // Recording this fixes https://code.google.com/p/skia/issues/detail
?id=1301, but |
| 193 // also requires bumping PICTURE_VERSION, so leaving out for now. |
| 194 // Store the coordinate of the offset, rather than fPixelRefOffset,
which may be |
| 195 // different depending on the decoder. |
| 196 int32_t x, y; |
| 197 if (0 == offset || !get_upper_left_from_offset(bitmap.config(), offs
et, |
| 198 bitmap.rowBytes(), &x
, &y)) { |
| 199 x = y = 0; |
| 200 } |
| 201 this->write32(x); |
| 202 this->write32(y); |
| 203 #endif |
| 204 return; |
| 194 } | 205 } |
| 195 } | 206 } |
| 196 if (fBitmapEncoder != NULL && !encoded) { | 207 // Bitmap was not encoded. Record a zero, implying that the reader need not
decode. |
| 197 SkASSERT(NULL == fBitmapHeap); | 208 this->writeUInt(0); |
| 198 SkDynamicMemoryWStream stream; | 209 bitmap.flatten(*this); |
| 199 if (fBitmapEncoder(&stream, bitmap)) { | |
| 200 uint32_t offset = fWriter.bytesWritten(); | |
| 201 // Write the length to indicate that the bitmap was encoded successf
ully, followed | |
| 202 // by the actual data. This must match the case where the original d
ata is used so the | |
| 203 // reader need not know the difference. | |
| 204 size_t length = stream.getOffset(); | |
| 205 this->writeUInt(SkToU32(length)); | |
| 206 if (stream.read(fWriter.reservePad(length), 0, length)) { | |
| 207 encoded = true; | |
| 208 } else { | |
| 209 // Writing the stream failed, so go back to original state to st
ore another way. | |
| 210 fWriter.rewindToOffset(offset); | |
| 211 } | |
| 212 } | |
| 213 } | |
| 214 if (!encoded) { | |
| 215 // Bitmap was not encoded. Record a zero, implying that the reader need
not decode. | |
| 216 this->writeUInt(0); | |
| 217 bitmap.flatten(*this); | |
| 218 } | |
| 219 } | 210 } |
| 220 | 211 |
| 221 void SkOrderedWriteBuffer::writeTypeface(SkTypeface* obj) { | 212 void SkOrderedWriteBuffer::writeTypeface(SkTypeface* obj) { |
| 222 if (NULL == obj || NULL == fTFSet) { | 213 if (NULL == obj || NULL == fTFSet) { |
| 223 fWriter.write32(0); | 214 fWriter.write32(0); |
| 224 } else { | 215 } else { |
| 225 fWriter.write32(fTFSet->add(obj)); | 216 fWriter.write32(fTFSet->add(obj)); |
| 226 } | 217 } |
| 227 } | 218 } |
| 228 | 219 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 // make room for the size of the flattened object | 309 // make room for the size of the flattened object |
| 319 (void)fWriter.reserve(sizeof(uint32_t)); | 310 (void)fWriter.reserve(sizeof(uint32_t)); |
| 320 // record the current size, so we can subtract after the object writes. | 311 // record the current size, so we can subtract after the object writes. |
| 321 uint32_t offset = fWriter.size(); | 312 uint32_t offset = fWriter.size(); |
| 322 // now flatten the object | 313 // now flatten the object |
| 323 flattenObject(flattenable, *this); | 314 flattenObject(flattenable, *this); |
| 324 uint32_t objSize = fWriter.size() - offset; | 315 uint32_t objSize = fWriter.size() - offset; |
| 325 // record the obj's size | 316 // record the obj's size |
| 326 *fWriter.peek32(offset - sizeof(uint32_t)) = objSize; | 317 *fWriter.peek32(offset - sizeof(uint32_t)) = objSize; |
| 327 } | 318 } |
| OLD | NEW |