diff options
-rw-r--r-- | include/core/SkFlattenable.h | 17 | ||||
-rw-r--r-- | include/core/SkPicture.h | 4 | ||||
-rw-r--r-- | src/core/SkFlattenable.cpp | 10 | ||||
-rw-r--r-- | src/core/SkOrderedReadBuffer.cpp | 2 | ||||
-rw-r--r-- | src/core/SkOrderedWriteBuffer.cpp | 6 | ||||
-rw-r--r-- | src/core/SkPicture.cpp | 3 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 26 | ||||
-rw-r--r-- | src/core/SkXfermode.cpp | 12 |
8 files changed, 66 insertions, 14 deletions
diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h index e6c56a330e..1828b42a45 100644 --- a/include/core/SkFlattenable.h +++ b/include/core/SkFlattenable.h @@ -127,9 +127,21 @@ class SkTypeface; class SkFlattenableReadBuffer { public: + enum Flags { + kCrossProcess_Flag = 1 << 0, + kScalarIsFloat_Flag = 1 << 1, + kPtrIs64Bit_Flag = 1 << 2, + }; + SkFlattenableReadBuffer(); virtual ~SkFlattenableReadBuffer() {} + void setFlags(uint32_t flags) { fFlags = flags; } + uint32_t getFlags() const { return fFlags; } + + bool isCrossProcess() const { return SkToBool(fFlags & kCrossProcess_Flag); } + bool isScalarFloat() const { return SkToBool(fFlags & kScalarIsFloat_Flag); } + bool isPtr64Bit() const { return SkToBool(fFlags & kPtrIs64Bit_Flag); } virtual uint8_t readU8() = 0; virtual uint16_t readU16() = 0; @@ -192,7 +204,7 @@ public: virtual SkRefCnt* readRefCnt() = 0; virtual void* readFunctionPtr() = 0; virtual SkFlattenable* readFlattenable() = 0; - + protected: SkRefCnt** fRCArray; int fRCCount; @@ -203,6 +215,9 @@ protected: SkTDArray<SkFlattenable::Factory>* fFactoryTDArray; SkFlattenable::Factory* fFactoryArray; int fFactoryCount; + +private: + uint32_t fFlags; }; /////////////////////////////////////////////////////////////////////////////// diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h index 51ed0d71ac..976c594cad 100644 --- a/include/core/SkPicture.h +++ b/include/core/SkPicture.h @@ -37,6 +37,10 @@ public: this call, those elements will not appear in this picture. */ SkPicture(const SkPicture& src); + /** + * Recreate a picture that was serialized into a stream. If an error occurs + * the picture will be "empty" : width and height == 0 + */ explicit SkPicture(SkStream*); virtual ~SkPicture(); diff --git a/src/core/SkFlattenable.cpp b/src/core/SkFlattenable.cpp index 0232f75292..920c4fd101 100644 --- a/src/core/SkFlattenable.cpp +++ b/src/core/SkFlattenable.cpp @@ -32,6 +32,16 @@ SkFlattenableReadBuffer::SkFlattenableReadBuffer() { fFactoryTDArray = NULL; fFactoryArray = NULL; fFactoryCount = 0; + + // Set default values. These should be explicitly set by our client + // via setFlags() if the buffer came from serialization. + fFlags = 0; +#ifdef SK_SCALAR_IS_FLOAT + fFlags |= kScalarIsFloat_Flag; +#endif + if (8 == sizeof(void*)) { + fFlags |= kPtrIs64Bit_Flag; + } } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkOrderedReadBuffer.cpp b/src/core/SkOrderedReadBuffer.cpp index 62404a1d48..f3ba4850b3 100644 --- a/src/core/SkOrderedReadBuffer.cpp +++ b/src/core/SkOrderedReadBuffer.cpp @@ -99,6 +99,8 @@ SkFlattenable* SkOrderedReadBuffer::readFlattenable() { } void* SkOrderedReadBuffer::readFunctionPtr() { + SkASSERT(!this->isCrossProcess()); + void* proc; fReader.read(&proc, sizeof(proc)); return proc; diff --git a/src/core/SkOrderedWriteBuffer.cpp b/src/core/SkOrderedWriteBuffer.cpp index 3fa9706023..9c4303347a 100644 --- a/src/core/SkOrderedWriteBuffer.cpp +++ b/src/core/SkOrderedWriteBuffer.cpp @@ -95,11 +95,7 @@ void SkOrderedWriteBuffer::writeFlattenable(SkFlattenable* flattenable) { } void SkOrderedWriteBuffer::writeFunctionPtr(void* proc) { -// enable this to catch writers who's function-ptrs will break if the -// serialized buffer is read-back in a diff process -#if 0 - SkASSERT(!proc || !this->isCrossProcess()); -#endif + SkASSERT(!this->isCrossProcess()); *(void**)this->reserve(sizeof(void*)) = proc; } diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp index bcc2236143..350784577a 100644 --- a/src/core/SkPicture.cpp +++ b/src/core/SkPicture.cpp @@ -202,7 +202,8 @@ void SkPicture::draw(SkCanvas* surface) { // V2 : adds SkPixelRef's generation ID. // V3 : PictInfo tag at beginning, and EOF tag at the end // V4 : move SkPictInfo to be the header -#define PICTURE_VERSION 4 +// V5 : don't read/write FunctionPtr on cross-process (we can detect that) +#define PICTURE_VERSION 5 SkPicture::SkPicture(SkStream* stream) : SkRefCnt() { fRecord = NULL; diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index 2e88d35f18..d3c77af2d1 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -337,6 +337,7 @@ void SkPicturePlayback::serialize(SkWStream* stream) const { buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag); buffer.setTypefaceRecorder(&typefaceSet); buffer.setFactoryRecorder(&factSet); + this->flattenToBuffer(buffer); // We have to write these to sets into the stream *before* we write @@ -354,6 +355,29 @@ void SkPicturePlayback::serialize(SkWStream* stream) const { /////////////////////////////////////////////////////////////////////////////// +/** + * Return the corresponding SkFlattenableReadBuffer flags, given a set of + * SkPictInfo flags. + */ +static uint32_t pictInfoFlagsToReadBufferFlags(uint32_t pictInfoFlags) { + static const struct { + uint32_t fSrc; + uint32_t fDst; + } gSD[] = { + { SkPictInfo::kCrossProcess_Flag, SkFlattenableReadBuffer::kCrossProcess_Flag }, + { SkPictInfo::kScalarIsFloat_Flag, SkFlattenableReadBuffer::kScalarIsFloat_Flag }, + { SkPictInfo::kPtrIs64Bit_Flag, SkFlattenableReadBuffer::kPtrIs64Bit_Flag }, + }; + + uint32_t rbMask = 0; + for (size_t i = 0; i < SK_ARRAY_COUNT(gSD); ++i) { + if (pictInfoFlags & gSD[i].fSrc) { + rbMask |= gSD[i].fDst; + } + } + return rbMask; +} + bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, uint32_t tag, size_t size) { /* @@ -403,6 +427,8 @@ bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, stream->read(storage.get(), size); SkOrderedReadBuffer buffer(storage.get(), size); + buffer.setFlags(pictInfoFlagsToReadBufferFlags(info.fFlags)); + fFactoryPlayback->setupBuffer(buffer); fTFPlayback.setupBuffer(buffer); diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 62e62a17c1..bb9dc79326 100644 --- a/src/core/SkXfermode.cpp +++ b/src/core/SkXfermode.cpp @@ -681,17 +681,15 @@ void SkProcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, SkProcXfermode::SkProcXfermode(SkFlattenableReadBuffer& buffer) : SkXfermode(buffer) { - // Might be a NULL if the Xfermode is recorded using the CrossProcess flag - fProc = (SkXfermodeProc)buffer.readFunctionPtr(); + fProc = NULL; + if (!buffer.isCrossProcess()) { + fProc = (SkXfermodeProc)buffer.readFunctionPtr(); + } } void SkProcXfermode::flatten(SkFlattenableWriteBuffer& buffer) const { this->INHERITED::flatten(buffer); - if (buffer.isCrossProcess()) { - // function pointer is only valid in the current process. Write a NULL - // so it can't be accidentally used - buffer.writeFunctionPtr(NULL); - } else { + if (!buffer.isCrossProcess()) { buffer.writeFunctionPtr((void*)fProc); } } |