зеркало из https://github.com/mozilla/moz-skia.git
export flags on the state of the world when a picture was serialized.
e.g. don't read/write functionptrs in that case (sizeof may be different for one) Review URL: https://codereview.appspot.com/6331050 git-svn-id: http://skia.googlecode.com/svn/trunk@4318 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
ec95a4ae45
Коммит
34342f6f51
|
@ -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;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -99,6 +99,8 @@ SkFlattenable* SkOrderedReadBuffer::readFlattenable() {
|
|||
}
|
||||
|
||||
void* SkOrderedReadBuffer::readFunctionPtr() {
|
||||
SkASSERT(!this->isCrossProcess());
|
||||
|
||||
void* proc;
|
||||
fReader.read(&proc, sizeof(proc));
|
||||
return proc;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче