Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/core/SkOrderedWriteBuffer.cpp

Issue 15489004: New API for encoding bitmaps during serialization. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix ifdef'd out code Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698