| 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);
|
| + }
|
| }
|
| }
|
|
|
|
|