Add option in flattening to write factory names inline, as we are recording.
SkGPipe needs this, since it cannot (unlike SkPicture) see all of the factories before it hands its data to the reader. In this mode, the writer embedds the factory name the first time it sees it, and then after that writes an index (referencing the fFactorySet). The reader installs an empty array, and as it encounters names, appends them to that array so that subsequent indices can be used to retrieve the previously named factory. Some of the existing patheffects did not register their factory names, so those changes are also part of this CL. Annoyingly, to register your factory using the current scheme, it has to be in the public section of the class definition. git-svn-id: http://skia.googlecode.com/svn/trunk@1663 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
25fb21f5df
commit
6bac947cd5
@ -100,11 +100,27 @@ public:
|
||||
fTFArray = array;
|
||||
fTFCount = count;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call this with a pre-loaded array of Factories, in the same order as
|
||||
* were created/written by the writer. SkPicture uses this.
|
||||
*/
|
||||
void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
|
||||
fFactoryTDArray = NULL;
|
||||
fFactoryArray = array;
|
||||
fFactoryCount = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this with an initially empty array, so the reader can cache each
|
||||
* factory it sees by name. Used by the pipe code in conjunction with
|
||||
* the writer's kInlineFactoryNames_Flag.
|
||||
*/
|
||||
void setFactoryArray(SkTDArray<SkFlattenable::Factory>* array) {
|
||||
fFactoryTDArray = array;
|
||||
fFactoryArray = NULL;
|
||||
fFactoryCount = 0;
|
||||
}
|
||||
|
||||
SkTypeface* readTypeface();
|
||||
SkRefCnt* readRefCnt();
|
||||
@ -118,6 +134,7 @@ private:
|
||||
SkTypeface** fTFArray;
|
||||
int fTFCount;
|
||||
|
||||
SkTDArray<SkFlattenable::Factory>* fFactoryTDArray;
|
||||
SkFlattenable::Factory* fFactoryArray;
|
||||
int fFactoryCount;
|
||||
|
||||
@ -165,12 +182,22 @@ public:
|
||||
SkFactorySet* setFactoryRecorder(SkFactorySet*);
|
||||
|
||||
enum Flags {
|
||||
kCrossProcess_Flag = 0x01
|
||||
kCrossProcess_Flag = 0x01,
|
||||
/**
|
||||
* Instructs the writer to inline Factory names as there are seen the
|
||||
* first time (after that we store an index). The pipe code uses this.
|
||||
*/
|
||||
kInlineFactoryNames_Flag = 0x02,
|
||||
};
|
||||
Flags getFlags() const { return fFlags; }
|
||||
Flags getFlags() const { return (Flags)fFlags; }
|
||||
void setFlags(Flags flags) { fFlags = flags; }
|
||||
|
||||
bool isCrossProcess() const { return (fFlags & kCrossProcess_Flag) != 0; }
|
||||
bool isCrossProcess() const {
|
||||
return SkToBool(fFlags & kCrossProcess_Flag);
|
||||
}
|
||||
bool inlineFactoryNames() const {
|
||||
return SkToBool(fFlags & kInlineFactoryNames_Flag);
|
||||
}
|
||||
|
||||
bool persistBitmapPixels() const {
|
||||
return (fFlags & kCrossProcess_Flag) != 0;
|
||||
@ -179,10 +206,10 @@ public:
|
||||
bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
|
||||
|
||||
private:
|
||||
Flags fFlags;
|
||||
SkRefCntSet* fTFSet;
|
||||
SkRefCntSet* fRCSet;
|
||||
SkFactorySet* fFactorySet;
|
||||
uint32_t fFlags;
|
||||
SkRefCntSet* fTFSet;
|
||||
SkRefCntSet* fRCSet;
|
||||
SkFactorySet* fFactorySet;
|
||||
|
||||
typedef SkWriter32 INHERITED;
|
||||
};
|
||||
|
@ -876,7 +876,7 @@ private:
|
||||
friend class SkTextToPathIter;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
|
||||
@ -894,20 +894,18 @@ public:
|
||||
SkPaint::Cap, SkScalar miterLimit = -1);
|
||||
|
||||
// overrides
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides for SkFlattenable
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
private:
|
||||
SkScalar fWidth, fMiter;
|
||||
uint8_t fStyle, fJoin, fCap;
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
SkStrokePathEffect(SkFlattenableReadBuffer&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
|
@ -31,7 +31,6 @@ class SkPath;
|
||||
*/
|
||||
class SK_API SkPathEffect : public SkFlattenable {
|
||||
public:
|
||||
// This method is not exported to java.
|
||||
SkPathEffect() {}
|
||||
|
||||
/** Given a src path and a width value, return true if the patheffect
|
||||
@ -86,16 +85,16 @@ public:
|
||||
|
||||
// overrides
|
||||
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkComposePathEffect, (buffer));
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
private:
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkComposePathEffect, (buffer));
|
||||
}
|
||||
SkComposePathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
// illegal
|
||||
@ -121,16 +120,16 @@ public:
|
||||
: INHERITED(first, second) {}
|
||||
|
||||
// overrides
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkSumPathEffect, (buffer));
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
private:
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkSumPathEffect, (buffer));
|
||||
}
|
||||
SkSumPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
// illegal
|
||||
|
@ -89,10 +89,13 @@ private:
|
||||
*/
|
||||
template <typename T> class SkTPtrSet : public SkPtrSet {
|
||||
public:
|
||||
uint32_t find(T ptr) {
|
||||
return this->INHERITED::find((void*)ptr);
|
||||
}
|
||||
uint32_t add(T ptr) {
|
||||
return this->INHERITED::add((void*)ptr);
|
||||
}
|
||||
|
||||
|
||||
void copyToArray(T* array) const {
|
||||
this->INHERITED::copyToArray((void**)array);
|
||||
}
|
||||
|
@ -42,17 +42,13 @@ public:
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
protected:
|
||||
SkCornerPathEffect(SkFlattenableReadBuffer&);
|
||||
|
||||
private:
|
||||
SkScalar fRadius;
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
// illegal
|
||||
SkCornerPathEffect(const SkCornerPathEffect&);
|
||||
SkCornerPathEffect& operator=(const SkCornerPathEffect&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
@ -44,6 +44,8 @@ public:
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
protected:
|
||||
SkDashPathEffect(SkFlattenableReadBuffer&);
|
||||
|
||||
@ -56,8 +58,6 @@ private:
|
||||
SkScalar fIntervalLength;
|
||||
bool fScaleToFit;
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
|
@ -41,13 +41,13 @@ public:
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
protected:
|
||||
SkDiscretePathEffect(SkFlattenableReadBuffer&);
|
||||
|
||||
private:
|
||||
SkScalar fSegLength, fPerterb;
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
@ -48,6 +48,7 @@ SkFlattenableReadBuffer::SkFlattenableReadBuffer() {
|
||||
fTFArray = NULL;
|
||||
fTFCount = 0;
|
||||
|
||||
fFactoryTDArray = NULL;
|
||||
fFactoryArray = NULL;
|
||||
fFactoryCount = 0;
|
||||
}
|
||||
@ -60,6 +61,7 @@ SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data) :
|
||||
fTFArray = NULL;
|
||||
fTFCount = 0;
|
||||
|
||||
fFactoryTDArray = NULL;
|
||||
fFactoryArray = NULL;
|
||||
fFactoryCount = 0;
|
||||
}
|
||||
@ -72,6 +74,7 @@ SkFlattenableReadBuffer::SkFlattenableReadBuffer(const void* data, size_t size)
|
||||
fTFArray = NULL;
|
||||
fTFCount = 0;
|
||||
|
||||
fFactoryTDArray = NULL;
|
||||
fFactoryArray = NULL;
|
||||
fFactoryCount = 0;
|
||||
}
|
||||
@ -103,26 +106,48 @@ SkFlattenable* SkFlattenableReadBuffer::readFlattenable() {
|
||||
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
|
||||
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 < (unsigned)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 sizeRecorded = this->readU32();
|
||||
uint32_t offset = this->offset();
|
||||
obj = (*factory)(*this);
|
||||
// check that we read the amount we expected
|
||||
@ -131,6 +156,9 @@ SkFlattenable* SkFlattenableReadBuffer::readFlattenable() {
|
||||
// we could try to fix up the offset...
|
||||
sk_throw();
|
||||
}
|
||||
} else {
|
||||
// we must skip the remaining data
|
||||
this->skip(sizeRecorded);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
@ -189,28 +217,78 @@ 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) {
|
||||
this->write32(fFactorySet->add(factory));
|
||||
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(-fFactorySet->add(factory));
|
||||
}
|
||||
} else {
|
||||
this->writeFunctionPtr((void*)factory);
|
||||
}
|
||||
|
||||
if (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
|
||||
flattenable->flatten(*this);
|
||||
uint32_t objSize = this->size() - offset;
|
||||
// record the obj's size
|
||||
*this->peek32(offset - sizeof(uint32_t)) = objSize;
|
||||
}
|
||||
// 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) {
|
||||
|
@ -30,8 +30,8 @@ SkPairPathEffect::SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1)
|
||||
}
|
||||
|
||||
SkPairPathEffect::~SkPairPathEffect() {
|
||||
fPE0->unref();
|
||||
fPE1->unref();
|
||||
SkSafeUnref(fPE0);
|
||||
SkSafeUnref(fPE1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -45,12 +45,18 @@ void SkPairPathEffect::flatten(SkFlattenableWriteBuffer& buffer) {
|
||||
SkPairPathEffect::SkPairPathEffect(SkFlattenableReadBuffer& buffer) {
|
||||
fPE0 = (SkPathEffect*)buffer.readFlattenable();
|
||||
fPE1 = (SkPathEffect*)buffer.readFlattenable();
|
||||
// either of these may fail, so we have to check for nulls later on
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SkComposePathEffect::filterPath(SkPath* dst, const SkPath& src,
|
||||
SkScalar* width) {
|
||||
// we may have failed to unflatten these, so we have to check
|
||||
if (!fPE0 || !fPE1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkPath tmp;
|
||||
const SkPath* ptr = &src;
|
||||
|
||||
@ -134,3 +140,14 @@ SkStrokePathEffect::SkStrokePathEffect(SkFlattenableReadBuffer& buffer) {
|
||||
fCap = buffer.readU8();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkFlattenable::Registrar gComposePathEffectReg("SkComposePathEffect",
|
||||
SkComposePathEffect::CreateProc);
|
||||
|
||||
static SkFlattenable::Registrar gSumPathEffectReg("SkSumPathEffect",
|
||||
SkSumPathEffect::CreateProc);
|
||||
|
||||
static SkFlattenable::Registrar gStrokePathEffectReg("SkStrokePathEffect",
|
||||
SkStrokePathEffect::CreateProc);
|
||||
|
||||
|
@ -195,8 +195,6 @@ bool SkWriter32::writeToStream(SkWStream* stream) {
|
||||
*/
|
||||
|
||||
const char* SkReader32::readString(size_t* outLen) {
|
||||
// we need to read at least 1-4 bytes
|
||||
SkASSERT(this->isAvailable(4));
|
||||
size_t len = this->readInt();
|
||||
const void* ptr = this->peek();
|
||||
|
||||
|
@ -38,7 +38,9 @@ SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
|
||||
}
|
||||
}
|
||||
|
||||
SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer) {
|
||||
SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
|
||||
: INHERITED(buffer) {
|
||||
|
||||
fDx = buffer.readScalar();
|
||||
fDy = buffer.readScalar();
|
||||
fBlurColor = buffer.readU32();
|
||||
|
@ -153,3 +153,8 @@ SkCornerPathEffect::SkCornerPathEffect(SkFlattenableReadBuffer& buffer) {
|
||||
fRadius = buffer.readScalar();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkFlattenable::Registrar gReg("SkCornerPathEffect",
|
||||
SkCornerPathEffect::CreateProc);
|
||||
|
||||
|
@ -168,4 +168,8 @@ SkDashPathEffect::SkDashPathEffect(SkFlattenableReadBuffer& buffer) {
|
||||
buffer.read(fIntervals, fCount * sizeof(fIntervals[0]));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkFlattenable::Registrar gReg("SkDashPathEffect",
|
||||
SkDashPathEffect::CreateProc);
|
||||
|
||||
|
@ -93,3 +93,8 @@ SkDiscretePathEffect::SkDiscretePathEffect(SkFlattenableReadBuffer& buffer) {
|
||||
fPerterb = buffer.readScalar();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkFlattenable::Registrar gReg("SkDiscretePathEffect",
|
||||
SkDiscretePathEffect::CreateProc);
|
||||
|
||||
|
@ -75,8 +75,6 @@ enum DrawOps {
|
||||
kDef_Typeface_DrawOp,
|
||||
kDef_Flattenable_DrawOp,
|
||||
|
||||
kName_Flattenable_DrawOp, // index <--> name
|
||||
|
||||
// these are signals to playback, not drawing verbs
|
||||
kDone_DrawOp,
|
||||
};
|
||||
|
@ -72,7 +72,7 @@ public:
|
||||
|
||||
void setReader(SkFlattenableReadBuffer* reader) {
|
||||
fReader = reader;
|
||||
fReader->setFactoryPlayback(fFactoryArray.begin(), fFactoryArray.count());
|
||||
fReader->setFactoryArray(&fFactoryArray);
|
||||
}
|
||||
|
||||
const SkPaint& paint() const { return fPaint; }
|
||||
@ -91,16 +91,6 @@ public:
|
||||
*fFlatArray.append() = obj;
|
||||
}
|
||||
|
||||
void nameFlattenable(PaintFlats pf, unsigned index) {
|
||||
SkASSERT(index == fFactoryArray.count() + 1);
|
||||
const char* name = fReader->readString();
|
||||
SkFlattenable::Factory fact = SkFlattenable::NameToFactory(name);
|
||||
*fFactoryArray.append() = fact;
|
||||
|
||||
// update this each time we grow the array
|
||||
fReader->setFactoryPlayback(fFactoryArray.begin(), fFactoryArray.count());
|
||||
}
|
||||
|
||||
void addTypeface() {
|
||||
size_t size = fReader->readU32();
|
||||
const void* data = fReader->skip(SkAlign4(size));
|
||||
@ -444,13 +434,6 @@ static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
|
||||
state->defFlattenable(pf, index);
|
||||
}
|
||||
|
||||
static void name_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
|
||||
unsigned index = DrawOp_unpackData(op32);
|
||||
state->nameFlattenable(pf, index);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
|
||||
@ -497,7 +480,6 @@ static const ReadProc gReadTable[] = {
|
||||
paintOp_rp,
|
||||
def_Typeface_rp,
|
||||
def_PaintFlat_rp,
|
||||
name_PaintFlat_rp,
|
||||
|
||||
done_rp
|
||||
};
|
||||
@ -507,8 +489,8 @@ static const ReadProc gReadTable[] = {
|
||||
SkGPipeState::SkGPipeState() {}
|
||||
|
||||
SkGPipeState::~SkGPipeState() {
|
||||
fTypefaces.unrefAll();
|
||||
fFlatArray.unrefAll();
|
||||
fTypefaces.safeUnrefAll();
|
||||
fFlatArray.safeUnrefAll();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -562,8 +544,7 @@ SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
|
||||
if (readAtom &&
|
||||
(table[op] != paintOp_rp &&
|
||||
table[op] != def_Typeface_rp &&
|
||||
table[op] != def_PaintFlat_rp &&
|
||||
table[op] != name_PaintFlat_rp
|
||||
table[op] != def_PaintFlat_rp
|
||||
)) {
|
||||
status = kReadAtom_Status;
|
||||
break;
|
||||
|
@ -197,31 +197,9 @@ int SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) {
|
||||
if (NULL == obj) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SkFlattenable::Factory fact = obj->getFactory();
|
||||
if (NULL == fact) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fFactorySet) {
|
||||
uint32_t id = fFactorySet->find((void*)fact);
|
||||
if (0 == id) {
|
||||
const char* name = SkFlattenable::FactoryToName(fact);
|
||||
if (NULL == name) {
|
||||
return 0;
|
||||
}
|
||||
size_t len = strlen(name);
|
||||
size_t size = SkWriter32::WriteStringSize(name, len);
|
||||
if (!this->needOpBytes(size)) {
|
||||
return 0;
|
||||
}
|
||||
unsigned id = fFactorySet->add(fact);
|
||||
this->writeOp(kName_Flattenable_DrawOp, paintflat, id);
|
||||
fWriter.writeString(name, len);
|
||||
}
|
||||
}
|
||||
|
||||
SkFlattenableWriteBuffer tmpWriter(1024);
|
||||
tmpWriter.setFlags(SkFlattenableWriteBuffer::kInlineFactoryNames_Flag);
|
||||
tmpWriter.setFactoryRecorder(fFactorySet);
|
||||
|
||||
tmpWriter.writeFlattenable(obj);
|
||||
|
Loading…
Reference in New Issue
Block a user