aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2012-02-17 14:15:23 -0500
committerDerek Sollenberger <djsollen@google.com>2012-02-27 14:10:55 -0500
commit341c93bd153d8fcc55114b0148301e98e34bc13c (patch)
treea4d9d96bbe441b5198b3e08c94c12a6034762b33
parent43ccec49e8a1f058730cf41d68c6a5c1b9450579 (diff)
downloadexternal_skia-341c93bd153d8fcc55114b0148301e98e34bc13c.zip
external_skia-341c93bd153d8fcc55114b0148301e98e34bc13c.tar.gz
external_skia-341c93bd153d8fcc55114b0148301e98e34bc13c.tar.bz2
Changes to preserve backwards compatibility for serialization
Skia's serialize methods are not intended for backwards compatibility, but the browser used it to implement saved pages. As a result the revision of Skia used for ICS (r1562) is not compatible with the revision of Skia used in JB (r3000+). This CL attempts to make pages saved in ICS render in JB while still allowing JB pages to be saved and displayed. bug: 6025365 Change-Id: I9983517b46d2dedf31c6d90f48f6cf00ec042bc2
-rw-r--r--include/core/SkFlattenable.h5
-rw-r--r--include/core/SkUserConfig.h3
-rw-r--r--src/core/SkFlattenable.cpp40
-rw-r--r--src/core/SkPaint.cpp18
-rw-r--r--src/core/SkPicture.cpp8
-rw-r--r--src/core/SkPictureFlat.h5
-rw-r--r--src/core/SkPicturePlayback.cpp12
-rw-r--r--src/core/SkPicturePlayback.h2
-rw-r--r--src/core/SkXfermode.cpp6
-rw-r--r--src/effects/SkLayerDrawLooper.cpp2
10 files changed, 89 insertions, 12 deletions
diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h
index a66638e..34ca34e 100644
--- a/include/core/SkFlattenable.h
+++ b/include/core/SkFlattenable.h
@@ -161,6 +161,9 @@ public:
void* readFunctionPtr();
SkFlattenable* readFlattenable();
+ void setPictureVersion(uint32_t version) { fPictureVersion = version; }
+ uint32_t getPictureVersion() { return fPictureVersion; }
+
private:
SkRefCnt** fRCArray;
int fRCCount;
@@ -172,6 +175,8 @@ private:
SkFlattenable::Factory* fFactoryArray;
int fFactoryCount;
+ uint32_t fPictureVersion;
+
typedef SkReader32 INHERITED;
};
diff --git a/include/core/SkUserConfig.h b/include/core/SkUserConfig.h
index b409e82..4bcf2e3 100644
--- a/include/core/SkUserConfig.h
+++ b/include/core/SkUserConfig.h
@@ -41,6 +41,9 @@
// ANDROID Specific changes - NO NOT CHECK BACK INTO code.google.com/p/skia
//
+#define PICTURE_VERSION_ICS 1 // r1562 of Skia
+#define PICTURE_VERSION_JB 2
+
// do this build check for other tools that still read this header
#ifdef ANDROID
#include <utils/misc.h>
diff --git a/src/core/SkFlattenable.cpp b/src/core/SkFlattenable.cpp
index 59a262a..131cf4f 100644
--- a/src/core/SkFlattenable.cpp
+++ b/src/core/SkFlattenable.cpp
@@ -58,6 +58,7 @@ SkFlattenableReadBuffer::SkFlattenableReadBuffer() {
fFactoryTDArray = NULL;
fFactoryArray = NULL;
fFactoryCount = 0;
+ fPictureVersion = PICTURE_VERSION_JB;
}
SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data) :
@@ -71,6 +72,7 @@ SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data) :
fFactoryTDArray = NULL;
fFactoryArray = NULL;
fFactoryCount = 0;
+ fPictureVersion = PICTURE_VERSION_JB;
}
SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data, size_t size)
@@ -84,6 +86,7 @@ SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data, size_t size)
fFactoryTDArray = NULL;
fFactoryArray = NULL;
fFactoryCount = 0;
+ fPictureVersion = PICTURE_VERSION_JB;
}
SkTypeface* SkFlattenableReadBuffer::readTypeface() {
@@ -110,6 +113,43 @@ SkRefCnt* SkFlattenableReadBuffer::readRefCnt() {
}
SkFlattenable* SkFlattenableReadBuffer::readFlattenable() {
+
+ if(fPictureVersion == PICTURE_VERSION_ICS) {
+ SkFlattenable::Factory factory = NULL;
+
+ if (fFactoryCount > 0) {
+ uint32_t index = this->readU32();
+ if (index > 0) {
+ index -= 1;
+ SkASSERT(index < (unsigned)fFactoryCount);
+ factory = fFactoryArray[index];
+ // if we recorded an index, but failed to get a factory, we need
+ // to skip the flattened data in the buffer
+ if (NULL == factory) {
+ uint32_t size = this->readU32();
+ this->skip(size);
+ // fall through and return NULL for the object
+ }
+ }
+ } else {
+ factory = (SkFlattenable::Factory)readFunctionPtr();
+ }
+
+ SkFlattenable* obj = NULL;
+ if (factory) {
+ uint32_t sizeRecorded = this->readU32();
+ uint32_t offset = this->offset();
+ obj = (*factory)(*this);
+ // check that we read the amount we expected
+ uint32_t sizeRead = this->offset() - offset;
+ if (sizeRecorded != sizeRead) {
+ // we could try to fix up the offset...
+ sk_throw();
+ }
+ }
+ return obj;
+ }
+
SkFlattenable::Factory factory = NULL;
if (fFactoryCount > 0) {
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index a6d30c9..ea5e876 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -1722,11 +1722,16 @@ void SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
uint32_t tmp = *pod++;
this->setFlags(tmp >> 16);
- // hinting added later. 0 in this nibble means use the default.
- uint32_t hinting = (tmp >> 12) & 0xF;
- this->setHinting(0 == hinting ? kNormal_Hinting : static_cast<Hinting>(hinting-1));
+ if (buffer.getPictureVersion() == PICTURE_VERSION_ICS) {
+ this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xFF));
+ this->setHinting(kNormal_Hinting);
+ } else {
+ // hinting added later. 0 in this nibble means use the default.
+ uint32_t hinting = (tmp >> 12) & 0xF;
+ this->setHinting(0 == hinting ? kNormal_Hinting : static_cast<Hinting>(hinting-1));
- this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xF));
+ this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xF));
+ }
uint8_t flatFlags = tmp & 0xFF;
@@ -1750,7 +1755,10 @@ void SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
SkSafeUnref(this->setColorFilter((SkColorFilter*) buffer.readFlattenable()));
SkSafeUnref(this->setRasterizer((SkRasterizer*) buffer.readFlattenable()));
SkSafeUnref(this->setLooper((SkDrawLooper*) buffer.readFlattenable()));
- SkSafeUnref(this->setImageFilter((SkImageFilter*) buffer.readFlattenable()));
+ if (buffer.getPictureVersion() != PICTURE_VERSION_ICS)
+ SkSafeUnref(this->setImageFilter((SkImageFilter*) buffer.readFlattenable()));
+ else
+ this->setImageFilter(NULL);
} else {
this->setPathEffect(NULL);
this->setShader(NULL);
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp
index a3b7396..6aaaf2d 100644
--- a/src/core/SkPicture.cpp
+++ b/src/core/SkPicture.cpp
@@ -192,7 +192,9 @@ void SkPicture::draw(SkCanvas* surface) {
#define PICTURE_VERSION 1
SkPicture::SkPicture(SkStream* stream) : SkRefCnt() {
- if (stream->readU32() != PICTURE_VERSION) {
+ const uint32_t pictureVersion = stream->readU32();
+ if (pictureVersion != PICTURE_VERSION_ICS &&
+ pictureVersion != PICTURE_VERSION_JB) {
sk_throw();
}
@@ -203,7 +205,7 @@ SkPicture::SkPicture(SkStream* stream) : SkRefCnt() {
fPlayback = NULL;
if (stream->readBool()) {
- fPlayback = SkNEW_ARGS(SkPicturePlayback, (stream));
+ fPlayback = SkNEW_ARGS(SkPicturePlayback, (stream, pictureVersion));
}
}
@@ -214,7 +216,7 @@ void SkPicture::serialize(SkWStream* stream) const {
playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord));
}
- stream->write32(PICTURE_VERSION);
+ stream->write32(PICTURE_VERSION_JB);
stream->write32(fWidth);
stream->write32(fHeight);
if (playback) {
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index 983bfc5..bfd253a 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -24,7 +24,6 @@ enum DrawType {
CONCAT,
DRAW_BITMAP,
DRAW_BITMAP_MATRIX,
- DRAW_BITMAP_NINE,
DRAW_BITMAP_RECT,
DRAW_CLEAR,
DRAW_DATA,
@@ -37,6 +36,7 @@ enum DrawType {
DRAW_POS_TEXT_H,
DRAW_POS_TEXT_H_TOP_BOTTOM, // fast variant of DRAW_POS_TEXT_H
DRAW_RECT,
+ DRAW_SHAPE,
DRAW_SPRITE,
DRAW_TEXT,
DRAW_TEXT_ON_PATH,
@@ -49,7 +49,8 @@ enum DrawType {
SCALE,
SET_MATRIX,
SKEW,
- TRANSLATE
+ TRANSLATE,
+ DRAW_BITMAP_NINE
};
enum DrawVertexFlags {
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index c2082c7..f5756a3 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -263,6 +263,7 @@ void SkPicturePlayback::dumpSize() const {
#define PICT_PAINT_TAG SkSetFourByteTag('p', 'n', 't', ' ')
#define PICT_PATH_TAG SkSetFourByteTag('p', 't', 'h', ' ')
#define PICT_REGION_TAG SkSetFourByteTag('r', 'g', 'n', ' ')
+#define PICT_SHAPE_TAG SkSetFourByteTag('s', 'h', 'p', ' ')
#include "SkStream.h"
@@ -391,7 +392,7 @@ static int readTagSize(SkStream* stream, uint32_t expectedTag) {
return stream->readU32();
}
-SkPicturePlayback::SkPicturePlayback(SkStream* stream) {
+SkPicturePlayback::SkPicturePlayback(SkStream* stream, uint32_t pictureVersion) {
this->init();
int i;
@@ -401,6 +402,7 @@ SkPicturePlayback::SkPicturePlayback(SkStream* stream) {
void* storage = sk_malloc_throw(size);
stream->read(storage, size);
fReader.setMemory(storage, size);
+ fReader.setPictureVersion(pictureVersion);
}
int factoryCount = readTagSize(stream, PICT_FACTORY_TAG);
@@ -434,6 +436,7 @@ SkPicturePlayback::SkPicturePlayback(SkStream* stream) {
stream->read(storage.get(), size);
SkFlattenableReadBuffer buffer(storage.get(), size);
+ buffer.setPictureVersion(pictureVersion);
fFactoryPlayback->setupBuffer(buffer);
fTFPlayback.setupBuffer(buffer);
@@ -467,6 +470,13 @@ SkPicturePlayback::SkPicturePlayback(SkStream* stream) {
SkDEBUGCODE(uint32_t bytes =) fRegions[i].unflatten(buffer.skip(size));
SkASSERT(size == bytes);
}
+
+ if (pictureVersion == PICTURE_VERSION_ICS) {
+ int shapeCount = readTagSize(buffer, PICT_SHAPE_TAG);
+ for (i = 0; i < shapeCount; i++) {
+ buffer.readFlattenable();
+ }
+ }
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkPicturePlayback.h b/src/core/SkPicturePlayback.h
index 88f86e2..16ac0b8 100644
--- a/src/core/SkPicturePlayback.h
+++ b/src/core/SkPicturePlayback.h
@@ -32,7 +32,7 @@ public:
SkPicturePlayback();
SkPicturePlayback(const SkPicturePlayback& src);
explicit SkPicturePlayback(const SkPictureRecord& record);
- explicit SkPicturePlayback(SkStream*);
+ explicit SkPicturePlayback(SkStream*, uint32_t pictureVersion = PICTURE_VERSION_JB);
virtual ~SkPicturePlayback();
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index fdf1798..4e1e539 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -755,6 +755,12 @@ protected:
: INHERITED(buffer) {
fMode = (SkXfermode::Mode)buffer.readU32();
+ if (buffer.getPictureVersion() == PICTURE_VERSION_ICS) {
+ fSrcCoeff = (Coeff)buffer.readU32();
+ fDstCoeff = (Coeff)buffer.readU32();
+ return;
+ }
+
const ProcCoeff& rec = gProcCoeffs[fMode];
// these may be valid, or may be CANNOT_USE_COEFF
fSrcCoeff = rec.fSC;
diff --git a/src/effects/SkLayerDrawLooper.cpp b/src/effects/SkLayerDrawLooper.cpp
index acb3e88..16636dc 100644
--- a/src/effects/SkLayerDrawLooper.cpp
+++ b/src/effects/SkLayerDrawLooper.cpp
@@ -218,6 +218,8 @@ SkLayerDrawLooper::SkLayerDrawLooper(SkFlattenableReadBuffer& buffer)
for (int i = 0; i < count; i++) {
LayerInfo info;
+ if (buffer.getPictureVersion() == PICTURE_VERSION_ICS)
+ info.fFlagsMask = buffer.readInt();
info.fPaintBits = buffer.readInt();
info.fColorMode = (SkXfermode::Mode)buffer.readInt();
info.fOffset.fX = buffer.readScalar();