From 3ac64b427af596e4e8341857ce5f214bf0b49efb Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Tue, 18 Oct 2016 19:34:08 -0400 Subject: [PATCH] image serialize/deserialize callbacks in pipe BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3607 Change-Id: I403fec72cacfc6a821f676f0afef390c89749a8b Reviewed-on: https://skia-review.googlesource.com/3607 Commit-Queue: Mike Reed Commit-Queue: Mike Klein Reviewed-by: Mike Klein --- src/core/SkPipe.h | 19 +++++++++++++++++++ src/pipe/SkPipeCanvas.cpp | 20 +++++++++++++++----- src/pipe/SkPipeCanvas.h | 2 ++ src/pipe/SkPipeReader.cpp | 30 +++++++++++++++++++++++------- 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/core/SkPipe.h b/src/core/SkPipe.h index 04c3ae2dca..739b9bc585 100644 --- a/src/core/SkPipe.h +++ b/src/core/SkPipe.h @@ -15,6 +15,8 @@ class SkImage; class SkPicture; class SkTypefaceSerializer; class SkTypefaceDeserializer; +class SkImageSerializer; +class SkImageDeserializer; class SkWStream; class SkPipeSerializer { @@ -24,6 +26,7 @@ public: // Ownership is not transferred, so caller must ceep the serializer alive void setTypefaceSerializer(SkTypefaceSerializer*); + void setImageSerializer(SkImageSerializer*); void resetCache(); @@ -48,6 +51,7 @@ public: // Ownership is not transferred, so caller must ceep the deserializer alive void setTypefaceDeserializer(SkTypefaceDeserializer*); + void setImageDeserializer(SkImageDeserializer*); sk_sp readImage(const SkData* data) { if (!data) { @@ -82,6 +86,14 @@ public: virtual sk_sp serialize(SkTypeface*) = 0; }; +class SkImageSerializer { +public: + virtual ~SkImageSerializer() {} + + virtual sk_sp serialize(SkImage*) = 0; +}; + + class SkTypefaceDeserializer { public: virtual ~SkTypefaceDeserializer() {} @@ -89,4 +101,11 @@ public: virtual sk_sp deserialize(const void* data, size_t size) = 0; }; +class SkImageDeserializer { +public: + virtual ~SkImageDeserializer() {} + + virtual sk_sp deserialize(const void*, size_t) = 0; +}; + #endif diff --git a/src/pipe/SkPipeCanvas.cpp b/src/pipe/SkPipeCanvas.cpp index 3b636a23c0..3e05989c30 100644 --- a/src/pipe/SkPipeCanvas.cpp +++ b/src/pipe/SkPipeCanvas.cpp @@ -862,6 +862,15 @@ protected: } }; +static sk_sp default_image_serializer(SkImage* image) { + A8Serializer serial; + sk_sp data(image->encode(&serial)); + if (!data) { + data.reset(image->encode()); + } + return data; +} + static bool show_deduper_traffic = false; int SkPipeDeduper::findOrDefineImage(SkImage* image) { @@ -874,11 +883,8 @@ int SkPipeDeduper::findOrDefineImage(SkImage* image) { return index; } - A8Serializer serial; - sk_sp data(image->encode(&serial)); - if (!data) { - data.reset(image->encode()); - } + sk_sp data = fIMSerializer ? fIMSerializer->serialize(image) + : default_image_serializer(image); if (data) { index = fImages.add(image->uniqueID()); SkASSERT(index > 0); @@ -1017,6 +1023,10 @@ void SkPipeSerializer::setTypefaceSerializer(SkTypefaceSerializer* tfs) { fImpl->fDeduper.setTypefaceSerializer(tfs); } +void SkPipeSerializer::setImageSerializer(SkImageSerializer* ims) { + fImpl->fDeduper.setImageSerializer(ims); +} + void SkPipeSerializer::resetCache() { fImpl->fDeduper.resetCaches(); } diff --git a/src/pipe/SkPipeCanvas.h b/src/pipe/SkPipeCanvas.h index 50d76edfd2..33f7821d51 100644 --- a/src/pipe/SkPipeCanvas.h +++ b/src/pipe/SkPipeCanvas.h @@ -63,6 +63,7 @@ public: void setCanvas(SkPipeCanvas* canvas) { fPipeCanvas = canvas; } void setStream(SkWStream* stream) { fStream = stream; } void setTypefaceSerializer(SkTypefaceSerializer* tfs) { fTFSerializer = tfs; } + void setImageSerializer(SkImageSerializer* ims) { fIMSerializer = ims; } // returns 0 if not found int findImage(SkImage* image) const { return fImages.find(image->uniqueID()); } @@ -78,6 +79,7 @@ private: SkWStream* fStream = nullptr; SkTypefaceSerializer* fTFSerializer = nullptr; + SkImageSerializer* fIMSerializer = nullptr; // All our keys (at the moment) are 32bit uniqueIDs SkTIndexSet fImages; diff --git a/src/pipe/SkPipeReader.cpp b/src/pipe/SkPipeReader.cpp index 47d4072d06..8fa539e64d 100644 --- a/src/pipe/SkPipeReader.cpp +++ b/src/pipe/SkPipeReader.cpp @@ -27,12 +27,13 @@ class SkPipeInflator : public SkInflator { public: SkPipeInflator(SkRefSet* images, SkRefSet* pictures, SkRefSet* typefaces, SkTDArray* factories, - SkTypefaceDeserializer* tfd) + SkTypefaceDeserializer* tfd, SkImageDeserializer* imd) : fImages(images) , fPictures(pictures) , fTypefaces(typefaces) , fFactories(factories) , fTFDeserializer(tfd) + , fIMDeserializer(imd) {} SkImage* getImage(int index) override { @@ -76,8 +77,13 @@ public: void setTypefaceDeserializer(SkTypefaceDeserializer* tfd) { fTFDeserializer = tfd; } - + + void setImageDeserializer(SkImageDeserializer* imd) { + fIMDeserializer = imd; + } + sk_sp makeTypeface(const void* data, size_t size); + sk_sp makeImage(const sk_sp&); private: SkRefSet* fImages; @@ -86,6 +92,7 @@ private: SkTDArray* fFactories; SkTypefaceDeserializer* fTFDeserializer; + SkImageDeserializer* fIMDeserializer; }; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -677,7 +684,10 @@ static sk_sp make_from_skiaimageformat(const void* encoded, size_t enco return SkImage::MakeRasterData(info, pixels, width); } -static sk_sp make_from_encoded(const sk_sp& data) { +sk_sp SkPipeInflator::makeImage(const sk_sp& data) { + if (fIMDeserializer) { + return fIMDeserializer->deserialize(data->data(), data->size()); + } sk_sp image = make_from_skiaimageformat(data->data(), data->size()); if (!image) { image = SkImage::MakeFromEncoded(data); @@ -685,6 +695,7 @@ static sk_sp make_from_encoded(const sk_sp& data) { return image; } + static void defineImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas*) { SkASSERT(SkPipeVerb::kDefineImage == unpack_verb(packedVerb)); SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator(); @@ -697,7 +708,7 @@ static void defineImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCan } else { // we are defining a new image sk_sp data = reader.readByteArrayAsData(); - sk_sp image = make_from_encoded(data); + sk_sp image = inflator->makeImage(data); if (!image) { SkDebugf("-- failed to decode\n"); } @@ -833,6 +844,7 @@ public: SkTDArray fFactories; SkTypefaceDeserializer* fTFDeserializer = nullptr; + SkImageDeserializer* fIMDeserializer = nullptr; }; SkPipeDeserializer::SkPipeDeserializer() : fImpl(new Impl) {} @@ -842,6 +854,10 @@ void SkPipeDeserializer::setTypefaceDeserializer(SkTypefaceDeserializer* tfd) { fImpl->fTFDeserializer = tfd; } +void SkPipeDeserializer::setImageDeserializer(SkImageDeserializer* imd) { + fImpl->fIMDeserializer = imd; +} + sk_sp SkPipeDeserializer::readImage(const void* data, size_t size) { if (size < sizeof(uint32_t)) { SkDebugf("-------- data length too short for readImage %d\n", size); @@ -855,7 +871,7 @@ sk_sp SkPipeDeserializer::readImage(const void* data, size_t size) { if (SkPipeVerb::kDefineImage == unpack_verb(packedVerb)) { SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures, &fImpl->fTypefaces, &fImpl->fFactories, - fImpl->fTFDeserializer); + fImpl->fTFDeserializer, fImpl->fIMDeserializer); SkPipeReader reader(this, ptr, size); reader.setInflator(&inflator); defineImage_handler(reader, packedVerb, nullptr); @@ -885,7 +901,7 @@ sk_sp SkPipeDeserializer::readPicture(const void* data, size_t size) if (SkPipeVerb::kDefinePicture == unpack_verb(packedVerb)) { SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures, &fImpl->fTypefaces, &fImpl->fFactories, - fImpl->fTFDeserializer); + fImpl->fTFDeserializer, fImpl->fIMDeserializer); SkPipeReader reader(this, ptr, size); reader.setInflator(&inflator); definePicture_handler(reader, packedVerb, nullptr); @@ -954,7 +970,7 @@ static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureI bool SkPipeDeserializer::playback(const void* data, size_t size, SkCanvas* canvas) { SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures, &fImpl->fTypefaces, &fImpl->fFactories, - fImpl->fTFDeserializer); + fImpl->fTFDeserializer, fImpl->fIMDeserializer); SkPipeReader reader(this, data, size); reader.setInflator(&inflator); return do_playback(reader, canvas);