- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrAllocator.h
1 /*
2  * Copyright 2010 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 GrAllocator_DEFINED
9 #define GrAllocator_DEFINED
10
11 #include "GrConfig.h"
12 #include "GrTypes.h"
13 #include "SkTArray.h"
14 #include "SkTypes.h"
15
16 class GrAllocator : public SkNoncopyable {
17 public:
18     ~GrAllocator() {
19         reset();
20     }
21
22     /**
23      * Create an allocator
24      *
25      * @param   itemSize        the size of each item to allocate
26      * @param   itemsPerBlock   the number of items to allocate at once
27      * @param   initialBlock    optional memory to use for the first block.
28      *                          Must be at least itemSize*itemsPerBlock sized.
29      *                          Caller is responsible for freeing this memory.
30      */
31     GrAllocator(size_t itemSize, int itemsPerBlock, void* initialBlock) :
32             fItemSize(itemSize),
33             fItemsPerBlock(itemsPerBlock),
34             fOwnFirstBlock(NULL == initialBlock),
35             fCount(0) {
36         SkASSERT(itemsPerBlock > 0);
37         fBlockSize = fItemSize * fItemsPerBlock;
38         fBlocks.push_back() = initialBlock;
39         SkDEBUGCODE(if (!fOwnFirstBlock) {*((char*)initialBlock+fBlockSize-1)='a';} );
40     }
41
42     /**
43      * Adds an item and returns pointer to it.
44      *
45      * @return pointer to the added item.
46      */
47     void* push_back() {
48         int indexInBlock = fCount % fItemsPerBlock;
49         // we always have at least one block
50         if (0 == indexInBlock) {
51             if (0 != fCount) {
52                 fBlocks.push_back() = sk_malloc_throw(fBlockSize);
53             } else if (fOwnFirstBlock) {
54                 fBlocks[0] = sk_malloc_throw(fBlockSize);
55             }
56         }
57         void* ret = (char*)fBlocks[fCount/fItemsPerBlock] +
58                     fItemSize * indexInBlock;
59         ++fCount;
60         return ret;
61     }
62
63     /**
64      * removes all added items
65      */
66     void reset() {
67         int blockCount = GrMax((unsigned)1,
68                                GrUIDivRoundUp(fCount, fItemsPerBlock));
69         for (int i = 1; i < blockCount; ++i) {
70             sk_free(fBlocks[i]);
71         }
72         if (fOwnFirstBlock) {
73             sk_free(fBlocks[0]);
74             fBlocks[0] = NULL;
75         }
76         fBlocks.pop_back_n(blockCount-1);
77         fCount = 0;
78     }
79
80     /**
81      * count of items
82      */
83     int count() const {
84         return fCount;
85     }
86
87     /**
88      * is the count 0
89      */
90     bool empty() const { return fCount == 0; }
91
92     /**
93      * access last item, only call if count() != 0
94      */
95     void* back() {
96         SkASSERT(fCount);
97         return (*this)[fCount-1];
98     }
99
100     /**
101      * access last item, only call if count() != 0
102      */
103     const void* back() const {
104         SkASSERT(fCount);
105         return (*this)[fCount-1];
106     }
107
108     /**
109      * access item by index.
110      */
111     void* operator[] (int i) {
112         SkASSERT(i >= 0 && i < fCount);
113         return (char*)fBlocks[i / fItemsPerBlock] +
114                fItemSize * (i % fItemsPerBlock);
115     }
116
117     /**
118      * access item by index.
119      */
120     const void* operator[] (int i) const {
121         SkASSERT(i >= 0 && i < fCount);
122         return (const char*)fBlocks[i / fItemsPerBlock] +
123                fItemSize * (i % fItemsPerBlock);
124     }
125
126 private:
127     static const int NUM_INIT_BLOCK_PTRS = 8;
128
129     SkSTArray<NUM_INIT_BLOCK_PTRS, void*>   fBlocks;
130     size_t                                  fBlockSize;
131     size_t                                  fItemSize;
132     int                                     fItemsPerBlock;
133     bool                                    fOwnFirstBlock;
134     int                                     fCount;
135
136     typedef SkNoncopyable INHERITED;
137 };
138
139 template <typename T>
140 class GrTAllocator : public SkNoncopyable {
141 public:
142     virtual ~GrTAllocator() { this->reset(); };
143
144     /**
145      * Create an allocator
146      *
147      * @param   itemsPerBlock   the number of items to allocate at once
148      * @param   initialBlock    optional memory to use for the first block.
149      *                          Must be at least size(T)*itemsPerBlock sized.
150      *                          Caller is responsible for freeing this memory.
151      */
152     explicit GrTAllocator(int itemsPerBlock)
153         : fAllocator(sizeof(T), itemsPerBlock, NULL) {}
154
155     /**
156      * Adds an item and returns it.
157      *
158      * @return the added item.
159      */
160     T& push_back() {
161         void* item = fAllocator.push_back();
162         SkASSERT(NULL != item);
163         SkNEW_PLACEMENT(item, T);
164         return *(T*)item;
165     }
166
167     T& push_back(const T& t) {
168         void* item = fAllocator.push_back();
169         SkASSERT(NULL != item);
170         SkNEW_PLACEMENT_ARGS(item, T, (t));
171         return *(T*)item;
172     }
173
174     /**
175      * removes all added items
176      */
177     void reset() {
178         int c = fAllocator.count();
179         for (int i = 0; i < c; ++i) {
180             ((T*)fAllocator[i])->~T();
181         }
182         fAllocator.reset();
183     }
184
185     /**
186      * count of items
187      */
188     int count() const {
189         return fAllocator.count();
190     }
191
192     /**
193      * is the count 0
194      */
195     bool empty() const { return fAllocator.empty(); }
196
197     /**
198      * access last item, only call if count() != 0
199      */
200     T& back() {
201         return *(T*)fAllocator.back();
202     }
203
204     /**
205      * access last item, only call if count() != 0
206      */
207     const T& back() const {
208         return *(const T*)fAllocator.back();
209     }
210
211     /**
212      * access item by index.
213      */
214     T& operator[] (int i) {
215         return *(T*)(fAllocator[i]);
216     }
217
218     /**
219      * access item by index.
220      */
221     const T& operator[] (int i) const {
222         return *(const T*)(fAllocator[i]);
223     }
224
225 protected:
226     GrTAllocator(int itemsPerBlock, void* initialBlock)
227         : fAllocator(sizeof(T), itemsPerBlock, initialBlock) {
228     }
229
230 private:
231     GrAllocator fAllocator;
232     typedef SkNoncopyable INHERITED;
233 };
234
235 template <int N, typename T> class GrSTAllocator : public GrTAllocator<T> {
236 private:
237     typedef GrTAllocator<T> INHERITED;
238
239 public:
240     GrSTAllocator() : INHERITED(N, fStorage.get()) {
241     }
242
243 private:
244     SkAlignedSTStorage<N, T> fStorage;
245 };
246
247 #endif