blob: 673d0ab43dde89fe9a64c89a8ca65e3d3bcac607 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
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
23class GrAutoMalloc : GrNoncopyable {
24public:
25 GrAutoMalloc(size_t bytes) : fPtr(GrMalloc(bytes)) {}
26 ~GrAutoMalloc() { GrFree(fPtr); }
27
28 /**
29 * Return the allocated memory, or NULL if it has already been freed or
30 * detached.
31 */
32 void* get() const { return fPtr; }
33
34 /**
35 * transfer ownership of the memory to the caller. It must be freed with
36 * a call to GrFree()
37 */
38 void* detach() {
39 void* ptr = fPtr;
40 fPtr = NULL; // we no longer own the block
41 return ptr;
42 }
43
44 /**
45 * free the block now. get() will now return NULL
46 */
47 void free() {
48 GrFree(fPtr);
49 fPtr = NULL;
50 }
51
52private:
53 void* fPtr;
54};
55
56/**
57 * Variant of GrAutoMalloc with a compile-time specified byte size that is
58 * pre-allocated in the class object, avoiding a call to to GrMalloc if
59 * possible.
60 */
61template <size_t SIZE> class GrAutoSMalloc : GrNoncopyable {
62public:
63 GrAutoSMalloc() {
64 fPtr = fStorage;
65 fAllocatedBytes = SIZE;
66 }
67
68 explicit GrAutoSMalloc(size_t bytes) {
69 if (bytes > SIZE) {
70 fPtr = GrMalloc(bytes);
71 fAllocatedBytes = bytes;
72 } else {
73 fPtr = fStorage;
74 fAllocatedBytes = SIZE;
75 }
76 }
77
78 ~GrAutoSMalloc() {
79 if (fPtr != (void*)fStorage) {
80 GrFree(fPtr);
81 }
82 }
83
84 /**
85 * Return the allocated memory, or NULL if it has already been freed or
86 * detached.
87 */
88 void* get() const { return fPtr; }
89
90 /**
91 * Reallocates to a new size. May or may not call malloc. The contents
92 * are not preserved. If growOnly is true it will never reduce the
93 * allocated size.
94 */
95 void* realloc(size_t newSize, bool growOnly = false) {
96 if (newSize <= SIZE) {
97 if (NULL == fPtr) {
98 fPtr = fStorage;
99 fAllocatedBytes = SIZE;
100 } else if (!growOnly && fPtr != (void*)fStorage) {
101 GrFree(fPtr);
102 fPtr = fStorage;
103 fAllocatedBytes = SIZE;
104 }
105 } else if ((newSize > fAllocatedBytes) ||
106 (!growOnly && newSize < (fAllocatedBytes >> 1))) {
107 if (NULL != fPtr && fPtr != (void*)fStorage) {
108 GrFree(fPtr);
109 }
110 fPtr = GrMalloc(newSize);
111 fAllocatedBytes = newSize;
112 }
113 GrAssert(fAllocatedBytes >= newSize);
114 GrAssert((fPtr == fStorage) == (fAllocatedBytes == SIZE));
115 GR_DEBUGCODE(memset(fPtr, 0xEF, fAllocatedBytes));
116 return fPtr;
117 }
118
119 /**
120 * free the block now. get() will now return NULL
121 */
122 void free() {
123 if (fPtr != (void*)fStorage) {
124 GrFree(fPtr);
125 }
126 fAllocatedBytes = 0;
127 fPtr = NULL;
128 }
129
130private:
131 void* fPtr;
132 uint32_t fAllocatedBytes;
133 uint32_t fStorage[GrALIGN4(SIZE) >> 2];
134};
135
136/**
137 * Variant of GrAutoMalloc with a compile-time specified byte size that is
138 * pre-allocated in the class object, avoiding a call to to GrMalloc if
139 * possible.
140 */
141template <int COUNT, typename T>
142class GrAutoSTMalloc : public GrAutoSMalloc<COUNT * sizeof(T)> {
143public:
144 GrAutoSTMalloc(int count) : GrAutoSMalloc<COUNT * sizeof(T)>(count * sizeof(T)) {}
145
146 operator T*() { return (T*)this->get(); }
147};
148
149
150#endif
151