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
diff --git a/gpu/include/GrAllocator.h b/gpu/include/GrAllocator.h
index eca2ab0..7f1fe5b 100755
--- a/gpu/include/GrAllocator.h
+++ b/gpu/include/GrAllocator.h
@@ -30,7 +30,6 @@
* 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 @@
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>
diff --git a/gpu/include/GrClip.h b/gpu/include/GrClip.h
index 9e235bf..d86eb97 100644
--- a/gpu/include/GrClip.h
+++ b/gpu/include/GrClip.h
@@ -135,8 +135,7 @@
enum {
kPreAllocElements = 4,
};
- SkAlignedSTStorage<kPreAllocElements, Element> fListStorage;
- SkTArray<Element> fList;
+ SkSTArray<kPreAllocElements, Element> fList;
};
#endif
diff --git a/gpu/src/GrAAHairLinePathRenderer.cpp b/gpu/src/GrAAHairLinePathRenderer.cpp
index 32a477b..6c136e2 100644
--- a/gpu/src/GrAAHairLinePathRenderer.cpp
+++ b/gpu/src/GrAAHairLinePathRenderer.cpp
@@ -133,6 +133,7 @@
namespace {
typedef SkTArray<SkPoint, true> PtArray;
+#define PREALLOC_PTARRAY(N) SkSTArray<(N),SkPoint, true>
typedef SkTArray<int, true> IntArray;
/**
@@ -344,8 +345,7 @@
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 @@
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);
diff --git a/gpu/src/GrClip.cpp b/gpu/src/GrClip.cpp
index afa143a..a02d9f4 100644
--- a/gpu/src/GrClip.cpp
+++ b/gpu/src/GrClip.cpp
@@ -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);
}
diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp
index 59661d8..51e6fdd 100644
--- a/gpu/src/GrDrawTarget.cpp
+++ b/gpu/src/GrDrawTarget.cpp
@@ -329,8 +329,7 @@
#define DEBUG_INVAL_BUFFER 0xdeadcafe
#define DEBUG_INVAL_START_IDX -1
-GrDrawTarget::GrDrawTarget()
-: fGeoSrcStateStack(&fGeoSrcStateStackStorage) {
+GrDrawTarget::GrDrawTarget() {
#if GR_DEBUG
VertexLayoutUnitTest();
#endif
diff --git a/gpu/src/GrDrawTarget.h b/gpu/src/GrDrawTarget.h
index f1c98e8..81d0b2b 100644
--- a/gpu/src/GrDrawTarget.h
+++ b/gpu/src/GrDrawTarget.h
@@ -1376,10 +1376,8 @@
enum {
kPreallocGeoSrcStateStackCnt = 4,
};
- SkAlignedSTStorage<kPreallocGeoSrcStateStackCnt,
- GeometrySrcState>
- fGeoSrcStateStackStorage;
- SkTArray<GeometrySrcState, true> fGeoSrcStateStack;
+ SkSTArray<kPreallocGeoSrcStateStackCnt,
+ GeometrySrcState, true> fGeoSrcStateStack;
};
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 91e659d..7b98ffa 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -36,7 +36,6 @@
, fIndexPool(NULL)
, fVertexPoolUseCnt(0)
, fIndexPoolUseCnt(0)
- , fGeomPoolStateStack(&fGeoSrcStateStackStorage)
, fQuadIndexBuffer(NULL)
, fUnitSquareVertexBuffer(NULL)
, fPathRendererChain(NULL)
diff --git a/gpu/src/GrGpu.h b/gpu/src/GrGpu.h
index 9ecb4b0..3193a56 100644
--- a/gpu/src/GrGpu.h
+++ b/gpu/src/GrGpu.h
@@ -374,9 +374,8 @@
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
diff --git a/gpu/src/GrInOrderDrawBuffer.cpp b/gpu/src/GrInOrderDrawBuffer.cpp
index 9519655..3d78da3 100644
--- a/gpu/src/GrInOrderDrawBuffer.cpp
+++ b/gpu/src/GrInOrderDrawBuffer.cpp
@@ -30,8 +30,7 @@
, fCurrQuad(0)
, fVertexPool(*vertexPool)
- , fIndexPool(*indexPool)
- , fGeoPoolStateStack(&fGeoStackStorage) {
+ , fIndexPool(*indexPool) {
fCaps = gpu->getCaps();
diff --git a/gpu/src/GrInOrderDrawBuffer.h b/gpu/src/GrInOrderDrawBuffer.h
index f0b5c9e..122be53 100644
--- a/gpu/src/GrInOrderDrawBuffer.h
+++ b/gpu/src/GrInOrderDrawBuffer.h
@@ -161,6 +161,15 @@
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 @@
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;
};
diff --git a/gpu/src/GrPathRendererChain.cpp b/gpu/src/GrPathRendererChain.cpp
index 87ebe10..7a064e8 100644
--- a/gpu/src/GrPathRendererChain.cpp
+++ b/gpu/src/GrPathRendererChain.cpp
@@ -16,8 +16,7 @@
GrPathRendererChain::GrPathRendererChain(GrContext* context, UsageFlags flags)
: fInit(false)
, fOwner(context)
- , fFlags(flags)
- , fChain(fStorage.get(), kPreAllocCount) {
+ , fFlags(flags) {
fInit = false;
}
diff --git a/gpu/src/GrPathRendererChain.h b/gpu/src/GrPathRendererChain.h
index 24abda4..5719484 100644
--- a/gpu/src/GrPathRendererChain.h
+++ b/gpu/src/GrPathRendererChain.h
@@ -55,8 +55,7 @@
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)
diff --git a/include/core/SkTArray.h b/include/core/SkTArray.h
index 3e2a006..9237611 100644
--- a/include/core/SkTArray.h
+++ b/include/core/SkTArray.h
@@ -35,66 +35,14 @@
* 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;
+ this->init(NULL, 0, NULL, reserveCount);
}
-
- /**
- * 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;
- }
-
+
/**
* 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 @@
* 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 @@
return *this;
}
- ~SkTArray() {
+ virtual ~SkTArray() {
for (int i = 0; i < fCount; ++i) {
fItemArray[i].~T();
}
@@ -379,6 +244,63 @@
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 @@
};
};
+/**
+ * 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