1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrMemoryPool_DEFINED 9 #define GrMemoryPool_DEFINED 10 11 #include "GrTypes.h" 12 13 /** 14 * Allocates memory in blocks and parcels out space in the blocks for allocation 15 * requests. It is optimized for allocate / release speed over memory 16 * effeciency. The interface is designed to be used to implement operator new 17 * and delete overrides. All allocations are expected to be released before the 18 * pool's destructor is called. Allocations will be 8-byte aligned. 19 */ 20 class GrMemoryPool { 21 public: 22 /** 23 * Prealloc size is the amount of space to make available at pool creation 24 * time and keep around until pool destruction. The min alloc size is the 25 * smallest allowed size of additional allocations. 26 */ 27 GrMemoryPool(size_t preallocSize, size_t minAllocSize); 28 29 ~GrMemoryPool(); 30 31 /** 32 * Allocates memory. The memory must be freed with release(). 33 */ 34 void* allocate(size_t size); 35 36 /** 37 * p must have been returned by allocate() 38 */ 39 void release(void* p); 40 41 /** 42 * Returns true if there are no unreleased allocations. 43 */ isEmpty()44 bool isEmpty() const { return fTail == fHead && !fHead->fLiveCount; } 45 46 /** 47 * Returns the total allocated size of the GrMemoryPool 48 */ size()49 size_t size() const { return fSize; } 50 51 private: 52 struct BlockHeader; 53 54 static BlockHeader* CreateBlock(size_t size); 55 56 static void DeleteBlock(BlockHeader* block); 57 58 void validate(); 59 60 struct BlockHeader { 61 BlockHeader* fNext; ///< doubly-linked list of blocks. 62 BlockHeader* fPrev; 63 int fLiveCount; ///< number of outstanding allocations in the 64 ///< block. 65 intptr_t fCurrPtr; ///< ptr to the start of blocks free space. 66 intptr_t fPrevPtr; ///< ptr to the last allocation made 67 size_t fFreeSize; ///< amount of free space left in the block. 68 size_t fSize; ///< total allocated size of the block 69 }; 70 71 enum { 72 // We assume this alignment is good enough for everybody. 73 kAlignment = 8, 74 kHeaderSize = GR_CT_ALIGN_UP(sizeof(BlockHeader), kAlignment), 75 kPerAllocPad = GR_CT_ALIGN_UP(sizeof(BlockHeader*), kAlignment), 76 }; 77 size_t fSize; 78 size_t fPreallocSize; 79 size_t fMinAllocSize; 80 BlockHeader* fHead; 81 BlockHeader* fTail; 82 #ifdef SK_DEBUG 83 int fAllocationCnt; 84 int fAllocBlockCnt; 85 #endif 86 }; 87 88 #endif 89