Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Unified Diff: src/gpu/GrMemoryPool.h

Issue 2525773002: Make GrMemoryPool play nice with bucketing allocators. (Closed)
Patch Set: Proper naming; kill friend Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/gpu/GrMemoryPool.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrMemoryPool.h
diff --git a/src/gpu/GrMemoryPool.h b/src/gpu/GrMemoryPool.h
index 43826d354a134f8d7bcbf667e395cb2095194fd0..e483aab6f2177ce333e7ad41c25de788e095bb75 100644
--- a/src/gpu/GrMemoryPool.h
+++ b/src/gpu/GrMemoryPool.h
@@ -13,16 +13,23 @@
/**
* Allocates memory in blocks and parcels out space in the blocks for allocation
* requests. It is optimized for allocate / release speed over memory
- * effeciency. The interface is designed to be used to implement operator new
+ * efficiency. The interface is designed to be used to implement operator new
* and delete overrides. All allocations are expected to be released before the
* pool's destructor is called. Allocations will be 8-byte aligned.
*/
class GrMemoryPool {
public:
/**
- * Prealloc size is the amount of space to make available at pool creation
- * time and keep around until pool destruction. The min alloc size is the
- * smallest allowed size of additional allocations.
+ * Prealloc size is the amount of space to allocate at pool creation
+ * time and keep around until pool destruction. The min alloc size is
+ * the smallest allowed size of additional allocations. Both sizes are
+ * adjusted to ensure that:
+ * 1. they are are 8-byte aligned
herb_g 2016/11/29 18:31:14 Generally , 8-byte alignment is not enough. You sh
+ * 2. minAllocSize >= kSmallestMinAllocSize
+ * 3. preallocSize >= minAllocSize
+ *
+ * Both sizes is what the pool will end up allocating from the system, and
+ * portions of the allocated memory is used for internal bookkeeping.
*/
GrMemoryPool(size_t preallocSize, size_t minAllocSize);
@@ -48,6 +55,16 @@ public:
*/
size_t size() const { return fSize; }
+ /**
+ * Returns the preallocated size of the GrMemoryPool
+ */
+ size_t preallocSize() const { return fHead->fSize; }
+
+ /**
+ * Minimum value of minAllocSize constructor argument.
+ */
+ constexpr static size_t kSmallestMinAllocSize = 1 << 10;
+
private:
struct BlockHeader;
@@ -81,14 +98,7 @@ private:
BlockHeader* fHeader; ///< pointer back to the block header in which an alloc resides
};
- enum {
- // We assume this alignment is good enough for everybody.
- kAlignment = 8,
- kHeaderSize = GR_CT_ALIGN_UP(sizeof(BlockHeader), kAlignment),
- kPerAllocPad = GR_CT_ALIGN_UP(sizeof(AllocHeader), kAlignment),
- };
size_t fSize;
- size_t fPreallocSize;
size_t fMinAllocSize;
BlockHeader* fHead;
BlockHeader* fTail;
@@ -96,6 +106,79 @@ private:
int fAllocationCnt;
int fAllocBlockCnt;
#endif
+
+protected:
+ enum {
+ // We assume this alignment is good enough for everybody.
+ kAlignment = 8,
+ kHeaderSize = GR_CT_ALIGN_UP(sizeof(BlockHeader), kAlignment),
+ kPerAllocPad = GR_CT_ALIGN_UP(sizeof(AllocHeader), kAlignment),
+ };
+};
+
+/**
+ * Variant of GrMemoryPool that can only allocate objects of a single type. It is
+ * not as flexible as GrMemoryPool, but it has more convenient allocate() method,
+ * and more importantly, it guarantees number of objects that are preallocated at
+ * construction or when adding a new memory block. I.e.
+ *
+ * GrMemoryPool pool(3 * sizeof(T), 1000 * sizeof(T));
+ * pool.allocate(sizeof(T));
+ * pool.allocate(sizeof(T));
+ * pool.allocate(sizeof(T));
+ *
+ * will preallocate 3 * sizeof(T) bytes and use some of those bytes for internal
+ * structures. Because of that, last allocate() call will end up allocating a new
+ * block of 1000 * sizeof(T) bytes. In contrast,
+ *
+ * GrObjectMemoryPool<T> pool(3, 1000);
+ * pool.allocate();
+ * pool.allocate();
+ * pool.allocate();
+ *
+ * guarantees to preallocate enough memory for 3 objects of sizeof(T), so last
+ * allocate() will use preallocated memory and won't cause allocation of a new block.
+ *
+ * Same thing is true for the second (minAlloc) ctor argument: this class guarantees
+ * that a newly added block will have enough space for 1000 objects of sizeof(T), while
+ * GrMemoryPool does not.
+ */
+template <class T>
+class GrObjectMemoryPool: public GrMemoryPool {
+public:
+ /**
+ * Preallocates memory for preallocCount objects, and sets new block size to be
+ * enough to hold minAllocCount objects.
+ */
+ GrObjectMemoryPool(size_t preallocCount, size_t minAllocCount)
+ : GrMemoryPool(CountToSize(preallocCount),
+ CountToSize(SkTMax(minAllocCount, kSmallestMinAllocCount))) {
+ }
+
+ /**
+ * Allocates memory for an object, but doesn't construct or otherwise initialize it.
+ * The memory must be freed with release().
+ */
+ T* allocate() { return static_cast<T*>(GrMemoryPool::allocate(sizeof(T))); }
herb_g 2016/11/29 18:31:14 I think this is a very dangerous API. It is not RA
+
+private:
+ constexpr static size_t kTotalObjectSize =
+ kPerAllocPad + GR_CT_ALIGN_UP(sizeof(T), kAlignment);
+
+ constexpr static size_t CountToSize(size_t count) {
+ return kHeaderSize + count * kTotalObjectSize;
+ }
+
+public:
+ /**
+ * Minimum value of minAllocCount constructor argument.
+ */
+ constexpr static size_t kSmallestMinAllocCount =
+ (GrMemoryPool::kSmallestMinAllocSize - kHeaderSize + kTotalObjectSize - 1) /
+ kTotalObjectSize;
};
+template <class T>
+constexpr size_t GrObjectMemoryPool<T>::kSmallestMinAllocCount;
+
#endif
« no previous file with comments | « no previous file | src/gpu/GrMemoryPool.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698