Allow supporting 1 older PICTURE_VERSION.

Allows https://codereview.chromium.org/14230022/ to be submitted
without breaking bench_pictures and render_pictures.

After DEPS roll and SKP capture, this will be reverted.

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

git-svn-id: http://skia.googlecode.com/svn/trunk@8918 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
scroggo@google.com 2013-04-30 02:37:56 +00:00
parent 74b7ffda68
commit 0cb7df9718
5 changed files with 86 additions and 39 deletions

View File

@ -192,7 +192,6 @@ public:
void abortPlayback();
#endif
protected:
// V2 : adds SkPixelRef's generation ID.
// V3 : PictInfo tag at beginning, and EOF tag at the end
// V4 : move SkPictInfo to be the header
@ -206,6 +205,7 @@ protected:
// V11: modify how readBitmap and writeBitmap store their info.
static const uint32_t PICTURE_VERSION = 11;
protected:
// fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
// install their own SkPicturePlayback-derived players,SkPictureRecord-derived
// recorders and set the picture size

View File

@ -23,6 +23,7 @@ SkOrderedReadBuffer::SkOrderedReadBuffer() : INHERITED() {
fFactoryArray = NULL;
fFactoryCount = 0;
fBitmapDecoder = NULL;
fPictureVersion = SkPicture::PICTURE_VERSION;
}
SkOrderedReadBuffer::SkOrderedReadBuffer(const void* data, size_t size) : INHERITED() {
@ -37,6 +38,7 @@ SkOrderedReadBuffer::SkOrderedReadBuffer(const void* data, size_t size) : INHERI
fFactoryArray = NULL;
fFactoryCount = 0;
fBitmapDecoder = NULL;
fPictureVersion = SkPicture::PICTURE_VERSION;
}
SkOrderedReadBuffer::SkOrderedReadBuffer(SkStream* stream) {
@ -53,6 +55,7 @@ SkOrderedReadBuffer::SkOrderedReadBuffer(SkStream* stream) {
fFactoryArray = NULL;
fFactoryCount = 0;
fBitmapDecoder = NULL;
fPictureVersion = SkPicture::PICTURE_VERSION;
}
SkOrderedReadBuffer::~SkOrderedReadBuffer() {
@ -168,52 +171,88 @@ uint32_t SkOrderedReadBuffer::getArrayCount() {
return *(uint32_t*)fReader.peek();
}
void SkOrderedReadBuffer::setPictureVersion(uint32_t version) {
SkASSERT(version <= SkPicture::PICTURE_VERSION);
fPictureVersion = version;
}
void SkOrderedReadBuffer::readBitmap(SkBitmap* bitmap) {
const int width = this->readInt();
const int height = this->readInt();
// The writer stored a boolean value to determine whether an SkBitmapHeap was used during
// writing.
if (this->readBool()) {
// An SkBitmapHeap was used for writing. Read the index from the stream and find the
// corresponding SkBitmap in fBitmapStorage.
const uint32_t index = fReader.readU32();
fReader.readU32(); // bitmap generation ID (see SkOrderedWriteBuffer::writeBitmap)
if (fBitmapStorage) {
*bitmap = *fBitmapStorage->getBitmap(index);
fBitmapStorage->releaseRef(index);
return;
} else {
// The bitmap was stored in a heap, but there is no way to access it. Set an error and
// fall through to use a place holder bitmap.
SkErrorInternals::SetError(kParseError_SkError, "SkOrderedWriteBuffer::writeBitmap "
"stored the SkBitmap in an SkBitmapHeap, but "
"SkOrderedReadBuffer has no SkBitmapHeapReader to "
"retrieve the SkBitmap.");
}
} else {
// The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap.
if (10 == fPictureVersion) {
// Old code to read a bitmap in PICTURE_VERSION 10
const size_t length = this->readUInt();
if (length > 0) {
// A non-zero size means the SkBitmap was encoded.
// Bitmap was encoded.
const void* data = this->skip(length);
const int width = this->readInt();
const int height = this->readInt();
if (fBitmapDecoder != NULL && fBitmapDecoder(data, length, bitmap)) {
SkASSERT(bitmap->width() == width && bitmap->height() == height);
} else {
// This bitmap was encoded when written, but we are unable to decode, possibly due to
// not having a decoder. Use a placeholder bitmap.
SkErrorInternals::SetError(kParseError_SkError,
"Could not decode bitmap. Resulting bitmap will be red.");
bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height);
bitmap->allocPixels();
bitmap->eraseColor(SK_ColorRED);
}
} else {
if (fBitmapStorage) {
const uint32_t index = fReader.readU32();
fReader.readU32(); // bitmap generation ID (see SkOrderedWriteBuffer::writeBitmap)
*bitmap = *fBitmapStorage->getBitmap(index);
fBitmapStorage->releaseRef(index);
} else {
bitmap->unflatten(*this);
}
}
} else {
const int width = this->readInt();
const int height = this->readInt();
// The writer stored a boolean value to determine whether an SkBitmapHeap was used during
// writing.
if (this->readBool()) {
// An SkBitmapHeap was used for writing. Read the index from the stream and find the
// corresponding SkBitmap in fBitmapStorage.
const uint32_t index = fReader.readU32();
fReader.readU32(); // bitmap generation ID (see SkOrderedWriteBuffer::writeBitmap)
if (fBitmapStorage) {
*bitmap = *fBitmapStorage->getBitmap(index);
fBitmapStorage->releaseRef(index);
return;
} else {
// The bitmap was stored in a heap, but there is no way to access it. Set an error and
// fall through to use a place holder bitmap.
SkErrorInternals::SetError(kParseError_SkError, "SkOrderedWriteBuffer::writeBitmap "
"stored the SkBitmap in an SkBitmapHeap, but "
"SkOrderedReadBuffer has no SkBitmapHeapReader to "
"retrieve the SkBitmap.");
}
} else {
// The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap.
const size_t length = this->readUInt();
if (length > 0) {
// A non-zero size means the SkBitmap was encoded.
const void* data = this->skip(length);
if (fBitmapDecoder != NULL && fBitmapDecoder(data, length, bitmap)) {
SkASSERT(bitmap->width() == width && bitmap->height() == height);
return;
}
// This bitmap was encoded when written, but we are unable to decode, possibly due to
// not having a decoder.
SkErrorInternals::SetError(kParseError_SkError,
"Could not decode bitmap. Resulting bitmap will be red.");
} else {
// A size of zero means the SkBitmap was simply flattened.
bitmap->unflatten(*this);
return;
}
// This bitmap was encoded when written, but we are unable to decode, possibly due to
// not having a decoder.
SkErrorInternals::SetError(kParseError_SkError,
"Could not decode bitmap. Resulting bitmap will be red.");
} else {
// A size of zero means the SkBitmap was simply flattened.
bitmap->unflatten(*this);
return;
}
// Could not read the SkBitmap. Use a placeholder bitmap.
bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height);
bitmap->allocPixels();
bitmap->eraseColor(SK_ColorRED);
}
// Could not read the SkBitmap. Use a placeholder bitmap.
bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height);
bitmap->allocPixels();
bitmap->eraseColor(SK_ColorRED);
}
SkTypeface* SkOrderedReadBuffer::readTypeface() {

View File

@ -27,6 +27,8 @@ public:
virtual SkOrderedReadBuffer* getOrderedBinaryBuffer() SK_OVERRIDE { return this; }
void setPictureVersion(uint32_t version);
SkReader32* getReader32() { return &fReader; }
uint32_t size() { return fReader.size(); }
@ -121,6 +123,7 @@ private:
int fFactoryCount;
SkPicture::InstallPixelRefProc fBitmapDecoder;
uint32_t fPictureVersion;
typedef SkFlattenableReadBuffer INHERITED;
};

View File

@ -6,7 +6,7 @@
* found in the LICENSE file.
*/
#include "SkErrorInternals.h"
#include "SkPictureFlat.h"
#include "SkPicturePlayback.h"
#include "SkPictureRecord.h"
@ -283,9 +283,13 @@ void SkPicture::initFromStream(SkStream* stream, bool* success, InstallPixelRefP
SkPictInfo info;
if (!stream->read(&info, sizeof(info))) {
SkErrorInternals::SetError(kParseError_SkError, "Failed to parse skp info.");
return;
}
if (PICTURE_VERSION != info.fVersion) {
if (info.fVersion < 10 || info.fVersion > PICTURE_VERSION) {
SkErrorInternals::SetError(kParseError_SkError, "skp version %d not supported.",
info.fVersion);
return;
}

View File

@ -537,6 +537,7 @@ void SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info,
SkOrderedReadBuffer buffer(storage.get(), size);
buffer.setFlags(pictInfoFlagsToReadBufferFlags(info.fFlags));
buffer.setPictureVersion(info.fVersion);
fFactoryPlayback->setupBuffer(buffer);
fTFPlayback.setupBuffer(buffer);