Chromium Code Reviews| Index: src/core/SkWriteBuffer.cpp |
| diff --git a/src/core/SkWriteBuffer.cpp b/src/core/SkWriteBuffer.cpp |
| index 33ac03b49de66e51d82fc1a0bb1a1a1c4c4c05b9..98257ca807da0ab7ce26034df6ff741f5cc30ddc 100644 |
| --- a/src/core/SkWriteBuffer.cpp |
| +++ b/src/core/SkWriteBuffer.cpp |
| @@ -8,11 +8,30 @@ |
| #include "SkWriteBuffer.h" |
| #include "SkBitmap.h" |
| #include "SkData.h" |
| +#include "SkDeduper.h" |
| #include "SkPixelRef.h" |
| #include "SkPtrRecorder.h" |
| #include "SkStream.h" |
| #include "SkTypeface.h" |
| +bool SkWriteBuffer::newWriteImage(const SkImage* image) { |
| + if (fDeduper) { |
| + this->write32(fDeduper->findOrDefineImage(const_cast<SkImage*>(image))); |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| +bool SkWriteBuffer::newWriteTypeface(SkTypeface* typeface) { |
| + if (fDeduper) { |
| + this->write32(fDeduper->findOrDefineTypeface(typeface)); |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| +/////////////////////////////////////////////////////////////////////////////////////////////////// |
| + |
| SkBinaryWriteBuffer::SkBinaryWriteBuffer(uint32_t flags) |
| : fFlags(flags) |
| , fFactorySet(nullptr) |
| @@ -173,6 +192,10 @@ void SkBinaryWriteBuffer::writeBitmap(const SkBitmap& bitmap) { |
| } |
| void SkBinaryWriteBuffer::writeImage(const SkImage* image) { |
| + if (this->newWriteImage(image)) { |
|
mtklein_C
2016/09/12 19:47:58
Doesn't really seem like newWriteImage() and newWr
reed1
2016/09/12 21:35:23
Done.
|
| + return; |
| + } |
| + |
| this->writeInt(image->width()); |
| this->writeInt(image->height()); |
| @@ -193,6 +216,10 @@ void SkBinaryWriteBuffer::writeImage(const SkImage* image) { |
| } |
| void SkBinaryWriteBuffer::writeTypeface(SkTypeface* obj) { |
| + if (this->newWriteTypeface(obj)) { |
| + return; |
| + } |
| + |
| if (nullptr == obj || nullptr == fTFSet) { |
| fWriter.write32(0); |
| } else { |
| @@ -222,53 +249,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); |
| + } |
| } |
| } |