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

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

Issue 1858323002: Enable flattening/unflattening with custom unflatten procs (Closed) Base URL: https://skia.googlesource.com/skia.git@flattenable
Patch Set: Send only the index or the string - never both Created 4 years, 8 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
« no previous file with comments | « src/core/SkValidatingReadBuffer.cpp ('k') | tests/FlattenableCustomFactory.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkWriteBuffer.h" 8 #include "SkWriteBuffer.h"
9 #include "SkBitmap.h" 9 #include "SkBitmap.h"
10 #include "SkBitmapHeap.h" 10 #include "SkBitmapHeap.h"
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 if (serializer) { 251 if (serializer) {
252 serializer->ref(); 252 serializer->ref();
253 SkASSERT(nullptr == fBitmapHeap); 253 SkASSERT(nullptr == fBitmapHeap);
254 SkSafeUnref(fBitmapHeap); 254 SkSafeUnref(fBitmapHeap);
255 fBitmapHeap = nullptr; 255 fBitmapHeap = nullptr;
256 } 256 }
257 } 257 }
258 258
259 void SkWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) { 259 void SkWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) {
260 /* 260 /*
261 * If we have a factoryset, then the first 32bits tell us... 261 * If this is not a validating buffer, then the first 32bits tell us...
262 * 0: failure to write the flattenable 262 * 0: failure to write the flattenable
263 * >0: (1-based) index into the SkFactorySet or SkNamedFactorySet 263 * >0: (1-based) index into fFactorySet or fFlattenableDict
264 * If we don't have a factoryset, then the first "ptr" is either the
265 * factory, or null for failure.
266 *
267 * The distinction is important, since 0-index is 32bits (always), but a
268 * 0-functionptr might be 32 or 64 bits.
269 */ 264 */
270 if (nullptr == flattenable) { 265 if (nullptr == flattenable) {
271 if (this->isValidating()) { 266 if (this->isValidating()) {
272 this->writeString(""); 267 this->writeString("");
273 } else if (fFactorySet != nullptr) { 268 } else {
274 this->write32(0); 269 this->write32(0);
275 } else {
276 this->writeFunctionPtr(nullptr);
277 } 270 }
278 return; 271 return;
279 } 272 }
280 273
281 SkFlattenable::Factory factory = flattenable->getFactory(); 274 const char* name;
282 SkASSERT(factory != nullptr); 275 SkFlattenable::Factory factory;
276 if (this->isValidating() || !fFactorySet) {
277 name = flattenable->getTypeName();
278 SkASSERT(name);
279 } else {
280 factory = flattenable->getFactory();
281 SkASSERT(factory);
282 }
283 283
284 /* 284 /*
285 * We can write 1 of 3 versions of the flattenable: 285 * We can write 1 of 3 versions of the flattenable:
286 * 1. function-ptr : this is the fastest for the reader, but assumes that 286 * 1. string : this is used by the validating read/write buffers.
287 * the writer and reader are in the same process.
288 * 2. index into fFactorySet : This is assumes the writer will later 287 * 2. index into fFactorySet : This is assumes the writer will later
289 * resolve the function-ptrs into strings for its reader. SkPicture 288 * resolve the function-ptrs into strings for its reader. SkPicture
290 * does exactly this, by writing a table of names (matching the indices ) 289 * does exactly this, by writing a table of names (matching the indices )
291 * up front in its serialized form. 290 * up front in its serialized form.
292 * 3. index into fNamedFactorySet. fNamedFactorySet will also store the 291 * 3. index into fFlattenableDict (plus string if necessary): We store
293 * name. SkGPipe uses this technique so it can write the name to its 292 * the string to allow the reader to specify its own factories after
294 * stream before writing the flattenable. 293 * write time. In order to improve compression, if we have already
294 * written the string, we only write its index.
295 */ 295 */
296 if (this->isValidating()) { 296 if (this->isValidating()) {
297 this->writeString(flattenable->getTypeName()); 297 this->writeString(name);
298 } else if (fFactorySet) { 298 } else if (fFactorySet) {
299 this->write32(fFactorySet->add(factory)); 299 this->write32(fFactorySet->add(factory));
300 } else { 300 } else {
301 this->writeFunctionPtr((void*)factory); 301 SkString key(name);
302 if (uint32_t* indexPtr = fFlattenableDict.find(key)) {
303 // We will write the index as a 32-bit int. We want the first byte
304 // that we send to be zero - this will act as a sentinel that we
305 // have an index (not a string). However, whether the "first" byte
306 // is high or low depends on the endianness. So we will guarantee
307 // that the first and last byte are zero. The middle 16-bits is
308 // plenty to store an index.
309 SkASSERT(0 == *indexPtr >> 16);
310 this->write32(*indexPtr << 8);
msarett 2016/04/20 17:20:59 There are more ways to do this: (1) I originally a
311 } else {
312 // Otherwise write the string. Clients should not use the empty
313 // string as a name, or we will have a problem.
314 SkASSERT(strcmp("", name));
315 this->writeString(name);
316
317 // Add key to dictionary
318 fFlattenableDict.set(key, fFlattenableDict.count() + 1);
319 }
302 } 320 }
303 321
304 // make room for the size of the flattened object 322 // make room for the size of the flattened object
305 (void)fWriter.reserve(sizeof(uint32_t)); 323 (void)fWriter.reserve(sizeof(uint32_t));
306 // record the current size, so we can subtract after the object writes. 324 // record the current size, so we can subtract after the object writes.
307 size_t offset = fWriter.bytesWritten(); 325 size_t offset = fWriter.bytesWritten();
308 // now flatten the object 326 // now flatten the object
309 flattenable->flatten(*this); 327 flattenable->flatten(*this);
310 size_t objSize = fWriter.bytesWritten() - offset; 328 size_t objSize = fWriter.bytesWritten() - offset;
311 // record the obj's size 329 // record the obj's size
312 fWriter.overwriteTAt(offset - sizeof(uint32_t), SkToU32(objSize)); 330 fWriter.overwriteTAt(offset - sizeof(uint32_t), SkToU32(objSize));
313 } 331 }
OLDNEW
« no previous file with comments | « src/core/SkValidatingReadBuffer.cpp ('k') | tests/FlattenableCustomFactory.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698