Index: src/core/SkWriteBuffer.cpp |
diff --git a/src/core/SkWriteBuffer.cpp b/src/core/SkWriteBuffer.cpp |
index 33ac03b49de66e51d82fc1a0bb1a1a1c4c4c05b9..1159ef3383fef5603d08bbf046a8a47e2cd9a446 100644 |
--- a/src/core/SkWriteBuffer.cpp |
+++ b/src/core/SkWriteBuffer.cpp |
@@ -8,11 +8,14 @@ |
#include "SkWriteBuffer.h" |
#include "SkBitmap.h" |
#include "SkData.h" |
+#include "SkDeduper.h" |
#include "SkPixelRef.h" |
#include "SkPtrRecorder.h" |
#include "SkStream.h" |
#include "SkTypeface.h" |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
SkBinaryWriteBuffer::SkBinaryWriteBuffer(uint32_t flags) |
: fFlags(flags) |
, fFactorySet(nullptr) |
@@ -173,6 +176,11 @@ void SkBinaryWriteBuffer::writeBitmap(const SkBitmap& bitmap) { |
} |
void SkBinaryWriteBuffer::writeImage(const SkImage* image) { |
+ if (fDeduper) { |
+ this->write32(fDeduper->findOrDefineImage(const_cast<SkImage*>(image))); |
+ return; |
+ } |
+ |
this->writeInt(image->width()); |
this->writeInt(image->height()); |
@@ -193,6 +201,11 @@ void SkBinaryWriteBuffer::writeImage(const SkImage* image) { |
} |
void SkBinaryWriteBuffer::writeTypeface(SkTypeface* obj) { |
+ if (fDeduper) { |
+ this->write32(fDeduper->findOrDefineTypeface(obj)); |
+ return; |
+ } |
+ |
if (nullptr == obj || nullptr == fTFSet) { |
fWriter.write32(0); |
} else { |
@@ -222,53 +235,51 @@ void SkBinaryWriteBuffer::setPixelSerializer(SkPixelSerializer* serializer) { |
} |
void SkBinaryWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) { |
- /* |
- * The first 32 bits tell us... |
- * 0: failure to write the flattenable |
- * >0: index (1-based) into fFactorySet or fFlattenableDict or |
- * the first character of a string |
- */ |
if (nullptr == flattenable) { |
this->write32(0); |
return; |
} |
- /* |
- * We can write 1 of 2 versions of the flattenable: |
- * 1. index into fFactorySet : This assumes the writer will later |
- * resolve the function-ptrs into strings for its reader. SkPicture |
- * does exactly this, by writing a table of names (matching the indices) |
- * up front in its serialized form. |
- * 2. string name of the flattenable or index into fFlattenableDict: We |
- * store the string to allow the reader to specify its own factories |
- * after write time. In order to improve compression, if we have |
- * already written the string, we write its index instead. |
- */ |
- if (fFactorySet) { |
- SkFlattenable::Factory factory = flattenable->getFactory(); |
- SkASSERT(factory); |
- this->write32(fFactorySet->add(factory)); |
+ if (fDeduper) { |
+ this->write32(fDeduper->findOrDefineFactory(const_cast<SkFlattenable*>(flattenable))); |
} else { |
- const char* name = flattenable->getTypeName(); |
- SkASSERT(name); |
- SkString key(name); |
- if (uint32_t* indexPtr = fFlattenableDict.find(key)) { |
- // We will write the index as a 32-bit int. We want the first byte |
- // that we send to be zero - this will act as a sentinel that we |
- // have an index (not a string). This means that we will send the |
- // the index shifted left by 8. The remaining 24-bits should be |
- // plenty to store the index. Note that this strategy depends on |
- // being little endian. |
- SkASSERT(0 == *indexPtr >> 24); |
- this->write32(*indexPtr << 8); |
+ /* |
+ * We can write 1 of 2 versions of the flattenable: |
+ * 1. index into fFactorySet : This assumes the writer will later |
+ * resolve the function-ptrs into strings for its reader. SkPicture |
+ * does exactly this, by writing a table of names (matching the indices) |
+ * up front in its serialized form. |
+ * 2. string name of the flattenable or index into fFlattenableDict: We |
+ * store the string to allow the reader to specify its own factories |
+ * after write time. In order to improve compression, if we have |
+ * already written the string, we write its index instead. |
+ */ |
+ if (fFactorySet) { |
+ SkFlattenable::Factory factory = flattenable->getFactory(); |
+ SkASSERT(factory); |
+ this->write32(fFactorySet->add(factory)); |
} else { |
- // Otherwise write the string. Clients should not use the empty |
- // string as a name, or we will have a problem. |
- SkASSERT(strcmp("", name)); |
- this->writeString(name); |
- |
- // Add key to dictionary. |
- fFlattenableDict.set(key, fFlattenableDict.count() + 1); |
+ const char* name = flattenable->getTypeName(); |
+ SkASSERT(name); |
+ SkString key(name); |
+ if (uint32_t* indexPtr = fFlattenableDict.find(key)) { |
+ // We will write the index as a 32-bit int. We want the first byte |
+ // that we send to be zero - this will act as a sentinel that we |
+ // have an index (not a string). This means that we will send the |
+ // the index shifted left by 8. The remaining 24-bits should be |
+ // plenty to store the index. Note that this strategy depends on |
+ // being little endian. |
+ SkASSERT(0 == *indexPtr >> 24); |
+ this->write32(*indexPtr << 8); |
+ } else { |
+ // Otherwise write the string. Clients should not use the empty |
+ // string as a name, or we will have a problem. |
+ SkASSERT(strcmp("", name)); |
+ this->writeString(name); |
+ |
+ // Add key to dictionary. |
+ fFlattenableDict.set(key, fFlattenableDict.count() + 1); |
+ } |
} |
} |