• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     Copyright 2010 Google Inc.
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8          http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15  */
16 
17 
18 #ifndef GrMemory_DEFINED
19 #define GrMemory_DEFINED
20 
21 #include "GrNoncopyable.h"
22 
23 class GrAutoMalloc : GrNoncopyable {
24 public:
GrAutoMalloc()25     GrAutoMalloc() : fPtr(NULL), fAllocatedBytes(0){
26     }
27 
GrAutoMalloc(size_t bytes)28     GrAutoMalloc(size_t bytes) : fPtr(GrMalloc(bytes)), fAllocatedBytes(bytes) {}
~GrAutoMalloc()29     ~GrAutoMalloc() { GrFree(fPtr); }
30 
31     /**
32      *  Return the allocated memory, or NULL if it has already been freed or
33      *  detached.
34      */
get()35     void* get() const { return fPtr; }
36 
size()37     size_t size() const { return fAllocatedBytes; }
38 
39     /**
40      *  transfer ownership of the memory to the caller. It must be freed with
41      *  a call to GrFree()
42      */
detach()43     void* detach() {
44         void* ptr = fPtr;
45         fPtr = NULL;    // we no longer own the block
46         fAllocatedBytes = 0;
47         return ptr;
48     }
49 
50     /**
51      *  Reallocates to a new size. May or may not call malloc. The contents
52      *  are not preserved. If growOnly is true it will never reduce the
53      *  allocated size.
54      */
55     void* realloc(size_t newSize, bool growOnly = false) {
56         bool alloc;
57         if (growOnly) {
58             alloc = newSize > fAllocatedBytes;
59         } else {
60             alloc = newSize != fAllocatedBytes;
61         }
62         if (alloc) {
63             GrFree(fPtr);
64             fPtr = newSize ? GrMalloc(newSize) : NULL;
65             fAllocatedBytes = newSize;
66         }
67         GrAssert(fAllocatedBytes >= newSize);
68         GR_DEBUGCODE(memset(fPtr, 0xEF, fAllocatedBytes));
69         return fPtr;
70     }
71 
72     /**
73      *  free the block now. get() will now return NULL
74      */
free()75     void free() {
76         GrFree(fPtr);
77         fPtr = NULL;
78         fAllocatedBytes = 0;
79     }
80 
81 private:
82     void* fPtr;
83     size_t fAllocatedBytes;
84 };
85 
86 /**
87  *  Variant of GrAutoMalloc with a compile-time specified byte size that is
88  *  pre-allocated in the class object, avoiding a call to to GrMalloc if
89  *  possible.
90  */
91 template <size_t SIZE> class GrAutoSMalloc : GrNoncopyable {
92 public:
GrAutoSMalloc()93     GrAutoSMalloc() {
94         fPtr = fStorage;
95         fAllocatedBytes = SIZE;
96     }
97 
GrAutoSMalloc(size_t bytes)98     explicit GrAutoSMalloc(size_t bytes) {
99         if (bytes > SIZE) {
100             fPtr = GrMalloc(bytes);
101             fAllocatedBytes = bytes;
102         } else {
103             fPtr = fStorage;
104             fAllocatedBytes = SIZE;
105         }
106     }
107 
~GrAutoSMalloc()108     ~GrAutoSMalloc() {
109         if (fPtr != (void*)fStorage) {
110             GrFree(fPtr);
111         }
112     }
113 
114     /**
115      *  Return the allocated memory, or NULL if it has already been freed or
116      *  detached.
117      */
get()118     void* get() const { return fPtr; }
119 
120     /**
121      *  Reallocates to a new size. May or may not call malloc. The contents
122      *  are not preserved. If growOnly is true it will never reduce the
123      *  allocated size.
124      */
125     void* realloc(size_t newSize, bool growOnly = false) {
126         if (newSize <= SIZE) {
127             if (NULL == fPtr) {
128                 fPtr = fStorage;
129                 fAllocatedBytes = SIZE;
130             } else if (!growOnly && fPtr != (void*)fStorage) {
131                 GrFree(fPtr);
132                 fPtr = fStorage;
133                 fAllocatedBytes = SIZE;
134             }
135         } else if ((newSize > fAllocatedBytes) ||
136                    (!growOnly && newSize < (fAllocatedBytes >> 1))) {
137             if (NULL != fPtr && fPtr != (void*)fStorage) {
138                 GrFree(fPtr);
139             }
140             fPtr = GrMalloc(newSize);
141             fAllocatedBytes = newSize;
142         }
143         GrAssert(fAllocatedBytes >= newSize);
144         GrAssert((fPtr == fStorage) == (fAllocatedBytes == SIZE));
145         GR_DEBUGCODE(memset(fPtr, 0xEF, fAllocatedBytes));
146         return fPtr;
147     }
148 
149     /**
150      *  free the block now. get() will now return NULL
151      */
free()152     void free() {
153         if (fPtr != (void*)fStorage) {
154             GrFree(fPtr);
155         }
156         fAllocatedBytes = 0;
157         fPtr = NULL;
158     }
159 
160 private:
161     void*    fPtr;
162     uint32_t fAllocatedBytes;
163     uint32_t fStorage[GrALIGN4(SIZE) >> 2];
164 };
165 
166 /**
167  *  Variant of GrAutoMalloc with a compile-time specified byte size that is
168  *  pre-allocated in the class object, avoiding a call to to GrMalloc if
169  *  possible.
170  */
171 template <int COUNT, typename T>
172 class GrAutoSTMalloc : public GrAutoSMalloc<COUNT * sizeof(T)> {
173 public:
GrAutoSTMalloc(int count)174     GrAutoSTMalloc(int count) : GrAutoSMalloc<COUNT * sizeof(T)>(count * sizeof(T)) {}
175 
176     operator T*() { return (T*)this->get(); }
177 };
178 
179 
180 #endif
181 
182