Thread picture version through to SkReadBuffer.

This will let code outside SkPicture* fork its read code based on the picture version.

BUG=skia:
R=reed@google.com, robertphillips@google.com, mtklein@google.com

Author: mtklein@chromium.org

Review URL: https://codereview.chromium.org/214413008

git-svn-id: http://skia.googlecode.com/svn/trunk@13984 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
commit-bot@chromium.org 2014-03-28 18:05:47 +00:00
parent d643a90ee2
commit 0943f5f58a
6 changed files with 67 additions and 45 deletions

View File

@ -164,15 +164,15 @@ public:
const SkTDArray<bool>& deletedCommands) { const SkTDArray<bool>& deletedCommands) {
// Mimics SkPicturePlayback::CreateFromStream // Mimics SkPicturePlayback::CreateFromStream
SkAutoTDelete<SkTimedPicturePlayback> playback(SkNEW_ARGS(SkTimedPicturePlayback, SkAutoTDelete<SkTimedPicturePlayback> playback(SkNEW_ARGS(SkTimedPicturePlayback,
(deletedCommands))); (deletedCommands, info)));
if (!playback->parseStream(stream, info, proc)) { if (!playback->parseStream(stream, proc)) {
return NULL; // we're invalid return NULL; // we're invalid
} }
return playback.detach(); return playback.detach();
} }
SkTimedPicturePlayback(const SkTDArray<bool>& deletedCommands) SkTimedPicturePlayback(const SkTDArray<bool>& deletedCommands, const SkPictInfo& info)
: INHERITED() : INHERITED(info)
, fSkipCommands(deletedCommands) , fSkipCommands(deletedCommands)
, fTot(0.0) , fTot(0.0)
, fCurCommand(0) { , fCurCommand(0) {
@ -254,14 +254,6 @@ protected:
#endif #endif
private: private:
// SkPicturePlayback::parseStream is protected, so it can be
// called here, but not by our static factory function. This
// allows the factory function to call it.
bool parseStream(SkStream* stream, const SkPictInfo& info,
SkPicture::InstallPixelRefProc proc) {
return this->INHERITED::parseStream(stream, info, proc);
}
typedef SkPicturePlayback INHERITED; typedef SkPicturePlayback INHERITED;
}; };

View File

