OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrTRecorder_DEFINED | 8 #ifndef GrTRecorder_DEFINED |
9 #define GrTRecorder_DEFINED | 9 #define GrTRecorder_DEFINED |
10 | 10 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
144 friend class Iter; | 144 friend class Iter; |
145 }; | 145 }; |
146 | 146 |
147 //////////////////////////////////////////////////////////////////////////////// | 147 //////////////////////////////////////////////////////////////////////////////// |
148 | 148 |
149 template<typename TBase, typename TAlign> | 149 template<typename TBase, typename TAlign> |
150 template<typename TItem> | 150 template<typename TItem> |
151 TItem* GrTRecorder<TBase, TAlign>::alloc_back(int dataLength) { | 151 TItem* GrTRecorder<TBase, TAlign>::alloc_back(int dataLength) { |
152 const int totalLength = length_of<Header>::kValue + length_of<TItem>::kValue + dataLength; | 152 const int totalLength = length_of<Header>::kValue + length_of<TItem>::kValue + dataLength; |
153 | 153 |
154 if (fTailBlock->fBack + totalLength > fTailBlock->fLength) { | 154 while (fTailBlock->fBack + totalLength > fTailBlock->fLength) { |
155 SkASSERT(!fTailBlock->fNext); | 155 if (!fTailBlock->fNext) { |
156 fTailBlock->fNext = MemBlock::Alloc(SkTMax(2 * fTailBlock->fLength, tota lLength)); | 156 fTailBlock->fNext = MemBlock::Alloc(SkTMax(2 * fTailBlock->fLength, totalLength)); |
157 } | |
157 fTailBlock = fTailBlock->fNext; | 158 fTailBlock = fTailBlock->fNext; |
159 SkASSERT(0 == fTailBlock->fBack); | |
158 } | 160 } |
159 | 161 |
160 Header* header = reinterpret_cast<Header*>(&(*fTailBlock)[fTailBlock->fBack] ); | 162 Header* header = reinterpret_cast<Header*>(&(*fTailBlock)[fTailBlock->fBack] ); |
161 TItem* rawPtr = reinterpret_cast<TItem*>( | 163 TItem* rawPtr = reinterpret_cast<TItem*>( |
162 &(*fTailBlock)[fTailBlock->fBack + length_of<Header>::kV alue]); | 164 &(*fTailBlock)[fTailBlock->fBack + length_of<Header>::kV alue]); |
163 | 165 |
164 header->fTotalLength = totalLength; | 166 header->fTotalLength = totalLength; |
165 fLastItem = rawPtr; | 167 fLastItem = rawPtr; |
166 fTailBlock->fBack += totalLength; | 168 fTailBlock->fBack += totalLength; |
167 | 169 |
168 // FIXME: We currently require that the base and subclass share the same sta rt address. | 170 // FIXME: We currently require that the base and subclass share the same sta rt address. |
169 // This is not required by the C++ spec, and is likely to not be true in the case of | 171 // This is not required by the C++ spec, and is likely to not be true in the case of |
170 // multiple inheritance or a base class that doesn't have virtual methods (w hen the | 172 // multiple inheritance or a base class that doesn't have virtual methods (w hen the |
171 // subclass does). It would be ideal to find a more robust solution that com es at no | 173 // subclass does). It would be ideal to find a more robust solution that com es at no |
172 // extra cost to performance or code generality. | 174 // extra cost to performance or code generality. |
173 SkDEBUGCODE(void* baseAddr = fLastItem; | 175 SkDEBUGCODE(void* baseAddr = fLastItem; |
174 void* subclassAddr = rawPtr); | 176 void* subclassAddr = rawPtr); |
175 SkASSERT(baseAddr == subclassAddr); | 177 SkASSERT(baseAddr == subclassAddr); |
176 | 178 |
177 return rawPtr; | 179 return rawPtr; |
178 } | 180 } |
179 | 181 |
180 template<typename TBase, typename TAlign> | 182 template<typename TBase, typename TAlign> |
181 class GrTRecorder<TBase, TAlign>::Iter { | 183 class GrTRecorder<TBase, TAlign>::Iter { |
182 public: | 184 public: |
183 Iter(GrTRecorder& recorder) : fBlock(recorder.fHeadBlock), fPosition(0), fIt em(NULL) {} | 185 Iter(GrTRecorder& recorder) : fBlock(recorder.fHeadBlock), fPosition(0), fIt em(NULL) {} |
184 | 186 |
185 bool next() { | 187 bool next() { |
186 if (fPosition >= fBlock->fBack) { | 188 while (fPosition >= fBlock->fBack) { |
187 SkASSERT(fPosition == fBlock->fBack); | 189 SkASSERT(fPosition == fBlock->fBack); |
188 if (!fBlock->fNext) { | 190 if (!fBlock->fNext) { |
189 return false; | 191 return false; |
190 } | 192 } |
191 SkASSERT(0 != fBlock->fNext->fBack); | |
192 fBlock = fBlock->fNext; | 193 fBlock = fBlock->fNext; |
193 fPosition = 0; | 194 fPosition = 0; |
194 } | 195 } |
195 | 196 |
196 Header* header = reinterpret_cast<Header*>(&(*fBlock)[fPosition]); | 197 Header* header = reinterpret_cast<Header*>(&(*fBlock)[fPosition]); |
197 fItem = reinterpret_cast<TBase*>(&(*fBlock)[fPosition + length_of<Header >::kValue]); | 198 fItem = reinterpret_cast<TBase*>(&(*fBlock)[fPosition + length_of<Header >::kValue]); |
198 fPosition += header->fTotalLength; | 199 fPosition += header->fTotalLength; |
199 return true; | 200 return true; |
200 } | 201 } |
201 | 202 |
202 TBase* get() const { | 203 TBase* get() const { |
203 SkASSERT(fItem); | 204 SkASSERT(fItem); |
204 return fItem; | 205 return fItem; |
205 } | 206 } |
206 | 207 |
207 TBase* operator->() const { return this->get(); } | 208 TBase* operator->() const { return this->get(); } |
208 | 209 |
209 private: | 210 private: |
210 MemBlock* fBlock; | 211 MemBlock* fBlock; |
211 int fPosition; | 212 int fPosition; |
212 TBase* fItem; | 213 TBase* fItem; |
213 }; | 214 }; |
214 | 215 |
215 template<typename TBase, typename TAlign> | 216 template<typename TBase, typename TAlign> |
216 void GrTRecorder<TBase, TAlign>::reset() { | 217 void GrTRecorder<TBase, TAlign>::reset() { |
217 Iter iter(*this); | 218 Iter iter(*this); |
218 while (iter.next()) { | 219 while (iter.next()) { |
219 iter->~TBase(); | 220 iter->~TBase(); |
220 } | 221 } |
221 fHeadBlock->fBack = 0; | 222 |
222 MemBlock::Free(fHeadBlock->fNext); | 223 // Assume the next time this recorder fills up it will use approximately the same |
bsalomon
2014/11/07 20:06:42
In the future we might want to consider exposing c
Chris Dalton
2014/11/07 20:42:39
Agreed.
| |
223 fHeadBlock->fNext = NULL; | 224 // amount of space as last time. Leave enough space for up to ~50% growth; f ree |
225 // everything else. | |
226 if (fTailBlock->fBack <= fTailBlock->fLength / 2) { | |
227 MemBlock::Free(fTailBlock->fNext); | |
228 fTailBlock->fNext = NULL; | |
229 } else if (fTailBlock->fNext) { | |
230 MemBlock::Free(fTailBlock->fNext->fNext); | |
231 fTailBlock->fNext->fNext = NULL; | |
232 } | |
233 | |
234 for (MemBlock* block = fHeadBlock; block; block = block->fNext) { | |
235 block->fBack = 0; | |
236 } | |
237 | |
224 fTailBlock = fHeadBlock; | 238 fTailBlock = fHeadBlock; |
225 fLastItem = NULL; | 239 fLastItem = NULL; |
226 } | 240 } |
227 | 241 |
228 //////////////////////////////////////////////////////////////////////////////// | 242 //////////////////////////////////////////////////////////////////////////////// |
229 | 243 |
230 template<typename TItem> struct GrTRecorderAllocWrapper { | 244 template<typename TItem> struct GrTRecorderAllocWrapper { |
231 GrTRecorderAllocWrapper() : fDataLength(0) {} | 245 GrTRecorderAllocWrapper() : fDataLength(0) {} |
232 | 246 |
233 template <typename TBase, typename TAlign> | 247 template <typename TBase, typename TAlign> |
(...skipping 17 matching lines...) Expand all Loading... | |
251 SK_CRASH(); | 265 SK_CRASH(); |
252 } | 266 } |
253 | 267 |
254 #define GrNEW_APPEND_TO_RECORDER(recorder, type_name, args) \ | 268 #define GrNEW_APPEND_TO_RECORDER(recorder, type_name, args) \ |
255 (new (recorder, GrTRecorderAllocWrapper<type_name>()) type_name args) | 269 (new (recorder, GrTRecorderAllocWrapper<type_name>()) type_name args) |
256 | 270 |
257 #define GrNEW_APPEND_WITH_DATA_TO_RECORDER(recorder, type_name, args, size_of_da ta) \ | 271 #define GrNEW_APPEND_WITH_DATA_TO_RECORDER(recorder, type_name, args, size_of_da ta) \ |
258 (new (recorder, GrTRecorderAllocWrapper<type_name>(recorder, size_of_data)) type_name args) | 272 (new (recorder, GrTRecorderAllocWrapper<type_name>(recorder, size_of_data)) type_name args) |
259 | 273 |
260 #endif | 274 #endif |
OLD | NEW |