Refactor dictionaries for use by entities other than just SkPicture

Review URL: https://codereview.appspot.com/6101043

git-svn-id: http://skia.googlecode.com/svn/trunk@4077 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
djsollen@google.com 2012-05-30 16:54:13 +00:00
parent dde718c558
commit d2700eec7e
9 changed files with 246 additions and 465 deletions

View File

@ -22,6 +22,8 @@ public:
size_t storageSize);
virtual ~SkOrderedWriteBuffer() {}
SkWriter32* getWriter32() { return &fWriter; }
// 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); }

View File

@ -14,216 +14,7 @@
#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));
result->fIndex = index;
result->fAllocSize = size + sizeof(result->fAllocSize);
return result;
}
SkFlatBitmap* SkFlatBitmap::Flatten(SkChunkAlloc* heap, const SkBitmap& bitmap,
int index, SkRefCntSet* rec) {
SkOrderedWriteBuffer buffer(1024);
buffer.setRefCntRecorder(rec);
bitmap.flatten(buffer);
size_t size = buffer.size();
SkFlatBitmap* result = (SkFlatBitmap*) INHERITED::Alloc(heap, size, index);
buffer.flatten(result->fBitmapData);
return result;
}
SkFlatMatrix* SkFlatMatrix::Flatten(SkChunkAlloc* heap, const SkMatrix& matrix, int index) {
size_t size = matrix.flatten(NULL);
SkFlatMatrix* result = (SkFlatMatrix*) INHERITED::Alloc(heap, size, index);
matrix.flatten(&result->fMatrixData);
return result;
}
#ifdef SK_DEBUG_DUMP
void SkFlatMatrix::dump() const {
const SkMatrix* matrix = (const SkMatrix*) fMatrixData;
char pBuffer[DUMP_BUFFER_SIZE];
char* bufferPtr = pBuffer;
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"matrix: ");
SkScalar scaleX = matrix->getScaleX();
SkMatrix defaultMatrix;
defaultMatrix.reset();
if (scaleX != defaultMatrix.getScaleX())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"scaleX:%g ", SkScalarToFloat(scaleX));
SkScalar scaleY = matrix->getScaleY();
if (scaleY != defaultMatrix.getScaleY())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"scaleY:%g ", SkScalarToFloat(scaleY));
SkScalar skewX = matrix->getSkewX();
if (skewX != defaultMatrix.getSkewX())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"skewX:%g ", SkScalarToFloat(skewX));
SkScalar skewY = matrix->getSkewY();
if (skewY != defaultMatrix.getSkewY())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"skewY:%g ", SkScalarToFloat(skewY));
SkScalar translateX = matrix->getTranslateX();
if (translateX != defaultMatrix.getTranslateX())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"translateX:%g ", SkScalarToFloat(translateX));
SkScalar translateY = matrix->getTranslateY();
if (translateY != defaultMatrix.getTranslateY())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"translateY:%g ", SkScalarToFloat(translateY));
SkScalar perspX = matrix->getPerspX();
if (perspX != defaultMatrix.getPerspX())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"perspX:%g ", SkFractToFloat(perspX));
SkScalar perspY = matrix->getPerspY();
if (perspY != defaultMatrix.getPerspY())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"perspY:%g ", SkFractToFloat(perspY));
SkDebugf("%s\n", pBuffer);
}
#endif
///////////////////////////////////////////////////////////////////////////////
SkFlatPaint* SkFlatPaint::Flatten(SkChunkAlloc* heap, const SkPaint& paint,
int index, SkRefCntSet* rec,
SkRefCntSet* faceRecorder) {
intptr_t storage[256];
SkOrderedWriteBuffer buffer(4*sizeof(SkPaint), storage, sizeof(storage));
buffer.setRefCntRecorder(rec);
buffer.setTypefaceRecorder(faceRecorder);
paint.flatten(buffer);
uint32_t size = buffer.size();
SkFlatPaint* result = (SkFlatPaint*) INHERITED::Alloc(heap, size, index);
buffer.flatten(&result->fPaintData);
return result;
}
void SkFlatPaint::Read(const void* storage, SkPaint* paint,
SkRefCntPlayback* rcp, SkTypefacePlayback* facePlayback) {
SkOrderedReadBuffer buffer(storage, 1024*1024);
if (rcp) {
rcp->setupBuffer(buffer);
}
if (facePlayback) {
facePlayback->setupBuffer(buffer);
}
paint->unflatten(buffer);
}
#ifdef SK_DEBUG_DUMP
void SkFlatPaint::dump() const {
SkPaint defaultPaint;
SkFlattenableReadBuffer buffer(fPaintData);
SkTypeface* typeface = (SkTypeface*) buffer.readPtr();
char pBuffer[DUMP_BUFFER_SIZE];
char* bufferPtr = pBuffer;
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"paint: ");
if (typeface != defaultPaint.getTypeface())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"typeface:%p ", typeface);
SkScalar textSize = buffer.readScalar();
if (textSize != defaultPaint.getTextSize())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"textSize:%g ", SkScalarToFloat(textSize));
SkScalar textScaleX = buffer.readScalar();
if (textScaleX != defaultPaint.getTextScaleX())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"textScaleX:%g ", SkScalarToFloat(textScaleX));
SkScalar textSkewX = buffer.readScalar();
if (textSkewX != defaultPaint.getTextSkewX())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"textSkewX:%g ", SkScalarToFloat(textSkewX));
const SkPathEffect* pathEffect = (const SkPathEffect*) buffer.readFlattenable();
if (pathEffect != defaultPaint.getPathEffect())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"pathEffect:%p ", pathEffect);
SkDELETE(pathEffect);
const SkShader* shader = (const SkShader*) buffer.readFlattenable();
if (shader != defaultPaint.getShader())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"shader:%p ", shader);
SkDELETE(shader);
const SkXfermode* xfermode = (const SkXfermode*) buffer.readFlattenable();
if (xfermode != defaultPaint.getXfermode())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"xfermode:%p ", xfermode);
SkDELETE(xfermode);
const SkMaskFilter* maskFilter = (const SkMaskFilter*) buffer.readFlattenable();
if (maskFilter != defaultPaint.getMaskFilter())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"maskFilter:%p ", maskFilter);
SkDELETE(maskFilter);
const SkColorFilter* colorFilter = (const SkColorFilter*) buffer.readFlattenable();
if (colorFilter != defaultPaint.getColorFilter())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"colorFilter:%p ", colorFilter);
SkDELETE(colorFilter);
const SkRasterizer* rasterizer = (const SkRasterizer*) buffer.readFlattenable();
if (rasterizer != defaultPaint.getRasterizer())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"rasterizer:%p ", rasterizer);
SkDELETE(rasterizer);
const SkDrawLooper* drawLooper = (const SkDrawLooper*) buffer.readFlattenable();
if (drawLooper != defaultPaint.getLooper())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"drawLooper:%p ", drawLooper);
SkDELETE(drawLooper);
unsigned color = buffer.readU32();
if (color != defaultPaint.getColor())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"color:0x%x ", color);
SkScalar strokeWidth = buffer.readScalar();
if (strokeWidth != defaultPaint.getStrokeWidth())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"strokeWidth:%g ", SkScalarToFloat(strokeWidth));
SkScalar strokeMiter = buffer.readScalar();
if (strokeMiter != defaultPaint.getStrokeMiter())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"strokeMiter:%g ", SkScalarToFloat(strokeMiter));
unsigned flags = buffer.readU16();
if (flags != defaultPaint.getFlags())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"flags:0x%x ", flags);
int align = buffer.readU8();
if (align != defaultPaint.getTextAlign())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"align:0x%x ", align);
int strokeCap = buffer.readU8();
if (strokeCap != defaultPaint.getStrokeCap())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"strokeCap:0x%x ", strokeCap);
int strokeJoin = buffer.readU8();
if (strokeJoin != defaultPaint.getStrokeJoin())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"align:0x%x ", strokeJoin);
int style = buffer.readU8();
if (style != defaultPaint.getStyle())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"style:0x%x ", style);
int textEncoding = buffer.readU8();
if (textEncoding != defaultPaint.getTextEncoding())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"textEncoding:0x%x ", textEncoding);
SkDebugf("%s\n", pBuffer);
}
#endif
SkFlatRegion* SkFlatRegion::Flatten(SkChunkAlloc* heap, const SkRegion& region, int index) {
uint32_t size = region.flatten(NULL);
SkFlatRegion* result = (SkFlatRegion*) INHERITED::Alloc(heap, size, index);
region.flatten(&result->fRegionData);
return result;
}
///////////////////////////////////////////////////////////////////////////////
SkRefCntPlayback::SkRefCntPlayback() : fCount(0), fArray(NULL) {}
@ -266,3 +57,49 @@ SkRefCnt* SkRefCntPlayback::set(int index, SkRefCnt* obj) {
return obj;
}
///////////////////////////////////////////////////////////////////////////////
SkFlatData* SkFlatData::Create(SkChunkAlloc* heap, const void* obj,
int index, void (*flattenProc)(SkOrderedWriteBuffer&, const void*),
SkRefCntSet* refCntRecorder, SkRefCntSet* faceRecorder) {
// a buffer of 256 bytes should be sufficient for most paints, regions,
// and matrices.
intptr_t storage[256];
SkOrderedWriteBuffer buffer(256, storage, sizeof(storage));
if (refCntRecorder) {
buffer.setRefCntRecorder(refCntRecorder);
}
if (faceRecorder) {
buffer.setTypefaceRecorder(faceRecorder);
}
flattenProc(buffer, obj);
uint32_t size = buffer.size();
// allocate the enough memory to hold both SkFlatData and the serialized
// contents
SkFlatData* result = (SkFlatData*) heap->allocThrow(size + sizeof(SkFlatData));
result->fIndex = index;
result->fAllocSize = size;
// put the serialized contents into the data section of the new allocation
buffer.flatten(result->data());
return result;
}
void SkFlatData::unflatten(void* result,
void (*unflattenProc)(SkOrderedReadBuffer&, void*),
SkRefCntPlayback* refCntPlayback,
SkTypefacePlayback* facePlayback) const {
SkOrderedReadBuffer buffer(this->data(), fAllocSize);
if (refCntPlayback) {
refCntPlayback->setupBuffer(buffer);
}
if (facePlayback) {
facePlayback->setupBuffer(buffer);
}
unflattenProc(buffer, result);
SkASSERT(fAllocSize == (int32_t)buffer.offset());
}

