Add SkSTArray, hide stack storage cons in SkTArray, unify SkTArray init logic
Review URL: http://codereview.appspot.com/5127044/ git-svn-id: http://skia.googlecode.com/svn/trunk@2342 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
c12e1b138e
commit
92669014aa
@ -30,7 +30,6 @@ public:
|
||||
* Caller is responsible for freeing this memory.
|
||||
*/
|
||||
GrAllocator(size_t itemSize, int itemsPerBlock, void* initialBlock) :
|
||||
fBlocks(fBlockInitialStorage, NUM_INIT_BLOCK_PTRS),
|
||||
fItemSize(itemSize),
|
||||
fItemsPerBlock(itemsPerBlock),
|
||||
fOwnFirstBlock(NULL == initialBlock),
|
||||
@ -128,13 +127,12 @@ public:
|
||||
private:
|
||||
static const int NUM_INIT_BLOCK_PTRS = 8;
|
||||
|
||||
SkTArray<void*> fBlocks;
|
||||
size_t fBlockSize;
|
||||
char fBlockInitialStorage[NUM_INIT_BLOCK_PTRS*sizeof(void*)];
|
||||
size_t fItemSize;
|
||||
int fItemsPerBlock;
|
||||
bool fOwnFirstBlock;
|
||||
int fCount;
|
||||
SkSTArray<NUM_INIT_BLOCK_PTRS, void*> fBlocks;
|
||||
size_t fBlockSize;
|
||||
size_t fItemSize;
|
||||
int fItemsPerBlock;
|
||||
bool fOwnFirstBlock;
|
||||
int fCount;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
@ -135,8 +135,7 @@ private:
|
||||
enum {
|
||||
kPreAllocElements = 4,
|
||||
};
|
||||
SkAlignedSTStorage<kPreAllocElements, Element> fListStorage;
|
||||
SkTArray<Element> fList;
|
||||
SkSTArray<kPreAllocElements, Element> fList;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -133,6 +133,7 @@ void GrAAHairLinePathRenderer::resetGeom() {
|
||||
namespace {
|
||||
|
||||
typedef SkTArray<SkPoint, true> PtArray;
|
||||
#define PREALLOC_PTARRAY(N) SkSTArray<(N),SkPoint, true>
|
||||
typedef SkTArray<int, true> IntArray;
|
||||
|
||||
/**
|
||||
@ -344,8 +345,7 @@ int generate_lines_and_quads(const SkPath& path,
|
||||
bounds.outset(SK_Scalar1, SK_Scalar1);
|
||||
bounds.roundOut(&ibounds);
|
||||
if (SkIRect::Intersects(clip, ibounds)) {
|
||||
SkPoint stackStorage[32];
|
||||
PtArray q((void*)stackStorage, 32);
|
||||
PREALLOC_PTARRAY(32) q;
|
||||
// in perspective have to do conversion in src space
|
||||
if (persp) {
|
||||
SkScalar tolScale =
|
||||
@ -629,10 +629,8 @@ bool GrAAHairLinePathRenderer::createGeom(GrDrawTarget::StageBitfield stages) {
|
||||
|
||||
GrMatrix viewM = fTarget->getViewMatrix();
|
||||
|
||||
SkAlignedSTStorage<128, GrPoint> lineStorage;
|
||||
SkAlignedSTStorage<128, GrPoint> quadStorage;
|
||||
PtArray lines(&lineStorage);
|
||||
PtArray quads(&quadStorage);
|
||||
PREALLOC_PTARRAY(128) lines;
|
||||
PREALLOC_PTARRAY(128) quads;
|
||||
IntArray qSubdivs;
|
||||
fQuadCnt = generate_lines_and_quads(*fPath, viewM, fTranslate, clip,
|
||||
&lines, &quads, &qSubdivs);
|
||||
|
@ -10,30 +10,25 @@
|
||||
|
||||
#include "GrClip.h"
|
||||
|
||||
GrClip::GrClip()
|
||||
: fList(&fListStorage) {
|
||||
GrClip::GrClip() {
|
||||
fConservativeBounds.setEmpty();
|
||||
fConservativeBoundsValid = true;
|
||||
}
|
||||
|
||||
GrClip::GrClip(const GrClip& src)
|
||||
: fList(&fListStorage) {
|
||||
GrClip::GrClip(const GrClip& src) {
|
||||
*this = src;
|
||||
}
|
||||
|
||||
GrClip::GrClip(const GrIRect& rect)
|
||||
: fList(&fListStorage) {
|
||||
GrClip::GrClip(const GrIRect& rect) {
|
||||
this->setFromIRect(rect);
|
||||
}
|
||||
|
||||
GrClip::GrClip(const GrRect& rect)
|
||||
: fList(&fListStorage) {
|
||||
GrClip::GrClip(const GrRect& rect) {
|
||||
this->setFromRect(rect);
|
||||
}
|
||||
|
||||
GrClip::GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
|
||||
const GrRect* bounds)
|
||||
: fList(&fListStorage) {
|
||||
const GrRect* bounds) {
|
||||
this->setFromIterator(iter, tx, ty, bounds);
|
||||
}
|
||||
|
||||
|
@ -329,8 +329,7 @@ void GrDrawTarget::VertexLayoutUnitTest() {
|
||||
#define DEBUG_INVAL_BUFFER 0xdeadcafe
|
||||
#define DEBUG_INVAL_START_IDX -1
|
||||
|
||||
GrDrawTarget::GrDrawTarget()
|
||||
: fGeoSrcStateStack(&fGeoSrcStateStackStorage) {
|
||||
GrDrawTarget::GrDrawTarget() {
|
||||
#if GR_DEBUG
|
||||
VertexLayoutUnitTest();
|
||||
#endif
|
||||
|
@ -1376,10 +1376,8 @@ private:
|
||||
enum {
|
||||
kPreallocGeoSrcStateStackCnt = 4,
|
||||
};
|
||||
SkAlignedSTStorage<kPreallocGeoSrcStateStackCnt,
|
||||
GeometrySrcState>
|
||||
fGeoSrcStateStackStorage;
|
||||
SkTArray<GeometrySrcState, true> fGeoSrcStateStack;
|
||||
SkSTArray<kPreallocGeoSrcStateStackCnt,
|
||||
GeometrySrcState, true> fGeoSrcStateStack;
|
||||
|
||||
};
|
||||
|
||||
|
@ -36,7 +36,6 @@ GrGpu::GrGpu()
|
||||
, fIndexPool(NULL)
|
||||
, fVertexPoolUseCnt(0)
|
||||
, fIndexPoolUseCnt(0)
|
||||
, fGeomPoolStateStack(&fGeoSrcStateStackStorage)
|
||||
, fQuadIndexBuffer(NULL)
|
||||
, fUnitSquareVertexBuffer(NULL)
|
||||
, fPathRendererChain(NULL)
|
||||
|
@ -374,9 +374,8 @@ private:
|
||||
enum {
|
||||
kPreallocGeomPoolStateStackCnt = 4,
|
||||
};
|
||||
SkAlignedSTStorage<kPreallocGeomPoolStateStackCnt,
|
||||
GeometryPoolState> fGeoSrcStateStackStorage;
|
||||
SkTArray<GeometryPoolState, true> fGeomPoolStateStack;
|
||||
SkSTArray<kPreallocGeomPoolStateStackCnt,
|
||||
GeometryPoolState, true> fGeomPoolStateStack;
|
||||
|
||||
mutable GrIndexBuffer* fQuadIndexBuffer; // mutable so it can be
|
||||
// created on-demand
|
||||
|
@ -30,8 +30,7 @@ GrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu,
|
||||
, fCurrQuad(0)
|
||||
|
||||
, fVertexPool(*vertexPool)
|
||||
, fIndexPool(*indexPool)
|
||||
, fGeoPoolStateStack(&fGeoStackStorage) {
|
||||
, fIndexPool(*indexPool) {
|
||||
|
||||
fCaps = gpu->getCaps();
|
||||
|
||||
|
@ -161,6 +161,15 @@ private:
|
||||
GrVertexBufferAllocPool& fVertexPool;
|
||||
|
||||
GrIndexBufferAllocPool& fIndexPool;
|
||||
|
||||
enum {
|
||||
kDrawPreallocCnt = 8,
|
||||
kStatePreallocCnt = 8,
|
||||
kClipPreallocCnt = 8,
|
||||
kClearPreallocCnt = 4,
|
||||
kGeoPoolStatePreAllocCnt = 4,
|
||||
};
|
||||
|
||||
struct GeometryPoolState {
|
||||
const GrVertexBuffer* fPoolVertexBuffer;
|
||||
int fPoolStartVertex;
|
||||
@ -172,23 +181,12 @@ private:
|
||||
size_t fUsedPoolVertexBytes;
|
||||
size_t fUsedPoolIndexBytes;
|
||||
};
|
||||
SkTArray<GeometryPoolState> fGeoPoolStateStack;
|
||||
|
||||
|
||||
enum {
|
||||
kDrawPreallocCnt = 8,
|
||||
kStatePreallocCnt = 8,
|
||||
kClipPreallocCnt = 8,
|
||||
kClearPreallocCnt = 4,
|
||||
kGeoPoolStatePreAllocCnt = 4,
|
||||
};
|
||||
SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
|
||||
|
||||
SkAlignedSTStorage<kDrawPreallocCnt, Draw> fDrawStorage;
|
||||
SkAlignedSTStorage<kStatePreallocCnt, SavedDrawState> fStateStorage;
|
||||
SkAlignedSTStorage<kClipPreallocCnt, GrClip> fClipStorage;
|
||||
SkAlignedSTStorage<kClearPreallocCnt, Clear> fClearStorage;
|
||||
SkAlignedSTStorage<kGeoPoolStatePreAllocCnt,
|
||||
GeometryPoolState> fGeoStackStorage;
|
||||
|
||||
typedef GrDrawTarget INHERITED;
|
||||
};
|
||||
|
@ -16,8 +16,7 @@
|
||||
GrPathRendererChain::GrPathRendererChain(GrContext* context, UsageFlags flags)
|
||||
: fInit(false)
|
||||
, fOwner(context)
|
||||
, fFlags(flags)
|
||||
, fChain(fStorage.get(), kPreAllocCount) {
|
||||
, fFlags(flags) {
|
||||
fInit = false;
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,7 @@ private:
|
||||
bool fInit;
|
||||
GrContext* fOwner;
|
||||
UsageFlags fFlags;
|
||||
SkAlignedSTStorage<kPreAllocCount, GrPathRenderer*> fStorage;
|
||||
SkTArray<GrPathRenderer*, true> fChain;
|
||||
SkSTArray<kPreAllocCount, GrPathRenderer*, true> fChain;
|
||||
};
|
||||
|
||||
GR_MAKE_BITFIELD_OPS(GrPathRendererChain::UsageFlags)
|
||||
|
@ -35,66 +35,14 @@ public:
|
||||
* elements.
|
||||
*/
|
||||
explicit SkTArray(int reserveCount) {
|
||||
SkASSERT(reserveCount >= 0);
|
||||
fCount = 0;
|
||||
fReserveCount = reserveCount > gMIN_ALLOC_COUNT ? reserveCount :
|
||||
gMIN_ALLOC_COUNT;
|
||||
fAllocCount = fReserveCount;
|
||||
fMemArray = sk_malloc_throw(sizeof(T) * fReserveCount);
|
||||
fPreAllocMemArray = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty array that will use the passed storage block until it
|
||||
* is insufficiently large to hold the entire array.
|
||||
*/
|
||||
template <int N>
|
||||
SkTArray(SkAlignedSTStorage<N,T>* storage) {
|
||||
SkASSERT(N > 0);
|
||||
fCount = 0;
|
||||
fReserveCount = N;
|
||||
fAllocCount = N;
|
||||
fMemArray = storage->get();
|
||||
fPreAllocMemArray = storage->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty array that will use the passed memory block until the
|
||||
* count exceeds preAllocCount. Be careful not to use this constructor
|
||||
* when you really want the (T*, int) version.
|
||||
*/
|
||||
SkTArray(void* preAllocStorage, int preAllocCount) {
|
||||
SkASSERT(preAllocCount >= 0);
|
||||
// we allow NULL,0 args and revert to the default cons. behavior
|
||||
// this makes it possible for a owner-object to use same constructor
|
||||
// to get either prealloc or nonprealloc behavior based using same line
|
||||
SkASSERT((NULL == preAllocStorage) == !preAllocCount);
|
||||
|
||||
fCount = 0;
|
||||
fReserveCount = preAllocCount > 0 ? preAllocCount :
|
||||
gMIN_ALLOC_COUNT;
|
||||
fAllocCount = preAllocCount;
|
||||
fMemArray = preAllocStorage;
|
||||
fPreAllocMemArray = preAllocStorage;
|
||||
this->init(NULL, 0, NULL, reserveCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies one array to another. The new array will be heap allocated.
|
||||
*/
|
||||
explicit SkTArray(const SkTArray& array) {
|
||||
fCount = array.count();
|
||||
fReserveCount = gMIN_ALLOC_COUNT;
|
||||
fAllocCount = SkMax32(fReserveCount, fCount);
|
||||
fMemArray = sk_malloc_throw(sizeof(T) * fAllocCount);
|
||||
fPreAllocMemArray = NULL;
|
||||
|
||||
if (DATA_TYPE) {
|
||||
memcpy(fMemArray, array.fMemArray, sizeof(T) * fCount);
|
||||
} else {
|
||||
for (int i = 0; i < fCount; ++i) {
|
||||
new (fItemArray + i) T(array[i]);
|
||||
}
|
||||
}
|
||||
this->init(array.fItemArray, array.fCount, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,90 +51,7 @@ public:
|
||||
* when you really want the (void*, int) version.
|
||||
*/
|
||||
SkTArray(const T* array, int count) {
|
||||
SkASSERT(count >= 0);
|
||||
fCount = count;
|
||||
fReserveCount = gMIN_ALLOC_COUNT;
|
||||
fAllocCount = SkMax32(fReserveCount, fCount);
|
||||
fMemArray = sk_malloc_throw(sizeof(T) * fAllocCount);
|
||||
fPreAllocMemArray = NULL;
|
||||
if (DATA_TYPE) {
|
||||
memcpy(fMemArray, array, sizeof(T) * fCount);
|
||||
} else {
|
||||
for (int i = 0; i < fCount; ++i) {
|
||||
new (fItemArray + i) T(array[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy another array, using preallocated storage if preAllocCount >=
|
||||
* array.count(). Otherwise preAllocStorage is only used if the array
|
||||
* shrinks to fit.
|
||||
*/
|
||||
SkTArray(const SkTArray& array,
|
||||
void* preAllocStorage, int preAllocCount) {
|
||||
|
||||
SkASSERT(preAllocCount >= 0);
|
||||
|
||||
// for same reason as non-copying cons we allow NULL, 0 for prealloc
|
||||
SkASSERT((NULL == preAllocStorage) == !preAllocCount);
|
||||
|
||||
fCount = array.count();
|
||||
fReserveCount = preAllocCount > 0 ? preAllocCount :
|
||||
gMIN_ALLOC_COUNT;
|
||||
fPreAllocMemArray = preAllocStorage;
|
||||
|
||||
if (fReserveCount >= fCount && preAllocCount) {
|
||||
fAllocCount = fReserveCount;
|
||||
fMemArray = preAllocStorage;
|
||||
} else {
|
||||
fAllocCount = SkMax32(fCount, fReserveCount);
|
||||
fMemArray = sk_malloc_throw(fAllocCount * sizeof(T));
|
||||
}
|
||||
|
||||
if (DATA_TYPE) {
|
||||
memcpy(fMemArray, array.fMemArray, sizeof(T) * fCount);
|
||||
} else {
|
||||
for (int i = 0; i < fCount; ++i) {
|
||||
new (fItemArray + i) T(array[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy C array to SkTArray, using preallocated storage if preAllocCount >=
|
||||
* preAllocCount. Otherwise preAllocStorage is only used if the array
|
||||
* shrinks to fit.
|
||||
*/
|
||||
SkTArray(const T* array, int count,
|
||||
void* preAllocStorage, int preAllocCount) {
|
||||
|
||||
SkASSERT(count >= 0);
|
||||
SkASSERT(preAllocCount >= 0);
|
||||
|
||||
// for same reason as non-copying cons we allow NULL, 0 for prealloc
|
||||
SkASSERT((NULL == preAllocStorage) == !preAllocCount);
|
||||
|
||||
fCount = count;
|
||||
fReserveCount = (preAllocCount > 0) ? preAllocCount :
|
||||
gMIN_ALLOC_COUNT;
|
||||
fPreAllocMemArray = preAllocStorage;
|
||||
|
||||
if (fReserveCount >= fCount && preAllocCount) {
|
||||
fAllocCount = fReserveCount;
|
||||
fMemArray = preAllocStorage;
|
||||
} else {
|
||||
fAllocCount = SkMax32(fCount, fReserveCount);
|
||||
fMemArray = sk_malloc_throw(fAllocCount * sizeof(T));
|
||||
}
|
||||
|
||||
if (DATA_TYPE) {
|
||||
memcpy(fMemArray, array, sizeof(T) * fCount);
|
||||
} else {
|
||||
for (int i = 0; i < fCount; ++i) {
|
||||
new (fItemArray + i) T(array[i]);
|
||||
}
|
||||
}
|
||||
this->init(array, count, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -209,7 +74,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
~SkTArray() {
|
||||
virtual ~SkTArray() {
|
||||
for (int i = 0; i < fCount; ++i) {
|
||||
fItemArray[i].~T();
|
||||
}
|
||||
@ -379,6 +244,63 @@ public:
|
||||
return fItemArray[fCount - i - 1];
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Creates an empty array that will use the passed storage block until it
|
||||
* is insufficiently large to hold the entire array.
|
||||
*/
|
||||
template <int N>
|
||||
SkTArray(SkAlignedSTStorage<N,T>* storage) {
|
||||
this->init(NULL, 0, storage->get(), N);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy another array, using preallocated storage if preAllocCount >=
|
||||
* array.count(). Otherwise storage will only be used when array shrinks
|
||||
* to fit.
|
||||
*/
|
||||
template <int N>
|
||||
SkTArray(const SkTArray& array, SkAlignedSTStorage<N,T>* storage) {
|
||||
this->init(array.fItemArray, array.fCount, storage->get(), N);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a C array, using preallocated storage if preAllocCount >=
|
||||
* count. Otherwise storage will only be used when array shrinks
|
||||
* to fit.
|
||||
*/
|
||||
template <int N>
|
||||
SkTArray(const T* array, int count, SkAlignedSTStorage<N,T>* storage) {
|
||||
this->init(array, count, storage->get(), N);
|
||||
}
|
||||
|
||||
void init(const T* array, int count,
|
||||
void* preAllocStorage, int preAllocOrReserveCount) {
|
||||
GrAssert(count >= 0);
|
||||
GrAssert(preAllocOrReserveCount >= 0);
|
||||
fCount = count;
|
||||
fReserveCount = (preAllocOrReserveCount > 0) ?
|
||||
preAllocOrReserveCount :
|
||||
gMIN_ALLOC_COUNT;
|
||||
fPreAllocMemArray = preAllocStorage;
|
||||
if (fReserveCount >= fCount &&
|
||||
NULL != preAllocStorage) {
|
||||
fAllocCount = fReserveCount;
|
||||
fMemArray = preAllocStorage;
|
||||
} else {
|
||||
fAllocCount = GrMax(fCount, fReserveCount);
|
||||
fMemArray = GrMalloc(fAllocCount * sizeof(T));
|
||||
}
|
||||
|
||||
if (DATA_TYPE) {
|
||||
memcpy(fMemArray, array, sizeof(T) * fCount);
|
||||
} else {
|
||||
for (int i = 0; i < fCount; ++i) {
|
||||
new (fItemArray + i) T(array[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static const int gMIN_ALLOC_COUNT = 8;
|
||||
@ -436,5 +358,42 @@ private:
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Subclass of SkTArray that contains a preallocated memory block for the array.
|
||||
*/
|
||||
template <int N, typename T, bool DATA_TYPE = false>
|
||||
class SkSTArray : public SkTArray<T, DATA_TYPE> {
|
||||
private:
|
||||
typedef SkTArray<T, DATA_TYPE> INHERITED;
|
||||
|
||||
public:
|
||||
SkSTArray() : INHERITED(&fStorage) {
|
||||
}
|
||||
|
||||
SkSTArray(const SkSTArray& array)
|
||||
: INHERITED(array, &fStorage) {
|
||||
}
|
||||
|
||||
explicit SkSTArray(const INHERITED& array)
|
||||
: INHERITED(array, &fStorage) {
|
||||
}
|
||||
|
||||
SkSTArray(const T* array, int count)
|
||||
: INHERITED(array, count, &fStorage) {
|
||||
}
|
||||
|
||||
SkSTArray& operator= (const SkSTArray& array) {
|
||||
return *this = *(const INHERITED*)&array;
|
||||
}
|
||||
|
||||
SkSTArray& operator= (const INHERITED& array) {
|
||||
INHERITED::operator=(array);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
SkAlignedSTStorage<N,T> fStorage;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user