• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 private:
47     struct BlockHeader;
48 
49     BlockHeader* CreateBlock(size_t size);
50 
51     void DeleteBlock(BlockHeader* block);
52 
53     void validate();
54 
55     struct BlockHeader {
56         BlockHeader* fNext;      ///< doubly-linked list of blocks.
57         BlockHeader* fPrev;
58         int          fLiveCount; ///< number of outstanding allocations in the
59                                  ///< block.
60         intptr_t     fCurrPtr;   ///< ptr to the start of blocks free space.
61         intptr_t     fPrevPtr;   ///< ptr to the last allocation made
62         size_t       fFreeSize;  ///< amount of free space left in the block.
63     };
64 
65     enum {
66         // We assume this alignment is good enough for everybody.
67         kAlignment    = 8,
68         kHeaderSize   = GR_CT_ALIGN_UP(sizeof(BlockHeader), kAlignment),
69         kPerAllocPad  = GR_CT_ALIGN_UP(sizeof(BlockHeader*), kAlignment),
70     };
71     size_t                            fPreallocSize;
72     size_t                            fMinAllocSize;
73     BlockHeader*                      fHead;
74     BlockHeader*                      fTail;
75 #if GR_DEBUG
76     int                               fAllocationCnt;
77 #endif
78 };
79 
80 #endif
81