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