@ -41,6 +41,15 @@ public:
SkReadBuffer(SkStream* stream); SkReadBuffer(SkStream* stream);
virtual ~SkReadBuffer(); virtual ~SkReadBuffer();
/** Return the version of the serialized picture this buffer holds, or 0 if unset. */
int pictureVersion() const { return fPictureVersion; }
/** This may be called at most once; most clients of SkReadBuffer should not mess with it. */
void setPictureVersion(int version) {
SkASSERT(0 == fPictureVersion);
fPictureVersion = version;
}
enum Flags { enum Flags {
kCrossProcess_Flag = 1 << 0, kCrossProcess_Flag = 1 << 0,
kScalarIsFloat_Flag = 1 << 1, kScalarIsFloat_Flag = 1 << 1,
@ -184,6 +193,7 @@ private:
bool readArray(void* value, size_t size, size_t elementSize); bool readArray(void* value, size_t size, size_t elementSize);
uint32_t fFlags; uint32_t fFlags;
int fPictureVersion;
void* fMemoryPtr; void* fMemoryPtr;

View File

@ -138,8 +138,10 @@ SkPicture::SkPicture(const SkPicture& src)
if (src.fPlayback) { if (src.fPlayback) {
fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fPlayback)); fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fPlayback));
} else if (src.fRecord) { } else if (src.fRecord) {
SkPictInfo info;
this->createHeader(&info);
// here we do a fake src.endRecording() // here we do a fake src.endRecording()
fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fRecord)); fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fRecord, info));
} else { } else {
fPlayback = NULL; fPlayback = NULL;
} }
@ -173,6 +175,8 @@ SkPicture* SkPicture::clone() const {
void SkPicture::clone(SkPicture* pictures, int count) const { void SkPicture::clone(SkPicture* pictures, int count) const {
SkPictCopyInfo copyInfo; SkPictCopyInfo copyInfo;
SkPictInfo info;
this->createHeader(&info);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
SkPicture* clone = &pictures[i]; SkPicture* clone = &pictures[i];
@ -190,7 +194,7 @@ void SkPicture::clone(SkPicture* pictures, int count) const {
clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fPlayback, &copyInfo)); clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fPlayback, &copyInfo));
} else if (fRecord) { } else if (fRecord) {
// here we do a fake src.endRecording() // here we do a fake src.endRecording()
clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, true)); clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info, true));
} else { } else {
clone->fPlayback = NULL; clone->fPlayback = NULL;
} }
@ -261,7 +265,9 @@ void SkPicture::endRecording() {
if (NULL == fPlayback) { if (NULL == fPlayback) {
if (NULL != fRecord) { if (NULL != fRecord) {
fRecord->endRecording(); fRecord->endRecording();
fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord)); SkPictInfo info;
this->createHeader(&info);
fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info));
SkSafeSetNull(fRecord); SkSafeSetNull(fRecord);
} }
} }
@ -384,7 +390,7 @@ SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) {
SkPicturePlayback* playback; SkPicturePlayback* playback;
// Check to see if there is a playback to recreate. // Check to see if there is a playback to recreate.
if (buffer.readBool()) { if (buffer.readBool()) {
playback = SkPicturePlayback::CreateFromBuffer(buffer); playback = SkPicturePlayback::CreateFromBuffer(buffer, info);
if (NULL == playback) { if (NULL == playback) {
return NULL; return NULL;
} }
@ -417,13 +423,13 @@ void SkPicture::createHeader(SkPictInfo* info) const {
void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const { void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
SkPicturePlayback* playback = fPlayback; SkPicturePlayback* playback = fPlayback;
SkPictInfo info;
this->createHeader(&info);
if (NULL == playback && fRecord) { if (NULL == playback && fRecord) {
playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord)); playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info));
} }
SkPictInfo header; stream->write(&info, sizeof(info));
this->createHeader(&header);
stream->write(&header, sizeof(header));
if (playback) { if (playback) {
stream->writeBool(true); stream->writeBool(true);
playback->serialize(stream, encoder); playback->serialize(stream, encoder);
@ -439,13 +445,13 @@ void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
void SkPicture::flatten(SkWriteBuffer& buffer) const { void SkPicture::flatten(SkWriteBuffer& buffer) const {
SkPicturePlayback* playback = fPlayback; SkPicturePlayback* playback = fPlayback;
SkPictInfo info;
this->createHeader(&info);
if (NULL == playback && fRecord) { if (NULL == playback && fRecord) {
playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord)); playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info));
} }
SkPictInfo header; buffer.writeByteArray(&info, sizeof(info));
this->createHeader(&header);
buffer.writeByteArray(&header, sizeof(header));
if (playback) { if (playback) {
buffer.writeBool(true); buffer.writeBool(true);
playback->flatten(buffer); playback->flatten(buffer);

View File

@ -24,11 +24,14 @@ template <typename T> int SafeCount(const T* obj) {
*/ */
#define SPEW_CLIP_SKIPPINGx #define SPEW_CLIP_SKIPPINGx
SkPicturePlayback::SkPicturePlayback() { SkPicturePlayback::SkPicturePlayback(const SkPictInfo& info) : fInfo(info) {
this->init(); this->init();
} }
SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record, bool deepCopy) { SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record,
const SkPictInfo& info,
bool deepCopy)
: fInfo(info) {
#ifdef SK_DEBUG_SIZE #ifdef SK_DEBUG_SIZE
size_t overallBytes, bitmapBytes, matricesBytes, size_t overallBytes, bitmapBytes, matricesBytes,
paintBytes, pathBytes, pictureBytes, regionBytes; paintBytes, pathBytes, pictureBytes, regionBytes;
@ -158,7 +161,8 @@ static bool needs_deep_copy(const SkPaint& paint) {
paint.getImageFilter(); paint.getImageFilter();
} }
SkPicturePlayback::SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo) { SkPicturePlayback::SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo)
: fInfo(src.fInfo) {
this->init(); this->init();
fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get())); fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get()));
@ -479,8 +483,10 @@ static uint32_t pictInfoFlagsToReadBufferFlags(uint32_t pictInfoFlags) {
return rbMask; return rbMask;
} }
bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, uint32_t tag, bool SkPicturePlayback::parseStreamTag(SkStream* stream,
size_t size, SkPicture::InstallPixelRefProc proc) { uint32_t tag,
size_t size,
SkPicture::InstallPixelRefProc proc) {
/* /*
* By the time we encounter BUFFER_SIZE_TAG, we need to have already seen * By the time we encounter BUFFER_SIZE_TAG, we need to have already seen
* its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required * its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required
@ -506,7 +512,7 @@ bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info,
// Remove this code when v21 and below are no longer supported. At the // Remove this code when v21 and below are no longer supported. At the
// same time add a new 'count' variable and use it rather then reusing 'size'. // same time add a new 'count' variable and use it rather then reusing 'size'.
#ifndef DISABLE_V21_COMPATIBILITY_CODE #ifndef DISABLE_V21_COMPATIBILITY_CODE
if (info.fVersion >= 22) { if (fInfo.fVersion >= 22) {
// in v22 this tag's size represents the size of the chunk in bytes // in v22 this tag's size represents the size of the chunk in bytes
// and the number of factory strings is written out separately // and the number of factory strings is written out separately
#endif #endif
@ -568,7 +574,8 @@ bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info,
} }
SkReadBuffer buffer(storage.get(), size); SkReadBuffer buffer(storage.get(), size);
buffer.setFlags(pictInfoFlagsToReadBufferFlags(info.fFlags)); buffer.setFlags(pictInfoFlagsToReadBufferFlags(fInfo.fFlags));
buffer.setPictureVersion(fInfo.fVersion);
fFactoryPlayback->setupBuffer(buffer); fFactoryPlayback->setupBuffer(buffer);
fTFPlayback.setupBuffer(buffer); fTFPlayback.setupBuffer(buffer);
@ -654,16 +661,18 @@ bool SkPicturePlayback::parseBufferTag(SkReadBuffer& buffer,
SkPicturePlayback* SkPicturePlayback::CreateFromStream(SkStream* stream, SkPicturePlayback* SkPicturePlayback::CreateFromStream(SkStream* stream,
const SkPictInfo& info, const SkPictInfo& info,
SkPicture::InstallPixelRefProc proc) { SkPicture::InstallPixelRefProc proc) {
SkAutoTDelete<SkPicturePlayback> playback(SkNEW(SkPicturePlayback)); SkAutoTDelete<SkPicturePlayback> playback(SkNEW_ARGS(SkPicturePlayback, (info)));
if (!playback->parseStream(stream, info, proc)) { if (!playback->parseStream(stream, proc)) {
return NULL; return NULL;
} }
return playback.detach(); return playback.detach();
} }
SkPicturePlayback* SkPicturePlayback::CreateFromBuffer(SkReadBuffer& buffer) { SkPicturePlayback* SkPicturePlayback::CreateFromBuffer(SkReadBuffer& buffer,
SkAutoTDelete<SkPicturePlayback> playback(SkNEW(SkPicturePlayback)); const SkPictInfo& info) {
SkAutoTDelete<SkPicturePlayback> playback(SkNEW_ARGS(SkPicturePlayback, (info)));
buffer.setPictureVersion(info.fVersion);
if (!playback->parseBuffer(buffer)) { if (!playback->parseBuffer(buffer)) {
return NULL; return NULL;
@ -671,7 +680,7 @@ SkPicturePlayback* SkPicturePlayback::CreateFromBuffer(SkReadBuffer& buffer) {
return playback.detach(); return playback.detach();
} }
bool SkPicturePlayback::parseStream(SkStream* stream, const SkPictInfo& info, bool SkPicturePlayback::parseStream(SkStream* stream,
SkPicture::InstallPixelRefProc proc) { SkPicture::InstallPixelRefProc proc) {
for (;;) { for (;;) {
uint32_t tag = stream->readU32(); uint32_t tag = stream->readU32();
@ -680,7 +689,7 @@ bool SkPicturePlayback::parseStream(SkStream* stream, const SkPictInfo& info,
} }
uint32_t size = stream->readU32(); uint32_t size = stream->readU32();
if (!this->parseStreamTag(stream, info, tag, size, proc)) { if (!this->parseStreamTag(stream, tag, size, proc)) {
return false; // we're invalid return false; // we're invalid
} }
} }

View File

@ -76,12 +76,12 @@ struct SkPictCopyInfo {
class SkPicturePlayback { class SkPicturePlayback {
public: public:
SkPicturePlayback();
SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo = NULL); SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo = NULL);
explicit SkPicturePlayback(const SkPictureRecord& record, bool deepCopy = false); SkPicturePlayback(const SkPictureRecord& record, const SkPictInfo&, bool deepCopy = false);
static SkPicturePlayback* CreateFromStream(SkStream*, const SkPictInfo&, static SkPicturePlayback* CreateFromStream(SkStream*,
const SkPictInfo&,
SkPicture::InstallPixelRefProc); SkPicture::InstallPixelRefProc);
static SkPicturePlayback* CreateFromBuffer(SkReadBuffer&); static SkPicturePlayback* CreateFromBuffer(SkReadBuffer&, const SkPictInfo&);
virtual ~SkPicturePlayback(); virtual ~SkPicturePlayback();
@ -106,8 +106,9 @@ public:
void resetOpID() { fCurOffset = 0; } void resetOpID() { fCurOffset = 0; }
protected: protected:
bool parseStream(SkStream*, const SkPictInfo&, explicit SkPicturePlayback(const SkPictInfo& info);
SkPicture::InstallPixelRefProc);
bool parseStream(SkStream*, SkPicture::InstallPixelRefProc);
bool parseBuffer(SkReadBuffer& buffer); bool parseBuffer(SkReadBuffer& buffer);
#ifdef SK_DEVELOPER #ifdef SK_DEVELOPER
virtual bool preDraw(int opIndex, int type); virtual bool preDraw(int opIndex, int type);
@ -217,8 +218,7 @@ public:
#endif #endif
private: // these help us with reading/writing private: // these help us with reading/writing
bool parseStreamTag(SkStream*, const SkPictInfo&, uint32_t tag, size_t size, bool parseStreamTag(SkStream*, uint32_t tag, size_t size, SkPicture::InstallPixelRefProc);
SkPicture::InstallPixelRefProc);
bool parseBufferTag(SkReadBuffer&, uint32_t tag, size_t size); bool parseBufferTag(SkReadBuffer&, uint32_t tag, size_t size);
void flattenToBuffer(SkWriteBuffer&) const; void flattenToBuffer(SkWriteBuffer&) const;
@ -271,6 +271,8 @@ private:
// The offset of the current operation when within the draw method // The offset of the current operation when within the draw method
size_t fCurOffset; size_t fCurOffset;
const SkPictInfo fInfo;
#ifdef SK_BUILD_FOR_ANDROID #ifdef SK_BUILD_FOR_ANDROID
SkMutex fDrawMutex; SkMutex fDrawMutex;
bool fAbortCurrentPlayback; bool fAbortCurrentPlayback;

View File

@ -25,6 +25,7 @@ static uint32_t default_flags() {
SkReadBuffer::SkReadBuffer() { SkReadBuffer::SkReadBuffer() {
fFlags = default_flags(); fFlags = default_flags();
fPictureVersion = 0;
fMemoryPtr = NULL; fMemoryPtr = NULL;
fBitmapStorage = NULL; fBitmapStorage = NULL;
@ -42,6 +43,7 @@ SkReadBuffer::SkReadBuffer() {
SkReadBuffer::SkReadBuffer(const void* data, size_t size) { SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
fFlags = default_flags(); fFlags = default_flags();
fPictureVersion = 0;
fReader.setMemory(data, size); fReader.setMemory(data, size);
fMemoryPtr = NULL; fMemoryPtr = NULL;
@ -60,6 +62,7 @@ SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
SkReadBuffer::SkReadBuffer(SkStream* stream) { SkReadBuffer::SkReadBuffer(SkStream* stream) {
fFlags = default_flags(); fFlags = default_flags();
fPictureVersion = 0;
const size_t length = stream->getLength(); const size_t length = stream->getLength();
fMemoryPtr = sk_malloc_throw(length); fMemoryPtr = sk_malloc_throw(length);
stream->read(fMemoryPtr, length); stream->read(fMemoryPtr, length);