diff options
author | 2016-09-13 08:09:45 -0700 | |
---|---|---|
committer | 2016-09-13 08:09:45 -0700 | |
commit | 54dc4878b02765efea39e68b218df1e4bfff4b88 (patch) | |
tree | 296347d73c08b8b1d0a0b244ca062434ac48caa1 /src/core | |
parent | 5f1d0f61ea182829826d9d76cb85346d3e23305d (diff) |
add pipecanvas
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2201323003
Review-Url: https://codereview.chromium.org/2201323003
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkDeduper.h | 39 | ||||
-rw-r--r-- | src/core/SkPipe.h | 74 | ||||
-rw-r--r-- | src/core/SkReadBuffer.cpp | 17 | ||||
-rw-r--r-- | src/core/SkReadBuffer.h | 10 | ||||
-rw-r--r-- | src/core/SkWriteBuffer.cpp | 91 |
5 files changed, 189 insertions, 42 deletions
diff --git a/src/core/SkDeduper.h b/src/core/SkDeduper.h new file mode 100644 index 0000000000..f82f4fd8c2 --- /dev/null +++ b/src/core/SkDeduper.h @@ -0,0 +1,39 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkDeduper_DEFINED +#define SkDeduper_DEFINED + +#include "SkTypes.h" + +class SkImage; +class SkPicture; +class SkTypeface; + +class SkDeduper { +public: + virtual ~SkDeduper() {} + + // These return 0 on failure + + virtual int findOrDefineImage(SkImage*) = 0; + virtual int findOrDefinePicture(SkPicture*) = 0; + virtual int findOrDefineTypeface(SkTypeface*) = 0; + virtual int findOrDefineFactory(SkFlattenable*) = 0; +}; + +class SkInflator { +public: + virtual ~SkInflator() {} + + virtual SkImage* getImage(int) = 0; + virtual SkPicture* getPicture(int) = 0; + virtual SkTypeface* getTypeface(int) = 0; + virtual SkFlattenable::Factory getFactory(int) = 0; +}; + +#endif diff --git a/src/core/SkPipe.h b/src/core/SkPipe.h new file mode 100644 index 0000000000..d3d5a362e7 --- /dev/null +++ b/src/core/SkPipe.h @@ -0,0 +1,74 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPipe_DEFINED +#define SkPipe_DEFINED + +#include "SkTypes.h" + +class SkCanvas; +class SkImage; +class SkPicture; +class SkTypefaceSerializer; +class SkTypefaceDeserializer; +class SkWStream; + +class SkPipeSerializer { +public: + SkPipeSerializer(); + ~SkPipeSerializer(); + + // Ownership is not transferred, so caller must ceep the serializer alive + void setTypefaceSerializer(SkTypefaceSerializer*); + + void resetCache(); + + void write(SkPicture*, SkWStream*); + void write(SkImage*, SkWStream*); + + SkCanvas* beginWrite(const SkRect& cullBounds, SkWStream*); + void endWrite(); + +private: + class Impl; + std::unique_ptr<Impl> fImpl; +}; + +class SkPipeDeserializer { +public: + SkPipeDeserializer(); + ~SkPipeDeserializer(); + + // Ownership is not transferred, so caller must ceep the deserializer alive + void setTypefaceDeserializer(SkTypefaceDeserializer*); + + sk_sp<SkPicture> readPicture(const void*, size_t); + sk_sp<SkImage> readImage(const void*, size_t); + bool playback(const void*, size_t, SkCanvas*); + +private: + class Impl; + std::unique_ptr<Impl> fImpl; +}; + +////////////////////////////////////////////////////////////////////////////////////////////////// + +class SkTypefaceSerializer { +public: + virtual ~SkTypefaceSerializer() {} + + virtual sk_sp<SkData> serialize(SkTypeface*) = 0; +}; + +class SkTypefaceDeserializer { +public: + virtual ~SkTypefaceDeserializer() {} + + virtual sk_sp<SkTypeface> deserialize(const void* data, size_t size) = 0; +}; + +#endif diff --git a/src/core/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp index 43eaf20261..4b9d5987a1 100644 --- a/src/core/SkReadBuffer.cpp +++ b/src/core/SkReadBuffer.cpp @@ -6,6 +6,7 @@ */ #include "SkBitmap.h" +#include "SkDeduper.h" #include "SkErrorInternals.h" #include "SkImage.h" #include "SkImageDeserializer.h" @@ -258,6 +259,11 @@ sk_sp<SkImage> SkReadBuffer::readBitmapAsImage() { } sk_sp<SkImage> SkReadBuffer::readImage() { + if (fInflator) { + SkImage* img = fInflator->getImage(this->read32()); + return img ? sk_ref_sp(img) : nullptr; + } + int width = this->read32(); int height = this->read32(); if (width <= 0 || height <= 0) { // SkImage never has a zero dimension @@ -298,6 +304,10 @@ sk_sp<SkImage> SkReadBuffer::readImage() { } sk_sp<SkTypeface> SkReadBuffer::readTypeface() { + if (fInflator) { + return sk_ref_sp(fInflator->getTypeface(this->read32())); + } + uint32_t index = fReader.readU32(); if (0 == index || index > (unsigned)fTFCount) { return nullptr; @@ -314,7 +324,12 @@ SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) { SkFlattenable::Factory factory = nullptr; - if (fFactoryCount > 0) { + if (fInflator) { + factory = fInflator->getFactory(this->read32()); + if (!factory) { + return nullptr; + } + } else if (fFactoryCount > 0) { int32_t index = fReader.readU32(); if (0 == index) { return nullptr; // writer failed to give us the flattenable diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h index 7c4ecc6bd3..1873c7d3f4 100644 --- a/src/core/SkReadBuffer.h +++ b/src/core/SkReadBuffer.h @@ -27,6 +27,7 @@ class SkBitmap; class SkImage; +class SkInflator; #if defined(SK_DEBUG) && defined(SK_BUILD_FOR_MAC) #define DEBUG_NON_DETERMINISTIC_ASSERT @@ -131,7 +132,7 @@ public: virtual void readRegion(SkRegion* region); virtual void readPath(SkPath* path); - void readPaint(SkPaint* paint) { paint->unflatten(*this); } + virtual void readPaint(SkPaint* paint) { paint->unflatten(*this); } virtual SkFlattenable* readFlattenable(SkFlattenable::Type); template <typename T> sk_sp<T> readFlattenable() { @@ -210,6 +211,11 @@ public: return this->validate(index >= 0 && index < count); } + SkInflator* getInflator() const { return fInflator; } + void setInflator(SkInflator* inf) { fInflator = inf; } + +// sk_sp<SkImage> inflateImage(); + protected: /** * Allows subclass to check if we are using factories for expansion @@ -256,6 +262,8 @@ private: // have decoded. int fDecodedBitmapIndex; #endif // DEBUG_NON_DETERMINISTIC_ASSERT + + SkInflator* fInflator = nullptr; }; #endif // SkReadBuffer_DEFINED diff --git a/src/core/SkWriteBuffer.cpp b/src/core/SkWriteBuffer.cpp index 33ac03b49d..1159ef3383 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); + } } } |