View File

@ -11,11 +11,13 @@
#include "SkChunkAlloc.h"
#include "SkBitmap.h"
#include "SkOrderedReadBuffer.h"
#include "SkOrderedWriteBuffer.h"
#include "SkPicture.h"
#include "SkMatrix.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkTSearch.h"
enum DrawType {
UNUSED,
@ -127,112 +129,193 @@ private:
SkFlattenable::Factory* fArray;
};
///////////////////////////////////////////////////////////////////////////////
//
//
// The following templated classes provide an efficient way to store and compare
// objects that have been flattened (i.e. serialized in an ordered binary
// format).
//
// SkFlatData: is a simple indexable container for the flattened data
// which is agnostic to the type of data is is indexing. It is
// also responsible for flattening/unflattening objects but
// details of that operation are hidden in the provided procs
// SkFlatDictionary: is a abstract templated dictionary that maintains a
// searchable set of SkFlataData objects of type T.
//
// NOTE: any class that wishes to be used in conjunction with SkFlatDictionary
// must subclass the dictionary and provide the necessary flattening procs.
// The end of this header contains dictionary subclasses for some common classes
// like SkBitmap, SkMatrix, SkPaint, and SkRegion.
//
//
///////////////////////////////////////////////////////////////////////////////
class SkFlatData {
public:
static int Compare(const SkFlatData* a, const SkFlatData* b) {
return memcmp(&a->fAllocSize, &b->fAllocSize, a->fAllocSize);
return memcmp(a->data(), b->data(), a->fAllocSize);
}
int index() const { return fIndex; }
void* data() const { return (char*)this + sizeof(*this); }
#ifdef SK_DEBUG_SIZE
size_t size() const { return sizeof(fIndex) + fAllocSize; }
size_t size() const { return sizeof(SkFlatData) + fAllocSize; }
#endif
protected:
static SkFlatData* Alloc(SkChunkAlloc* heap, int32_t size, int index);
static SkFlatData* Create(SkChunkAlloc* heap, const void* obj, int index,
void (*flattenProc)(SkOrderedWriteBuffer&, const void*),
SkRefCntSet* refCntRecorder = NULL,
SkRefCntSet* faceRecorder = NULL);
void unflatten(void* result,
void (*unflattenProc)(SkOrderedReadBuffer&, void*),
SkRefCntPlayback* refCntPlayback = NULL,
SkTypefacePlayback* facePlayback = NULL) const;
private:
int fIndex;
int32_t fAllocSize;
};
class SkFlatBitmap : public SkFlatData {
template <class T>
class SkFlatDictionary {
public:
static SkFlatBitmap* Flatten(SkChunkAlloc*, const SkBitmap&, int index,
SkRefCntSet*);
SkFlatDictionary(SkChunkAlloc* heap) {
fFlattenProc = NULL;
fUnflattenProc = NULL;
fHeap = heap;
// set to 1 since returning a zero from find() indicates failure
fNextIndex = 1;
}
void unflatten(SkBitmap* bitmap, SkRefCntPlayback* rcp) const {
SkOrderedReadBuffer buffer(fBitmapData, fAllocSize);
if (rcp) {
rcp->setupBuffer(buffer);
int count() const { return fData.count(); }
const SkFlatData* operator[](int index) const {
SkASSERT(index >= 0 && index < fData.count());
return fData[index];
}
/**
* Clears the dictionary of all entries. However, it does NOT free the
* memory that was allocated for each entry.
*/
void reset() { fData.reset(); fNextIndex = 1; }
/**
* Given an element of type T it returns its index in the dictionary. If
* the element wasn't previously in the dictionary it is automatically added
*/
int find(const T* element, SkRefCntSet* refCntRecorder = NULL,
SkRefCntSet* faceRecorder = NULL) {
if (element == NULL)
return 0;
SkFlatData* flat = SkFlatData::Create(fHeap, element, fNextIndex,
fFlattenProc, refCntRecorder, faceRecorder);
int index = SkTSearch<SkFlatData>((const SkFlatData**) fData.begin(),
fData.count(), flat, sizeof(flat), &SkFlatData::Compare);
if (index >= 0) {
(void)fHeap->unalloc(flat);
return fData[index]->index();
}
bitmap->unflatten(buffer);
index = ~index;
*fData.insert(index) = flat;
SkASSERT(fData.count() == fNextIndex);
return fNextIndex++;
}
#ifdef SK_DEBUG_VALIDATE
void validate() const {
// to be written
/**
* Given a pointer to a array of type T we allocate the array and fill it
* with the unflattened dictionary contents. The return value is the size of
* the allocated array.
*/
int unflattenDictionary(T*& array, SkRefCntPlayback* refCntPlayback = NULL,
SkTypefacePlayback* facePlayback = NULL) const {
int elementCount = fData.count();
if (elementCount > 0) {
array = SkNEW_ARRAY(T, elementCount);
for (const SkFlatData** elementPtr = fData.begin();
elementPtr != fData.end(); elementPtr++) {
const SkFlatData* element = *elementPtr;
int index = element->index() - 1;
element->unflatten(&array[index], fUnflattenProc,
refCntPlayback, facePlayback);
}
}
return elementCount;
}
#endif
protected:
void (*fFlattenProc)(SkOrderedWriteBuffer&, const void*);
void (*fUnflattenProc)(SkOrderedReadBuffer&, void*);
private:
char fBitmapData[1];
typedef SkFlatData INHERITED;
SkChunkAlloc* fHeap;
int fNextIndex;
SkTDArray<const SkFlatData*> fData;
};
class SkFlatMatrix : public SkFlatData {
///////////////////////////////////////////////////////////////////////////////
// Some common dictionaries are defined here for both reference and convenience
///////////////////////////////////////////////////////////////////////////////
template <class T>
static void SkFlattenObjectProc(SkOrderedWriteBuffer& buffer, const void* obj) {
((T*)obj)->flatten(buffer);
}
template <class T>
static void SkUnflattenObjectProc(SkOrderedReadBuffer& buffer, void* obj) {
((T*)obj)->unflatten(buffer);
}
class SkBitmapDictionary : public SkFlatDictionary<SkBitmap> {
public:
static SkFlatMatrix* Flatten(SkChunkAlloc* heap, const SkMatrix& matrix, int index);
void unflatten(SkMatrix* result) const {
result->unflatten(fMatrixData);
SkBitmapDictionary(SkChunkAlloc* heap) : SkFlatDictionary<SkBitmap>(heap) {
fFlattenProc = &SkFlattenObjectProc<SkBitmap>;
fUnflattenProc = &SkUnflattenObjectProc<SkBitmap>;
}
#ifdef SK_DEBUG_DUMP
void dump() const;
#endif
#ifdef SK_DEBUG_VALIDATE
void validate() const {
// to be written
}
#endif
private:
char fMatrixData[1];
typedef SkFlatData INHERITED;
};
class SkFlatPaint : public SkFlatData {
public:
static SkFlatPaint* Flatten(SkChunkAlloc* heap, const SkPaint& paint,
int index, SkRefCntSet*,
SkRefCntSet* faceRecorder);
void unflatten(SkPaint* result, SkRefCntPlayback* rcp,
SkTypefacePlayback* facePlayback) const {
Read(fPaintData, result, rcp, facePlayback);
class SkMatrixDictionary : public SkFlatDictionary<SkMatrix> {
public:
SkMatrixDictionary(SkChunkAlloc* heap) : SkFlatDictionary<SkMatrix>(heap) {
fFlattenProc = &flattenMatrix;
fUnflattenProc = &unflattenMatrix;
}
static void Read(const void* storage, SkPaint* paint, SkRefCntPlayback*,
SkTypefacePlayback* facePlayback);
#ifdef SK_DEBUG_DUMP
void dump() const;
#endif
private:
char fPaintData[1];
typedef SkFlatData INHERITED;
static void flattenMatrix(SkOrderedWriteBuffer& buffer, const void* obj) {
buffer.getWriter32()->writeMatrix(*(SkMatrix*)obj);
}
static void unflattenMatrix(SkOrderedReadBuffer& buffer, void* obj) {
buffer.getReader32()->readMatrix((SkMatrix*)obj);
}
};
class SkFlatRegion : public SkFlatData {
public:
static SkFlatRegion* Flatten(SkChunkAlloc* heap, const SkRegion& region, int index);
void unflatten(SkRegion* result) const {
result->unflatten(fRegionData);
class SkPaintDictionary : public SkFlatDictionary<SkPaint> {
public:
SkPaintDictionary(SkChunkAlloc* heap) : SkFlatDictionary<SkPaint>(heap) {
fFlattenProc = &SkFlattenObjectProc<SkPaint>;
fUnflattenProc = &SkUnflattenObjectProc<SkPaint>;
}
};
class SkRegionDictionary : public SkFlatDictionary<SkRegion> {
public:
SkRegionDictionary(SkChunkAlloc* heap) : SkFlatDictionary<SkRegion>(heap) {
fFlattenProc = &flattenRegion;
fUnflattenProc = &unflattenRegion;
}
#ifdef SK_DEBUG_VALIDATE
void validate() const {
// to be written
static void flattenRegion(SkOrderedWriteBuffer& buffer, const void* obj) {
buffer.getWriter32()->writeRegion(*(SkRegion*)obj);
}
#endif
private:
char fRegionData[1];
typedef SkFlatData INHERITED;
static void unflattenRegion(SkOrderedReadBuffer& buffer, void* obj) {
buffer.getReader32()->readRegion((SkRegion*)obj);
}
};
#endif

View File

@ -77,41 +77,15 @@ SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record) {
fRCPlayback.reset(&record.fRCSet);
fTFPlayback.reset(&record.fTFSet);
const SkTDArray<const SkFlatBitmap* >& bitmaps = record.getBitmaps();
fBitmapCount = bitmaps.count();
if (fBitmapCount > 0) {
fBitmaps = SkNEW_ARRAY(SkBitmap, fBitmapCount);
for (const SkFlatBitmap** flatBitmapPtr = bitmaps.begin();
flatBitmapPtr != bitmaps.end(); flatBitmapPtr++) {
const SkFlatBitmap* flatBitmap = *flatBitmapPtr;
int index = flatBitmap->index() - 1;
flatBitmap->unflatten(&fBitmaps[index], &fRCPlayback);
}
}
fBitmapCount = record.getBitmaps().unflattenDictionary(fBitmaps, &fRCPlayback);
fMatrixCount = record.getMatrices().unflattenDictionary(fMatrices);
fPaintCount = record.getPaints().unflattenDictionary(fPaints, &fRCPlayback, &fTFPlayback);
fRegionCount = record.getRegions().unflattenDictionary(fRegions);
const SkTDArray<const SkFlatMatrix* >& matrices = record.getMatrices();
fMatrixCount = matrices.count();
if (fMatrixCount > 0) {
fMatrices = SkNEW_ARRAY(SkMatrix, fMatrixCount);
for (const SkFlatMatrix** matrixPtr = matrices.begin();
matrixPtr != matrices.end(); matrixPtr++) {
const SkFlatMatrix* flatMatrix = *matrixPtr;
flatMatrix->unflatten(&fMatrices[flatMatrix->index() - 1]);
}
}
const SkTDArray<const SkFlatPaint* >& paints = record.getPaints();
fPaintCount = paints.count();
if (fPaintCount > 0) {
fPaints = SkNEW_ARRAY(SkPaint, fPaintCount);
for (const SkFlatPaint** flatPaintPtr = paints.begin();
flatPaintPtr != paints.end(); flatPaintPtr++) {
const SkFlatPaint* flatPaint = *flatPaintPtr;
int index = flatPaint->index() - 1;
SkASSERT((unsigned)index < (unsigned)fPaintCount);
flatPaint->unflatten(&fPaints[index], &fRCPlayback, &fTFPlayback);
}
}
SkASSERT(fBitmapCount == record.getBitmaps().count());
SkASSERT(fMatrixCount == record.getMatrices().count());
SkASSERT(fPaintCount == record.getPaints().count());
SkASSERT(fRegionCount == record.getRegions().count());
fPathHeap = record.fPathHeap;
SkSafeRef(fPathHeap);
@ -126,17 +100,6 @@ SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record) {
}
}
const SkTDArray<const SkFlatRegion* >& regions = record.getRegions();
fRegionCount = regions.count();
if (fRegionCount > 0) {
fRegions = SkNEW_ARRAY(SkRegion, fRegionCount);
for (const SkFlatRegion** flatRegionPtr = regions.begin();
flatRegionPtr != regions.end(); flatRegionPtr++) {
const SkFlatRegion* flatRegion = *flatRegionPtr;
flatRegion->unflatten(&fRegions[flatRegion->index() - 1]);
}
}
#ifdef SK_DEBUG_SIZE
int overall = fPlayback->size(&overallBytes);
bitmaps = fPlayback->bitmaps(&bitmapBytes);
@ -349,11 +312,7 @@ void SkPicturePlayback::serialize(SkWStream* stream) const {
writeTagSize(buffer, PICT_REGION_TAG, fRegionCount);
for (i = 0; i < fRegionCount; i++) {
uint32_t size = fRegions[i].flatten(NULL);
buffer.write32(size);
SkAutoSMalloc<512> storage(size);
fRegions[i].flatten(storage.get());
buffer.writePad(storage.get(), size);
buffer.getWriter32()->writeRegion(fRegions[i]);
}
// now we can write to the stream again
@ -460,10 +419,7 @@ SkPicturePlayback::SkPicturePlayback(SkStream* stream) {
fRegionCount = readTagSize(buffer, PICT_REGION_TAG);
fRegions = SkNEW_ARRAY(SkRegion, fRegionCount);
for (i = 0; i < fRegionCount; i++) {
uint32_t bufferSize = buffer.readU32();
SkDEBUGCODE(uint32_t bytes =)
fRegions[i].unflatten(buffer.skip(bufferSize));
SkASSERT(bufferSize == bytes);
buffer.getReader32()->readRegion(&fRegions[i]);
}
}

View File

@ -12,8 +12,13 @@
#define HEAP_BLOCK_SIZE 4096
SkPictureRecord::SkPictureRecord(uint32_t flags) :
fHeap(HEAP_BLOCK_SIZE), fWriter(MIN_WRITER_SIZE), fRecordFlags(flags) {
fBitmapIndex = fMatrixIndex = fPaintIndex = fRegionIndex = 1;
fHeap(HEAP_BLOCK_SIZE),
fBitmaps(&fHeap),
fMatrices(&fHeap),
fPaints(&fHeap),
fRegions(&fHeap),
fWriter(MIN_WRITER_SIZE),
fRecordFlags(flags) {
#ifdef SK_DEBUG_SIZE
fPointBytes = fRectBytes = fTextBytes = 0;
fPointWrites = fRectWrites = fTextWrites = 0;
@ -505,7 +510,7 @@ void SkPictureRecord::reset() {
}
void SkPictureRecord::addBitmap(const SkBitmap& bitmap) {
addInt(find(fBitmaps, bitmap));
addInt(fBitmaps.find(&bitmap, &fRCSet));
}
void SkPictureRecord::addMatrix(const SkMatrix& matrix) {
@ -513,7 +518,7 @@ void SkPictureRecord::addMatrix(const SkMatrix& matrix) {
}
void SkPictureRecord::addMatrixPtr(const SkMatrix* matrix) {
addInt(find(fMatrices, matrix));
addInt(fMatrices.find(matrix));
}
void SkPictureRecord::addPaint(const SkPaint& paint) {
@ -521,7 +526,7 @@ void SkPictureRecord::addPaint(const SkPaint& paint) {
}
void SkPictureRecord::addPaintPtr(const SkPaint* paint) {
addInt(find(fPaints, paint));
addInt(fPaints.find(paint, &fRCSet, &fTFSet));
}
void SkPictureRecord::addPath(const SkPath& path) {
@ -589,7 +594,7 @@ void SkPictureRecord::addIRectPtr(const SkIRect* rect) {
}
void SkPictureRecord::addRegion(const SkRegion& region) {
addInt(find(fRegions, region));
addInt(fRegions.find(&region));
}
void SkPictureRecord::addText(const void* text, size_t byteLength) {
@ -606,85 +611,6 @@ void SkPictureRecord::addText(const void* text, size_t byteLength) {
///////////////////////////////////////////////////////////////////////////////
int SkPictureRecord::find(SkTDArray<const SkFlatBitmap* >& bitmaps, const SkBitmap& bitmap) {
SkFlatBitmap* flat = SkFlatBitmap::Flatten(&fHeap, bitmap, fBitmapIndex,
&fRCSet);
int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(),
bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
if (index >= 0) {
(void)fHeap.unalloc(flat);
return bitmaps[index]->index();
}
index = ~index;
*bitmaps.insert(index) = flat;
return fBitmapIndex++;
}
int SkPictureRecord::find(SkTDArray<const SkFlatMatrix* >& matrices, const SkMatrix* matrix) {
if (matrix == NULL)
return 0;
SkFlatMatrix* flat = SkFlatMatrix::Flatten(&fHeap, *matrix, fMatrixIndex);
int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(),
matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
if (index >= 0) {
(void)fHeap.unalloc(flat);
return matrices[index]->index();
}
index = ~index;
*matrices.insert(index) = flat;
return fMatrixIndex++;
}
int SkPictureRecord::find(SkTDArray<const SkFlatPaint* >& paints, const SkPaint* paint) {
if (paint == NULL) {
return 0;
}
SkFlatPaint* flat = SkFlatPaint::Flatten(&fHeap, *paint, fPaintIndex,
&fRCSet, &fTFSet);
int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(),
paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
if (index >= 0) {
(void)fHeap.unalloc(flat);
return paints[index]->index();
}
index = ~index;
*paints.insert(index) = flat;
return fPaintIndex++;
}
int SkPictureRecord::find(SkTDArray<const SkFlatRegion* >& regions, const SkRegion& region) {
SkFlatRegion* flat = SkFlatRegion::Flatten(&fHeap, region, fRegionIndex);
int index = SkTSearch<SkFlatData>((const SkFlatData**) regions.begin(),
regions.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
if (index >= 0) {
(void)fHeap.unalloc(flat);
return regions[index]->index();
}
index = ~index;
*regions.insert(index) = flat;
return fRegionIndex++;
}
#ifdef SK_DEBUG_DUMP
void SkPictureRecord::dumpMatrices() {
int count = fMatrices.count();
SkMatrix defaultMatrix;
defaultMatrix.reset();
for (int index = 0; index < count; index++) {
const SkFlatMatrix* flatMatrix = fMatrices[index];
flatMatrix->dump();
}
}
void SkPictureRecord::dumpPaints() {
int count = fPaints.count();
for (int index = 0; index < count; index++)
fPaints[index]->dump();
}
#endif
#ifdef SK_DEBUG_SIZE
size_t SkPictureRecord::size() const {
size_t result = 0;

View File

@ -69,19 +69,19 @@ public:
void addFontMetricsTopBottom(const SkPaint& paint, SkScalar minY, SkScalar maxY);
const SkTDArray<const SkFlatBitmap* >& getBitmaps() const {
const SkBitmapDictionary& getBitmaps() const {
return fBitmaps;
}
const SkTDArray<const SkFlatMatrix* >& getMatrices() const {
const SkMatrixDictionary& getMatrices() const {
return fMatrices;
}
const SkTDArray<const SkFlatPaint* >& getPaints() const {
const SkPaintDictionary& getPaints() const {
return fPaints;
}
const SkTDArray<SkPicture* >& getPictureRefs() const {
return fPictureRefs;
}
const SkTDArray<const SkFlatRegion* >& getRegions() const {
const SkRegionDictionary& getRegions() const {
return fRegions;
}
@ -127,13 +127,6 @@ private:
void addRegion(const SkRegion& region);
void addText(const void* text, size_t byteLength);
int find(SkTDArray<const SkFlatBitmap* >& bitmaps,
const SkBitmap& bitmap);
int find(SkTDArray<const SkFlatMatrix* >& matrices,
const SkMatrix* matrix);
int find(SkTDArray<const SkFlatPaint* >& paints, const SkPaint* paint);
int find(SkTDArray<const SkFlatRegion* >& regions, const SkRegion& region);
#ifdef SK_DEBUG_DUMP
public:
void dumpMatrices();
@ -170,14 +163,11 @@ public:
private:
SkChunkAlloc fHeap;
int fBitmapIndex;
SkTDArray<const SkFlatBitmap* > fBitmaps;
int fMatrixIndex;
SkTDArray<const SkFlatMatrix* > fMatrices;
int fPaintIndex;
SkTDArray<const SkFlatPaint* > fPaints;
int fRegionIndex;
SkTDArray<const SkFlatRegion* > fRegions;
SkBitmapDictionary fBitmaps;
SkMatrixDictionary fMatrices;
SkPaintDictionary fPaints;
SkRegionDictionary fRegions;
SkPathHeap* fPathHeap; // reference counted
SkWriter32 fWriter;

View File

@ -74,18 +74,11 @@ void Sk2DPathEffect::end(SkPath* dst) {}
void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
char storage[SkMatrix::kMaxFlattenSize];
uint32_t size = fMatrix.flatten(storage);
buffer.write32(size);
buffer.write(storage, size);
buffer.writeMatrix(fMatrix);
}
Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) {
char storage[SkMatrix::kMaxFlattenSize];
uint32_t size = buffer.readS32();
SkASSERT(size <= sizeof(storage));
buffer.read(storage, size);
fMatrix.unflatten(storage);
buffer.readMatrix(&fMatrix);
fMatrixIsInvertible = fMatrix.invert(&fInverse);
}

View File

@ -92,13 +92,9 @@ void SkGroupShape::flatten(SkFlattenableWriteBuffer& buffer) const {
const Rec* stop = fList.end();
while (rec < stop) {
buffer.writeFlattenable(rec->fShape);
buffer.writeBool(rec->fMatrixRef);
if (rec->fMatrixRef) {
char storage[SkMatrix::kMaxFlattenSize];
uint32_t size = rec->fMatrixRef->flatten(storage);
buffer.write32(size);
buffer.writePad(storage, size);
} else {
buffer.write32(0);
buffer.writeMatrix(*rec->fMatrixRef);
}
rec += 1;
}
@ -109,12 +105,10 @@ SkGroupShape::SkGroupShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer){
for (int i = 0; i < count; i++) {
SkShape* shape = reinterpret_cast<SkShape*>(buffer.readFlattenable());
SkMatrixRef* mr = NULL;
uint32_t size = buffer.readS32();
if (size) {
char storage[SkMatrix::kMaxFlattenSize];
buffer.read(storage, SkAlign4(size));
bool hasMatrix = buffer.readBool();
if (hasMatrix) {
mr = SkNEW(SkMatrixRef);
mr->unflatten(storage);
buffer.readMatrix(mr);
}
if (shape) {
this->appendShape(shape, mr)->unref();

View File

@ -583,14 +583,14 @@ public:
// Verify that deserialization-serialization round trip conserves all
// data by comparing referenceRecord to roundTripRecord
REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fBitmapIndex ==
roundTripRecord->fBitmapIndex, testStep->assertMessage());
REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fMatrixIndex ==
roundTripRecord->fMatrixIndex, testStep->assertMessage());
REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fPaintIndex ==
roundTripRecord->fPaintIndex, testStep->assertMessage());
REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fRegionIndex ==
roundTripRecord->fRegionIndex, testStep->assertMessage());
REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fBitmaps.count() ==
roundTripRecord->fBitmaps.count(), testStep->assertMessage());
REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fMatrices.count() ==
roundTripRecord->fMatrices.count(), testStep->assertMessage());
REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fPaints.count() ==
roundTripRecord->fPaints.count(), testStep->assertMessage());
REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fRegions.count() ==
roundTripRecord->fRegions.count(), testStep->assertMessage());
char referenceBuffer[kMaxPictureBufferSize];
SkMemoryWStream referenceStream(referenceBuffer,
kMaxPictureBufferSize);