Decouple the SkFlattenable from SkReader32/SkWriter32.

The current impl for SkFlattenable read/write buffers is 
that they extend from SkReader32 and SkWriter32, but that
dependency must be abstract if we are to add any other
serialization format.
Review URL: https://codereview.appspot.com/5999045

git-svn-id: http://skia.googlecode.com/svn/trunk@3654 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
djsollen@google.com 2012-04-12 13:24:04 +00:00
parent 7463f19097
commit 2b2ede3e71
23 changed files with 496 additions and 317 deletions

View File

@ -87,6 +87,8 @@
'../src/core/SkMatrix.cpp',
'../src/core/SkMetaData.cpp',
'../src/core/SkMMapStream.cpp',
'../src/core/SkOrderedReadBuffer.cpp',
'../src/core/SkOrderedWriteBuffer.cpp',
'../src/core/SkPackBits.cpp',
'../src/core/SkPaint.cpp',
'../src/core/SkPath.cpp',

View File

@ -12,6 +12,8 @@
#include "SkRefCnt.h"
#include "SkBitmap.h"
#include "SkPath.h"
#include "SkPoint.h"
#include "SkReader32.h"
#include "SkTDArray.h"
#include "SkWriter32.h"
@ -119,12 +121,38 @@ extern void SkWriteRegion(SkWriter32*, const SkRegion&);
class SkTypeface;
class SkFlattenableReadBuffer : public SkReader32 {
class SkFlattenableReadBuffer {
public:
SkFlattenableReadBuffer();
explicit SkFlattenableReadBuffer(const void* data);
SkFlattenableReadBuffer(const void* data, size_t size);
virtual ~SkFlattenableReadBuffer() {}
virtual uint8_t readU8() = 0;
virtual uint16_t readU16() = 0;
virtual uint32_t readU32() = 0;
virtual void read(void* dst, size_t size) = 0;
virtual bool readBool() = 0;
virtual int32_t readInt() = 0;
virtual SkScalar readScalar() = 0;
virtual const void* skip(size_t size) = 0;
virtual int32_t readS32() { return readInt(); }
template <typename T> const T& skipT() {
SkASSERT(SkAlign4(sizeof(T)) == sizeof(T));
return *(const T*)this->skip(sizeof(T));
}
virtual void readMatrix(SkMatrix*) = 0;
virtual void readPath(SkPath*) = 0;
virtual void readPoint(SkPoint*) = 0;
// helper function for classes with const SkPoint members
SkPoint readPoint() {
SkPoint point;
this->readPoint(&point);
return point;
}
void setRefCntArray(SkRefCnt* array[], int count) {
fRCArray = array;
fRCCount = count;
@ -156,12 +184,12 @@ public:
fFactoryCount = 0;
}
SkTypeface* readTypeface();
SkRefCnt* readRefCnt();
void* readFunctionPtr();
SkFlattenable* readFlattenable();
virtual SkTypeface* readTypeface() = 0;
virtual SkRefCnt* readRefCnt() = 0;
virtual void* readFunctionPtr() = 0;
virtual SkFlattenable* readFlattenable() = 0;
private:
protected:
SkRefCnt** fRCArray;
int fRCCount;
@ -171,8 +199,6 @@ private:
SkTDArray<SkFlattenable::Factory>* fFactoryTDArray;
SkFlattenable::Factory* fFactoryArray;
int fFactoryCount;
typedef SkReader32 INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
@ -187,7 +213,7 @@ private:
class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
public:
virtual ~SkRefCntSet();
protected:
// overrides
virtual void incPtr(void*);
@ -196,22 +222,47 @@ protected:
class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
class SkFlattenableWriteBuffer : public SkWriter32 {
class SkFlattenableWriteBuffer {
public:
SkFlattenableWriteBuffer(size_t minSize);
SkFlattenableWriteBuffer();
virtual ~SkFlattenableWriteBuffer();
// deprecated naming convention that will be removed after callers are updated
virtual bool writeBool(bool value) = 0;
virtual void writeInt(int32_t value) = 0;
virtual void write8(int32_t value) = 0;
virtual void write16(int32_t value) = 0;
virtual void write32(int32_t value) = 0;
virtual void writeScalar(SkScalar value) = 0;
virtual void writeMul4(const void* values, size_t size) = 0;
virtual void writePad(const void* src, size_t size) = 0;
virtual void writeString(const char* str, size_t len = (size_t)-1) = 0;
virtual uint32_t* reserve(size_t size) = 0;
virtual void flatten(void* dst) = 0;
virtual uint32_t size() = 0;
virtual void write(const void* values, size_t size) = 0;
virtual void writeRect(const SkRect& rect) = 0;
virtual size_t readFromStream(SkStream*, size_t length) = 0;
virtual void writeMatrix(const SkMatrix& matrix) = 0;
virtual void writePath(const SkPath& path) = 0;
virtual void writePoint(const SkPoint& point) = 0;
virtual bool writeToStream(SkWStream*) = 0;
virtual void writeFunctionPtr(void*)= 0;
virtual void writeFlattenable(SkFlattenable* flattenable)= 0;
void writeTypeface(SkTypeface*);
void writeRefCnt(SkRefCnt*);
void writeFunctionPtr(void*);
void writeFlattenable(SkFlattenable* flattenable);
void writeRefCnt(SkRefCnt* obj);
SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
SkRefCntSet* getRefCntRecorder() const { return fRCSet; }
SkRefCntSet* setRefCntRecorder(SkRefCntSet*);
SkFactorySet* getFactoryRecorder() const { return fFactorySet; }
SkFactorySet* setFactoryRecorder(SkFactorySet*);
@ -225,7 +276,7 @@ public:
};
Flags getFlags() const { return (Flags)fFlags; }
void setFlags(Flags flags) { fFlags = flags; }
bool isCrossProcess() const {
return SkToBool(fFlags & kCrossProcess_Flag);
}
@ -236,16 +287,21 @@ public:
bool persistBitmapPixels() const {
return (fFlags & kCrossProcess_Flag) != 0;
}
bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
private:
protected:
// A helper function so that each subclass does not have to be a friend of
// SkFlattenable.
void flattenObject(SkFlattenable* obj, SkFlattenableWriteBuffer& buffer) {
obj->flatten(buffer);
}
uint32_t fFlags;
SkRefCntSet* fTFSet;
SkRefCntSet* fRCSet;
SkFactorySet* fFactorySet;
typedef SkWriter32 INHERITED;
};
#endif

View File

@ -0,0 +1,61 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkOrderedReadBuffer_DEFINED
#define SkOrderedReadBuffer_DEFINED
#include "SkRefCnt.h"
#include "SkBitmap.h"
#include "SkFlattenable.h"
#include "SkWriter32.h"
#include "SkPath.h"
class SkOrderedReadBuffer : public SkFlattenableReadBuffer {
public:
SkOrderedReadBuffer() : INHERITED() {}
SkOrderedReadBuffer(const void* data, size_t size);
void setMemory(const void* data, size_t size) { fReader.setMemory(data, size); }
uint32_t size() { return fReader.size(); }
const void* base() { return fReader.base(); }
uint32_t offset() { return fReader.offset(); }
bool eof() { return fReader.eof(); }
void rewind() { fReader.rewind(); }
void setOffset(size_t offset) { fReader.setOffset(offset); }
SkReader32* getReader32() { return &fReader; }
virtual uint8_t readU8() { return fReader.readU8(); }
virtual uint16_t readU16() { return fReader.readU16(); }
virtual uint32_t readU32() { return fReader.readU32(); }
virtual void read(void* dst, size_t size) { return fReader.read(dst, size); }
virtual bool readBool() { return fReader.readBool(); }
virtual int32_t readInt() { return fReader.readInt(); }
virtual SkScalar readScalar() { return fReader.readScalar(); }
virtual const void* skip(size_t size) { return fReader.skip(size); }
virtual void readMatrix(SkMatrix* m) { fReader.readMatrix(m); }
virtual void readPath(SkPath* p) { p->unflatten(fReader); }
virtual void readPoint(SkPoint* p) {
p->fX = fReader.readScalar();
p->fY = fReader.readScalar();
}
virtual SkTypeface* readTypeface();
virtual SkRefCnt* readRefCnt();
virtual void* readFunctionPtr();
virtual SkFlattenable* readFlattenable();
private:
SkReader32 fReader;
typedef SkFlattenableReadBuffer INHERITED;
};
#endif // SkOrderedReadBuffer_DEFINED

View File

@ -0,0 +1,59 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkOrderedWriteBuffer_DEFINED
#define SkOrderedWriteBuffer_DEFINED
#include "SkRefCnt.h"
#include "SkBitmap.h"
#include "SkFlattenable.h"
#include "SkWriter32.h"
#include "SkPath.h"
class SkOrderedWriteBuffer : public SkFlattenableWriteBuffer {
public:
SkOrderedWriteBuffer(size_t minSize);
virtual ~SkOrderedWriteBuffer() {}
// deprecated naming convention that will be removed after callers are updated
virtual bool writeBool(bool value) { return fWriter.writeBool(value); }
virtual void writeInt(int32_t value) { fWriter.writeInt(value); }
virtual void write8(int32_t value) { fWriter.write8(value); }
virtual void write16(int32_t value) { fWriter.write16(value); }
virtual void write32(int32_t value) { fWriter.write32(value); }
virtual void writeScalar(SkScalar value) { fWriter.writeScalar(value); }
virtual void writeMul4(const void* values, size_t size) { fWriter.writeMul4(values, size); }
virtual void writePad(const void* src, size_t size) { fWriter.writePad(src, size); }
virtual void writeString(const char* str, size_t len = (size_t)-1) { fWriter.writeString(str, len); }
virtual bool writeToStream(SkWStream* stream) { return fWriter.writeToStream(stream); }
virtual void write(const void* values, size_t size) { fWriter.write(values, size); }
virtual void writeRect(const SkRect& rect) { fWriter.writeRect(rect); }
virtual size_t readFromStream(SkStream* s, size_t length) { return fWriter.readFromStream(s, length); }
virtual void writeMatrix(const SkMatrix& matrix) { fWriter.writeMatrix(matrix); }
virtual void writePath(const SkPath& path) { path.flatten(fWriter); };
virtual void writePoint(const SkPoint& point) {
fWriter.writeScalar(point.fX);
fWriter.writeScalar(point.fY);
}
virtual uint32_t* reserve(size_t size) { return fWriter.reserve(size); }
virtual void flatten(void* dst) { fWriter.flatten(dst); }
virtual uint32_t size() { return fWriter.size(); }
virtual void writeFunctionPtr(void*);
virtual void writeFlattenable(SkFlattenable* flattenable);
private:
SkWriter32 fWriter;
typedef SkFlattenableWriteBuffer INHERITED;
};
#endif // SkOrderedWriteBuffer_DEFINED

View File

@ -10,6 +10,8 @@
#ifndef SkReader32_DEFINED
#define SkReader32_DEFINED
#include "SkMatrix.h"
#include "SkRegion.h"
#include "SkScalar.h"
class SkString;
@ -90,6 +92,18 @@ public:
int32_t readS32() { return this->readInt(); }
uint32_t readU32() { return this->readInt(); }
void readMatrix(SkMatrix* matrix) {
size_t size = matrix->unflatten(this->peek());
SkASSERT(SkAlign4(size) == size);
(void)this->skip(size);
}
void readRegion(SkRegion* rgn) {
size_t size = rgn->unflatten(this->peek());
SkASSERT(SkAlign4(size) == size);
(void)this->skip(size);
}
/**
* Read the length of a string (written by SkWriter32::writeString) into
* len (if len is not NULL) and return the null-ternimated address of the

View File

@ -15,6 +15,8 @@
#include "SkScalar.h"
#include "SkPoint.h"
#include "SkRect.h"
#include "SkMatrix.h"
#include "SkRegion.h"
class SkStream;
class SkWStream;
@ -76,7 +78,19 @@ public:
void writeRect(const SkRect& rect) {
*(SkRect*)this->reserve(sizeof(rect)) = rect;
}
void writeMatrix(const SkMatrix& matrix) {
size_t size = matrix.flatten(NULL);
SkASSERT(SkAlign4(size) == size);
matrix.flatten(this->reserve(size));
}
void writeRegion(const SkRegion& rgn) {
size_t size = rgn.flatten(NULL);
SkASSERT(SkAlign4(size) == size);
rgn.flatten(this->reserve(size));
}
// write count bytes (must be a multiple of 4)
void writeMul4(const void* values, size_t size) {
this->write(values, size);

View File

@ -8,33 +8,6 @@
#include "SkFlattenable.h"
#include "SkTypeface.h"
#include "SkMatrix.h"
#include "SkRegion.h"
void SkReadMatrix(SkReader32* reader, SkMatrix* matrix) {
size_t size = matrix->unflatten(reader->peek());
SkASSERT(SkAlign4(size) == size);
(void)reader->skip(size);
}
void SkWriteMatrix(SkWriter32* writer, const SkMatrix& matrix) {
size_t size = matrix.flatten(NULL);
SkASSERT(SkAlign4(size) == size);
matrix.flatten(writer->reserve(size));
}
void SkReadRegion(SkReader32* reader, SkRegion* rgn) {
size_t size = rgn->unflatten(reader->peek());
SkASSERT(SkAlign4(size) == size);
(void)reader->skip(size);
}
void SkWriteRegion(SkWriter32* writer, const SkRegion& rgn) {
size_t size = rgn.flatten(NULL);
SkASSERT(SkAlign4(size) == size);
rgn.flatten(writer->reserve(size));
}
///////////////////////////////////////////////////////////////////////////////
void SkFlattenable::flatten(SkFlattenableWriteBuffer&) const
@ -45,7 +18,6 @@ void SkFlattenable::flatten(SkFlattenableWriteBuffer&) const
*/
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SkFlattenableReadBuffer::SkFlattenableReadBuffer() {
@ -60,126 +32,9 @@ SkFlattenableReadBuffer::SkFlattenableReadBuffer() {
fFactoryCount = 0;
}
SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data) :
INHERITED(data, 1024 * 1024) {
fRCArray = NULL;
fRCCount = 0;
fTFArray = NULL;
fTFCount = 0;
fFactoryTDArray = NULL;
fFactoryArray = NULL;
fFactoryCount = 0;
}
SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data, size_t size)
: INHERITED(data, size) {
fRCArray = NULL;
fRCCount = 0;
fTFArray = NULL;
fTFCount = 0;
fFactoryTDArray = NULL;
fFactoryArray = NULL;
fFactoryCount = 0;
}
SkTypeface* SkFlattenableReadBuffer::readTypeface() {
uint32_t index = this->readU32();
if (0 == index || index > (unsigned)fTFCount) {
if (index) {
SkDebugf("====== typeface index %d\n", index);
}
return NULL;
} else {
SkASSERT(fTFArray);
return fTFArray[index - 1];
}
}
SkRefCnt* SkFlattenableReadBuffer::readRefCnt() {
uint32_t index = this->readU32();
if (0 == index || index > (unsigned)fRCCount) {
return NULL;
} else {
SkASSERT(fRCArray);
return fRCArray[index - 1];
}
}
SkFlattenable* SkFlattenableReadBuffer::readFlattenable() {
SkFlattenable::Factory factory = NULL;
if (fFactoryCount > 0) {
int32_t index = this->readU32();
if (0 == index) {
return NULL; // writer failed to give us the flattenable
}
index = -index; // we stored the negative of the index
index -= 1; // we stored the index-base-1
SkASSERT(index < fFactoryCount);
factory = fFactoryArray[index];
} else if (fFactoryTDArray) {
const int32_t* peek = (const int32_t*)this->peek();
if (*peek <= 0) {
int32_t index = this->readU32();
if (0 == index) {
return NULL; // writer failed to give us the flattenable
}
index = -index; // we stored the negative of the index
index -= 1; // we stored the index-base-1
factory = (*fFactoryTDArray)[index];
} else {
const char* name = this->readString();
factory = SkFlattenable::NameToFactory(name);
if (factory) {
SkASSERT(fFactoryTDArray->find(factory) < 0);
*fFactoryTDArray->append() = factory;
} else {
// SkDebugf("can't find factory for [%s]\n", name);
}
// if we didn't find a factory, that's our failure, not the writer's,
// so we fall through, so we can skip the sizeRecorded data.
}
} else {
factory = (SkFlattenable::Factory)readFunctionPtr();
if (NULL == factory) {
return NULL; // writer failed to give us the flattenable
}
}
// if we get here, factory may still be null, but if that is the case, the
// failure was ours, not the writer.
SkFlattenable* obj = NULL;
uint32_t sizeRecorded = this->readU32();
if (factory) {
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();
}
} else {
// we must skip the remaining data
this->skip(sizeRecorded);
}
return obj;
}
void* SkFlattenableReadBuffer::readFunctionPtr() {
void* proc;
this->read(&proc, sizeof(proc));
return proc;
}
///////////////////////////////////////////////////////////////////////////////
SkFlattenableWriteBuffer::SkFlattenableWriteBuffer(size_t minSize) :
INHERITED(minSize) {
SkFlattenableWriteBuffer::SkFlattenableWriteBuffer() {
fFlags = (Flags)0;
fRCSet = NULL;
fTFSet = NULL;
@ -207,15 +62,8 @@ SkFactorySet* SkFlattenableWriteBuffer::setFactoryRecorder(SkFactorySet* rec) {
return rec;
}
void SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) {
if (NULL == obj || NULL == fTFSet) {
this->write32(0);
} else {
this->write32(fTFSet->add(obj));
}
}
void SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) {
SkASSERT(!isCrossProcess());
if (NULL == obj || NULL == fRCSet) {
this->write32(0);
} else {
@ -223,83 +71,12 @@ void SkFlattenableWriteBuffer::writeRefCnt(SkRefCnt* obj) {
}
}
void SkFlattenableWriteBuffer::writeFlattenable(SkFlattenable* flattenable) {
/*
* If we have a factoryset, then the first 32bits tell us...
* 0: failure to write the flattenable
* <0: we store the negative of the (1-based) index
* >0: the length of the name
* If we don't have a factoryset, then the first "ptr" is either the
* factory, or null for failure.
*
* The distinction is important, since 0-index is 32bits (always), but a
* 0-functionptr might be 32 or 64 bits.
*/
SkFlattenable::Factory factory = NULL;
if (flattenable) {
factory = flattenable->getFactory();
}
if (NULL == factory) {
if (fFactorySet) {
this->write32(0);
} else {
this->writeFunctionPtr(NULL);
}
return;
}
/*
* We can write 1 of 3 versions of the flattenable:
* 1. function-ptr : this is the fastest for the reader, but assumes that
* the writer and reader are in the same process.
* 2. index into fFactorySet : This is assumes the writer will later
* resolve the function-ptrs into strings for its reader. SkPicture
* does exactly this, by writing a table of names (matching the indices)
* up front in its serialized form.
* 3. names : Reuse fFactorySet to store indices, but only after we've
* written the name the first time. SkGPipe uses this technique, as it
* doesn't require the reader to be told to know the table of names
* up front.
*/
if (fFactorySet) {
if (this->inlineFactoryNames()) {
int index = fFactorySet->find(factory);
if (index) {
// we write the negative of the index, to distinguish it from
// the length of a string
this->write32(-index);
} else {
const char* name = SkFlattenable::FactoryToName(factory);
if (NULL == name) {
this->write32(0);
return;
}
this->writeString(name);
index = fFactorySet->add(factory);
}
} else {
// we write the negative of the index, to distinguish it from
// the length of a string
this->write32(-(int)fFactorySet->add(factory));
}
void SkFlattenableWriteBuffer::writeTypeface(SkTypeface* obj) {
if (NULL == obj || NULL == fTFSet) {
this->write32(0);
} else {
this->writeFunctionPtr((void*)factory);
this->write32(fTFSet->add(obj));
}
// make room for the size of the flatttened object
(void)this->reserve(sizeof(uint32_t));
// record the current size, so we can subtract after the object writes.
uint32_t offset = this->size();
// now flatten the object
flattenable->flatten(*this);
uint32_t objSize = this->size() - offset;
// record the obj's size
*this->peek32(offset - sizeof(uint32_t)) = objSize;
}
void SkFlattenableWriteBuffer::writeFunctionPtr(void* proc) {
*(void**)this->reserve(sizeof(void*)) = proc;
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,106 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkOrderedReadBuffer.h"
#include "SkTypeface.h"
SkOrderedReadBuffer::SkOrderedReadBuffer(const void* data, size_t size)
: INHERITED() {
fReader.setMemory(data, size);
}
SkTypeface* SkOrderedReadBuffer::readTypeface() {
uint32_t index = fReader.readU32();
if (0 == index || index > (unsigned)fTFCount) {
if (index) {
SkDebugf("====== typeface index %d\n", index);
}
return NULL;
} else {
SkASSERT(fTFArray);
return fTFArray[index - 1];
}
}
SkRefCnt* SkOrderedReadBuffer::readRefCnt() {
uint32_t index = fReader.readU32();
if (0 == index || index > (unsigned)fRCCount) {
return NULL;
} else {
SkASSERT(fRCArray);
return fRCArray[index - 1];
}
}
SkFlattenable* SkOrderedReadBuffer::readFlattenable() {
SkFlattenable::Factory factory = NULL;
if (fFactoryCount > 0) {
int32_t index = fReader.readU32();
if (0 == index) {
return NULL; // writer failed to give us the flattenable
}
index = -index; // we stored the negative of the index
index -= 1; // we stored the index-base-1
SkASSERT(index < fFactoryCount);
factory = fFactoryArray[index];
} else if (fFactoryTDArray) {
const int32_t* peek = (const int32_t*)fReader.peek();
if (*peek <= 0) {
int32_t index = fReader.readU32();
if (0 == index) {
return NULL; // writer failed to give us the flattenable
}
index = -index; // we stored the negative of the index
index -= 1; // we stored the index-base-1
factory = (*fFactoryTDArray)[index];
} else {
const char* name = fReader.readString();
factory = SkFlattenable::NameToFactory(name);
if (factory) {
SkASSERT(fFactoryTDArray->find(factory) < 0);
*fFactoryTDArray->append() = factory;
} else {
// SkDebugf("can't find factory for [%s]\n", name);
}
// if we didn't find a factory, that's our failure, not the writer's,
// so we fall through, so we can skip the sizeRecorded data.
}
} else {
factory = (SkFlattenable::Factory)readFunctionPtr();
if (NULL == factory) {
return NULL; // writer failed to give us the flattenable
}
}
// if we get here, factory may still be null, but if that is the case, the
// failure was ours, not the writer.
SkFlattenable* obj = NULL;
uint32_t sizeRecorded = fReader.readU32();
if (factory) {
uint32_t offset = fReader.offset();
obj = (*factory)(*this);
// check that we read the amount we expected
uint32_t sizeRead = fReader.offset() - offset;
if (sizeRecorded != sizeRead) {
// we could try to fix up the offset...
sk_throw();
}
} else {
// we must skip the remaining data
fReader.skip(sizeRecorded);
}
return obj;
}
void* SkOrderedReadBuffer::readFunctionPtr() {
void* proc;
fReader.read(&proc, sizeof(proc));
return proc;
}

View File

@ -0,0 +1,94 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkOrderedWriteBuffer.h"
#include "SkTypeface.h"
SkOrderedWriteBuffer::SkOrderedWriteBuffer(size_t minSize) :
INHERITED(),
fWriter(minSize) {
}
void SkOrderedWriteBuffer::writeFlattenable(SkFlattenable* flattenable) {
/*
* If we have a factoryset, then the first 32bits tell us...
* 0: failure to write the flattenable
* <0: we store the negative of the (1-based) index
* >0: the length of the name
* If we don't have a factoryset, then the first "ptr" is either the
* factory, or null for failure.
*
* The distinction is important, since 0-index is 32bits (always), but a
* 0-functionptr might be 32 or 64 bits.
*/
SkFlattenable::Factory factory = NULL;
if (flattenable) {
factory = flattenable->getFactory();
}
if (NULL == factory) {
if (fFactorySet) {
this->write32(0);
} else {
this->writeFunctionPtr(NULL);
}
return;
}
/*
* We can write 1 of 3 versions of the flattenable:
* 1. function-ptr : this is the fastest for the reader, but assumes that
* the writer and reader are in the same process.
* 2. index into fFactorySet : This is assumes the writer will later
* resolve the function-ptrs into strings for its reader. SkPicture
* does exactly this, by writing a table of names (matching the indices)
* up front in its serialized form.
* 3. names : Reuse fFactorySet to store indices, but only after we've
* written the name the first time. SkGPipe uses this technique, as it
* doesn't require the reader to be told to know the table of names
* up front.
*/
if (fFactorySet) {
if (this->inlineFactoryNames()) {
int index = fFactorySet->find(factory);
if (index) {
// we write the negative of the index, to distinguish it from
// the length of a string
this->write32(-index);
} else {
const char* name = SkFlattenable::FactoryToName(factory);
if (NULL == name) {
this->write32(0);
return;
}
this->writeString(name);
index = fFactorySet->add(factory);
}
} else {
// we write the negative of the index, to distinguish it from
// the length of a string
this->write32(-(int)fFactorySet->add(factory));
}
} else {
this->writeFunctionPtr((void*)factory);
}
// make room for the size of the flatttened object
(void)this->reserve(sizeof(uint32_t));
// record the current size, so we can subtract after the object writes.
uint32_t offset = this->size();
// now flatten the object
flattenObject(flattenable, *this);
uint32_t objSize = this->size() - offset;
// record the obj's size
*fWriter.peek32(offset - sizeof(uint32_t)) = objSize;
}
void SkOrderedWriteBuffer::writeFunctionPtr(void* proc) {
*(void**)this->reserve(sizeof(void*)) = proc;
}

View File

@ -24,6 +24,7 @@
#include "SkAutoKern.h"
#include "SkGlyphCache.h"
#include "SkPaintDefaults.h"
#include "SkOrderedWriteBuffer.h"
// define this to get a printf for out-of-range parameter in setters
// e.g. setTextSize(-1)
@ -1682,9 +1683,9 @@ void SkPaint::descriptorProc(const SkMatrix* deviceMatrix,
SkMaskFilter* mf = this->getMaskFilter();
SkRasterizer* ra = this->getRasterizer();
SkFlattenableWriteBuffer peBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
SkFlattenableWriteBuffer mfBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
SkFlattenableWriteBuffer raBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
SkOrderedWriteBuffer peBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
SkOrderedWriteBuffer mfBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
SkOrderedWriteBuffer raBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
if (pe) {
peBuffer.writeFlattenable(pe);

View File

@ -26,7 +26,7 @@ SkPathHeap::SkPathHeap(SkFlattenableReadBuffer& buffer)
for (int i = 0; i < count; i++) {
new (p) SkPath;
p->unflatten(buffer);
buffer.readPath(p);
*ptr++ = p; // record the pointer
p++; // move to the next storage location
}
@ -55,7 +55,7 @@ void SkPathHeap::flatten(SkFlattenableWriteBuffer& buffer) const {
SkPath** iter = fPaths.begin();
SkPath** stop = fPaths.end();
while (iter < stop) {
(*iter)->flatten(buffer);
buffer.writePath(**iter);
iter++;
}
}

View File

@ -14,6 +14,8 @@
#include "SkShader.h"
#include "SkTypeface.h"
#include "SkXfermode.h"
#include "SkOrderedReadBuffer.h"
#include "SkOrderedWriteBuffer.h"
SkFlatData* SkFlatData::Alloc(SkChunkAlloc* heap, int32_t size, int index) {
SkFlatData* result = (SkFlatData*) heap->allocThrow(size + sizeof(SkFlatData));
@ -24,7 +26,7 @@ SkFlatData* SkFlatData::Alloc(SkChunkAlloc* heap, int32_t size, int index) {
SkFlatBitmap* SkFlatBitmap::Flatten(SkChunkAlloc* heap, const SkBitmap& bitmap,
int index, SkRefCntSet* rec) {
SkFlattenableWriteBuffer buffer(1024);
SkOrderedWriteBuffer buffer(1024);
buffer.setRefCntRecorder(rec);
bitmap.flatten(buffer);
@ -91,7 +93,8 @@ void SkFlatMatrix::dump() const {
SkFlatPaint* SkFlatPaint::Flatten(SkChunkAlloc* heap, const SkPaint& paint,
int index, SkRefCntSet* rec,
SkRefCntSet* faceRecorder) {
SkFlattenableWriteBuffer buffer(2*sizeof(SkPaint));
SkOrderedWriteBuffer buffer(2*sizeof(SkPaint));
buffer.setRefCntRecorder(rec);
buffer.setTypefaceRecorder(faceRecorder);
@ -104,7 +107,7 @@ SkFlatPaint* SkFlatPaint::Flatten(SkChunkAlloc* heap, const SkPaint& paint,
void SkFlatPaint::Read(const void* storage, SkPaint* paint,
SkRefCntPlayback* rcp, SkTypefacePlayback* facePlayback) {
SkFlattenableReadBuffer buffer(storage);
SkOrderedReadBuffer buffer(storage, 1024*1024);
if (rcp) {
rcp->setupBuffer(buffer);
}

View File

@ -10,6 +10,7 @@
#include "SkChunkAlloc.h"
#include "SkBitmap.h"
#include "SkOrderedReadBuffer.h"
#include "SkPicture.h"
#include "SkMatrix.h"
#include "SkPaint.h"
@ -151,7 +152,7 @@ public:
SkRefCntSet*);
void unflatten(SkBitmap* bitmap, SkRefCntPlayback* rcp) const {
SkFlattenableReadBuffer buffer(fBitmapData);
SkOrderedReadBuffer buffer(fBitmapData, 1024*1024);
if (rcp) {
rcp->setupBuffer(buffer);
}

View File

@ -8,6 +8,8 @@
#include "SkPicturePlayback.h"
#include "SkPictureRecord.h"
#include "SkTypeface.h"
#include "SkOrderedReadBuffer.h"
#include "SkOrderedWriteBuffer.h"
#include <new>
/* Define this to spew out a debug statement whenever we skip the remainder of
@ -319,7 +321,7 @@ void SkPicturePlayback::serialize(SkWStream* stream) const {
SkRefCntSet typefaceSet;
SkFactorySet factSet;
SkFlattenableWriteBuffer buffer(1024);
SkOrderedWriteBuffer buffer(1024);
buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
buffer.setTypefaceRecorder(&typefaceSet);
@ -431,7 +433,7 @@ SkPicturePlayback::SkPicturePlayback(SkStream* stream) {
SkAutoMalloc storage(tagSize);
stream->read(storage.get(), tagSize);
SkFlattenableReadBuffer buffer(storage.get(), tagSize);
SkOrderedReadBuffer buffer(storage.get(), tagSize);
fFactoryPlayback->setupBuffer(buffer);
fTFPlayback.setupBuffer(buffer);

View File

@ -13,6 +13,7 @@
#include "SkBitmap.h"
#include "SkMatrix.h"
#include "SkOrderedReadBuffer.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkPathHeap.h"
@ -166,7 +167,7 @@ private:
int fPaintCount;
SkRegion* fRegions;
int fRegionCount;
mutable SkFlattenableReadBuffer fReader;
mutable SkOrderedReadBuffer fReader;
SkPicture** fPictureRefs;
int fPictureCount;

View File

@ -13,6 +13,7 @@
#include "SkDraw.h"
#include "SkFontHost.h"
#include "SkMaskFilter.h"
#include "SkOrderedReadBuffer.h"
#include "SkPathEffect.h"
#include "SkRasterizer.h"
#include "SkRasterClip.h"
@ -64,7 +65,7 @@ static SkFlattenable* load_flattenable(const SkDescriptor* desc, uint32_t tag) {
const void* data = desc->findEntry(tag, &len);
if (data) {
SkFlattenableReadBuffer buffer(data, len);
SkOrderedReadBuffer buffer(data, len);
obj = buffer.readFlattenable();
SkASSERT(buffer.offset() == buffer.size());
}

View File

@ -20,7 +20,7 @@ SkShader::SkShader(SkFlattenableReadBuffer& buffer)
: INHERITED(buffer), fLocalMatrix(NULL) {
if (buffer.readBool()) {
SkMatrix matrix;
SkReadMatrix(&buffer, &matrix);
buffer.readMatrix(&matrix);
setLocalMatrix(matrix);
}
SkDEBUGCODE(fInSession = false;)
@ -45,7 +45,7 @@ void SkShader::flatten(SkFlattenableWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
buffer.writeBool(fLocalMatrix != NULL);
if (fLocalMatrix) {
SkWriteMatrix(&buffer, *fLocalMatrix);
buffer.writeMatrix(*fLocalMatrix);
}
}

View File

@ -141,7 +141,7 @@ static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas,
SkPath1DPathEffect::SkPath1DPathEffect(SkFlattenableReadBuffer& buffer) {
fAdvance = buffer.readScalar();
if (fAdvance > 0) {
fPath.unflatten(buffer);
buffer.readPath(&fPath);
fInitialOffset = buffer.readScalar();
fStyle = (Style) buffer.readU8();
} else {
@ -160,7 +160,7 @@ void SkPath1DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
buffer.writeScalar(fAdvance);
if (fAdvance > 0) {
fPath.flatten(buffer);
buffer.writePath(fPath);
buffer.writeScalar(fInitialOffset);
buffer.write8(fStyle);
}

View File

@ -90,12 +90,12 @@ SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p)
SkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer)
: INHERITED(buffer) {
fPath.unflatten(buffer);
buffer.readPath(&fPath);
}
void SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
fPath.flatten(buffer);
buffer.writePath(fPath);
}
void SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {

View File

@ -38,17 +38,6 @@ static void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1,
}
}
///////////////////////////////////////////////////////////////////////////////
// Can't use a two-argument function with side effects like this in a
// constructor's initializer's argument list because the order of
// evaluations in that context is undefined (and backwards on linux/gcc).
static SkPoint unflatten_point(SkReader32& buffer) {
SkPoint retval;
retval.fX = buffer.readScalar();
retval.fY = buffer.readScalar();
return retval;
}
// Clamp
static SkFixed clamp_tileproc(SkFixed x) {
@ -371,7 +360,7 @@ Gradient_Shader::Gradient_Shader(SkFlattenableReadBuffer& buffer) :
recs[i].fScale = buffer.readU32();
}
}
SkReadMatrix(&buffer, &fPtsToUnit);
buffer.readMatrix(&fPtsToUnit);
this->initCommon();
}
@ -408,7 +397,7 @@ void Gradient_Shader::flatten(SkFlattenableWriteBuffer& buffer) const {
buffer.write32(recs[i].fScale);
}
}
SkWriteMatrix(&buffer, fPtsToUnit);
buffer.writeMatrix(fPtsToUnit);
}
bool Gradient_Shader::isOpaque() const {
@ -813,15 +802,13 @@ public:
protected:
Linear_Gradient(SkFlattenableReadBuffer& buffer)
: INHERITED(buffer),
fStart(unflatten_point(buffer)),
fEnd(unflatten_point(buffer)) {
fStart(buffer.readPoint()),
fEnd(buffer.readPoint()) {
}
virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
this->INHERITED::flatten(buffer);
buffer.writeScalar(fStart.fX);
buffer.writeScalar(fStart.fY);
buffer.writeScalar(fEnd.fX);
buffer.writeScalar(fEnd.fY);
buffer.writePoint(fStart);
buffer.writePoint(fEnd);
}
private:
@ -1470,13 +1457,12 @@ public:
protected:
Radial_Gradient(SkFlattenableReadBuffer& buffer)
: INHERITED(buffer),
fCenter(unflatten_point(buffer)),
fCenter(buffer.readPoint()),
fRadius(buffer.readScalar()) {
}
virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
this->INHERITED::flatten(buffer);
buffer.writeScalar(fCenter.fX);
buffer.writeScalar(fCenter.fY);
buffer.writePoint(fCenter);
buffer.writeScalar(fRadius);
}
@ -2001,8 +1987,8 @@ public:
protected:
Two_Point_Radial_Gradient(SkFlattenableReadBuffer& buffer)
: INHERITED(buffer),
fCenter1(unflatten_point(buffer)),
fCenter2(unflatten_point(buffer)),
fCenter1(buffer.readPoint()),
fCenter2(buffer.readPoint()),
fRadius1(buffer.readScalar()),
fRadius2(buffer.readScalar()) {
init();
@ -2010,10 +1996,8 @@ protected:
virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
this->INHERITED::flatten(buffer);
buffer.writeScalar(fCenter1.fX);
buffer.writeScalar(fCenter1.fY);
buffer.writeScalar(fCenter2.fX);
buffer.writeScalar(fCenter2.fY);
buffer.writePoint(fCenter1);
buffer.writePoint(fCenter2);
buffer.writeScalar(fRadius1);
buffer.writeScalar(fRadius2);
}
@ -2087,12 +2071,11 @@ public:
protected:
Sweep_Gradient(SkFlattenableReadBuffer& buffer)
: INHERITED(buffer),
fCenter(unflatten_point(buffer)) {
fCenter(buffer.readPoint()) {
}
virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
this->INHERITED::flatten(buffer);
buffer.writeScalar(fCenter.fX);
buffer.writeScalar(fCenter.fY);
buffer.writePoint(fCenter);
}
private:

View File

@ -18,6 +18,7 @@
#include "SkColorFilter.h"
#include "SkDrawLooper.h"
#include "SkMaskFilter.h"
#include "SkOrderedReadBuffer.h"
#include "SkPathEffect.h"
#include "SkRasterizer.h"
#include "SkShader.h"
@ -131,7 +132,7 @@ static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
SkGPipeState* state) {
SkRegion rgn;
SkReadRegion(reader, &rgn);
reader->readRegion(&rgn);
canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
}
@ -145,14 +146,14 @@ static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
SkGPipeState* state) {
SkMatrix matrix;
SkReadMatrix(reader, &matrix);
reader->readMatrix(&matrix);
canvas->setMatrix(matrix);
}
static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
SkGPipeState* state) {
SkMatrix matrix;
SkReadMatrix(reader, &matrix);
reader->readMatrix(&matrix);
canvas->concat(matrix);
}
@ -315,7 +316,7 @@ static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op3
SkMatrix matrixStorage;
const SkMatrix* matrix = NULL;
if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
SkReadMatrix(reader, &matrixStorage);
reader->readMatrix(&matrixStorage);
matrix = &matrixStorage;
}
@ -508,7 +509,7 @@ SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
const ReadProc* table = gReadTable;
SkFlattenableReadBuffer reader(data, length);
SkOrderedReadBuffer reader(data, length);
SkCanvas* canvas = fCanvas;
Status status = kEOF_Status;
@ -527,7 +528,7 @@ SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
status = kDone_Status;
break;
}
table[op](canvas, &reader, op32, fState);
table[op](canvas, reader.getReader32(), op32, fState);
if (readAtom &&
(table[op] != paintOp_rp &&
table[op] != def_Typeface_rp &&

View File

@ -23,6 +23,7 @@
#include "SkMaskFilter.h"
#include "SkRasterizer.h"
#include "SkShader.h"
#include "SkOrderedWriteBuffer.h"
static SkFlattenable* get_paintflat(const SkPaint& paint, unsigned paintFlat) {
SkASSERT(paintFlat < kCount_PaintFlats);
@ -194,7 +195,7 @@ int SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) {
return 0;
}
SkFlattenableWriteBuffer tmpWriter(1024);
SkOrderedWriteBuffer tmpWriter(1024);
tmpWriter.setFlags(SkFlattenableWriteBuffer::kInlineFactoryNames_Flag);
tmpWriter.setFactoryRecorder(fFactorySet);
@ -388,7 +389,7 @@ bool SkGPipeCanvas::concat(const SkMatrix& matrix) {
NOTIFY_SETUP(this);
if (this->needOpBytes(matrix.flatten(NULL))) {
this->writeOp(kConcat_DrawOp);
SkWriteMatrix(&fWriter, matrix);
fWriter.writeMatrix(matrix);
}
}
return this->INHERITED::concat(matrix);
@ -398,7 +399,7 @@ void SkGPipeCanvas::setMatrix(const SkMatrix& matrix) {
NOTIFY_SETUP(this);
if (this->needOpBytes(matrix.flatten(NULL))) {
this->writeOp(kSetMatrix_DrawOp);
SkWriteMatrix(&fWriter, matrix);
fWriter.writeMatrix(matrix);
}
this->INHERITED::setMatrix(matrix);
}
@ -426,7 +427,7 @@ bool SkGPipeCanvas::clipRegion(const SkRegion& region, SkRegion::Op rgnOp) {
NOTIFY_SETUP(this);
if (this->needOpBytes(region.flatten(NULL))) {
this->writeOp(kClipRegion_DrawOp, 0, rgnOp);
SkWriteRegion(&fWriter, region);
fWriter.writeRegion(region);
}
return this->INHERITED::clipRegion(region, rgnOp);
}
@ -575,7 +576,7 @@ void SkGPipeCanvas::drawTextOnPath(const void* text, size_t byteLength,
path.flatten(fWriter);
if (matrix) {
SkWriteMatrix(&fWriter, *matrix);
fWriter.writeMatrix(*matrix);
}
}
}

View File

@ -10,9 +10,11 @@
#include "SkColorFilter.h"
#include "SkRandom.h"
#include "SkXfermode.h"
#include "SkOrderedReadBuffer.h"
#include "SkOrderedWriteBuffer.h"
static SkFlattenable* reincarnate_flattenable(SkFlattenable* obj) {
SkFlattenableWriteBuffer wb(1024);
SkOrderedWriteBuffer wb(1024);
wb.writeFlattenable(obj);
size_t size = wb.size();
@ -20,7 +22,7 @@ static SkFlattenable* reincarnate_flattenable(SkFlattenable* obj) {
// make a copy into storage
wb.flatten(storage.get());
SkFlattenableReadBuffer rb(storage.get(), size);
SkOrderedReadBuffer rb(storage.get(), size);
return rb.readFlattenable();
}