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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 class Iter; | 47 class Iter; |
48 class ReverseIter; | 48 class ReverseIter; |
49 | 49 |
50 /** | 50 /** |
51 * Create a recorder. | 51 * Create a recorder. |
52 * | 52 * |
53 * @param initialSizeInBytes The amount of memory reserved by the recorder
initially, | 53 * @param initialSizeInBytes The amount of memory reserved by the recorder
initially, |
54 and after calls to reset(). | 54 and after calls to reset(). |
55 */ | 55 */ |
56 GrTRecorder(int initialSizeInBytes) | 56 GrTRecorder(int initialSizeInBytes) |
57 : fHeadBlock(MemBlock::Alloc(LengthOf(initialSizeInBytes), NULL)), | 57 : fHeadBlock(MemBlock::Alloc(LengthOf(initialSizeInBytes), nullptr)), |
58 fTailBlock(fHeadBlock), | 58 fTailBlock(fHeadBlock), |
59 fLastItem(NULL) {} | 59 fLastItem(nullptr) {} |
60 | 60 |
61 ~GrTRecorder() { | 61 ~GrTRecorder() { |
62 this->reset(); | 62 this->reset(); |
63 MemBlock::Free(fHeadBlock); | 63 MemBlock::Free(fHeadBlock); |
64 } | 64 } |
65 | 65 |
66 bool empty() { return !fLastItem; } | 66 bool empty() { return !fLastItem; } |
67 | 67 |
68 TBase& back() { | 68 TBase& back() { |
69 SkASSERT(!this->empty()); | 69 SkASSERT(!this->empty()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 }; | 105 }; |
106 static int LengthOf(int bytes) { return (bytes + sizeof(TAlign) - 1) / sizeo
f(TAlign); } | 106 static int LengthOf(int bytes) { return (bytes + sizeof(TAlign) - 1) / sizeo
f(TAlign); } |
107 | 107 |
108 struct Header { | 108 struct Header { |
109 int fTotalLength; // The length of an entry including header, item, and
data in TAligns. | 109 int fTotalLength; // The length of an entry including header, item, and
data in TAligns. |
110 int fPrevLength; // Same but for the previous entry. Used for iterating
backwards. | 110 int fPrevLength; // Same but for the previous entry. Used for iterating
backwards. |
111 }; | 111 }; |
112 template<typename TItem> void* alloc_back(int dataLength); | 112 template<typename TItem> void* alloc_back(int dataLength); |
113 | 113 |
114 struct MemBlock : SkNoncopyable { | 114 struct MemBlock : SkNoncopyable { |
115 /** Allocates a new block and appends it to prev if not NULL. The length
param is in units | 115 /** Allocates a new block and appends it to prev if not nullptr. The len
gth param is in units |
116 of TAlign. */ | 116 of TAlign. */ |
117 static MemBlock* Alloc(int length, MemBlock* prev) { | 117 static MemBlock* Alloc(int length, MemBlock* prev) { |
118 MemBlock* block = reinterpret_cast<MemBlock*>( | 118 MemBlock* block = reinterpret_cast<MemBlock*>( |
119 sk_malloc_throw(sizeof(TAlign) * (length_of<MemBlock>::kValue +
length))); | 119 sk_malloc_throw(sizeof(TAlign) * (length_of<MemBlock>::kValue +
length))); |
120 block->fLength = length; | 120 block->fLength = length; |
121 block->fBack = 0; | 121 block->fBack = 0; |
122 block->fNext = NULL; | 122 block->fNext = nullptr; |
123 block->fPrev = prev; | 123 block->fPrev = prev; |
124 if (prev) { | 124 if (prev) { |
125 SkASSERT(NULL == prev->fNext); | 125 SkASSERT(nullptr == prev->fNext); |
126 prev->fNext = block; | 126 prev->fNext = block; |
127 } | 127 } |
128 return block; | 128 return block; |
129 } | 129 } |
130 | 130 |
131 // Frees from this block forward. Also adjusts prev block's next ptr. | 131 // Frees from this block forward. Also adjusts prev block's next ptr. |
132 static void Free(MemBlock* block) { | 132 static void Free(MemBlock* block) { |
133 if (block && block->fPrev) { | 133 if (block && block->fPrev) { |
134 SkASSERT(block->fPrev->fNext == block); | 134 SkASSERT(block->fPrev->fNext == block); |
135 block->fPrev->fNext = NULL; | 135 block->fPrev->fNext = nullptr; |
136 } | 136 } |
137 while (block) { | 137 while (block) { |
138 MemBlock* next = block->fNext; | 138 MemBlock* next = block->fNext; |
139 sk_free(block); | 139 sk_free(block); |
140 block = next; | 140 block = next; |
141 } | 141 } |
142 } | 142 } |
143 | 143 |
144 TAlign& operator [](int i) { | 144 TAlign& operator [](int i) { |
145 return reinterpret_cast<TAlign*>(this)[length_of<MemBlock>::kValue +
i]; | 145 return reinterpret_cast<TAlign*>(this)[length_of<MemBlock>::kValue +
i]; |
(...skipping 27 matching lines...) Expand all Loading... |
173 Header* header = reinterpret_cast<Header*>( | 173 Header* header = reinterpret_cast<Header*>( |
174 reinterpret_cast<TAlign*>(fLastItem) - length_of<Header>::kValue); | 174 reinterpret_cast<TAlign*>(fLastItem) - length_of<Header>::kValue); |
175 fTailBlock->fBack -= header->fTotalLength; | 175 fTailBlock->fBack -= header->fTotalLength; |
176 reinterpret_cast<TBase*>(fLastItem)->~TBase(); | 176 reinterpret_cast<TBase*>(fLastItem)->~TBase(); |
177 | 177 |
178 int lastItemLength = header->fPrevLength; | 178 int lastItemLength = header->fPrevLength; |
179 | 179 |
180 if (!header->fPrevLength) { | 180 if (!header->fPrevLength) { |
181 // We popped the first entry in the recorder. | 181 // We popped the first entry in the recorder. |
182 SkASSERT(0 == fTailBlock->fBack); | 182 SkASSERT(0 == fTailBlock->fBack); |
183 fLastItem = NULL; | 183 fLastItem = nullptr; |
184 return; | 184 return; |
185 } | 185 } |
186 while (!fTailBlock->fBack) { | 186 while (!fTailBlock->fBack) { |
187 // We popped the last entry in a block that isn't the head block. Move b
ack a block but | 187 // We popped the last entry in a block that isn't the head block. Move b
ack a block but |
188 // don't free it since we'll probably grow into it shortly. | 188 // don't free it since we'll probably grow into it shortly. |
189 fTailBlock = fTailBlock->fPrev; | 189 fTailBlock = fTailBlock->fPrev; |
190 SkASSERT(fTailBlock); | 190 SkASSERT(fTailBlock); |
191 } | 191 } |
192 fLastItem = &(*fTailBlock)[fTailBlock->fBack - lastItemLength + length_of<He
ader>::kValue]; | 192 fLastItem = &(*fTailBlock)[fTailBlock->fBack - lastItemLength + length_of<He
ader>::kValue]; |
193 } | 193 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 * to not have the front item loaded yet; next() must be called first. Usage mod
el: | 243 * to not have the front item loaded yet; next() must be called first. Usage mod
el: |
244 * | 244 * |
245 * GrTRecorder<TBase, TAlign>::Iter iter(recorder); | 245 * GrTRecorder<TBase, TAlign>::Iter iter(recorder); |
246 * while (iter.next()) { | 246 * while (iter.next()) { |
247 * iter->doSomething(); | 247 * iter->doSomething(); |
248 * } | 248 * } |
249 */ | 249 */ |
250 template<typename TBase, typename TAlign> | 250 template<typename TBase, typename TAlign> |
251 class GrTRecorder<TBase, TAlign>::Iter { | 251 class GrTRecorder<TBase, TAlign>::Iter { |
252 public: | 252 public: |
253 Iter(GrTRecorder& recorder) : fBlock(recorder.fHeadBlock), fPosition(0), fIt
em(NULL) {} | 253 Iter(GrTRecorder& recorder) : fBlock(recorder.fHeadBlock), fPosition(0), fIt
em(nullptr) {} |
254 | 254 |
255 bool next() { | 255 bool next() { |
256 while (fPosition >= fBlock->fBack) { | 256 while (fPosition >= fBlock->fBack) { |
257 SkASSERT(fPosition == fBlock->fBack); | 257 SkASSERT(fPosition == fBlock->fBack); |
258 if (!fBlock->fNext) { | 258 if (!fBlock->fNext) { |
259 return false; | 259 return false; |
260 } | 260 } |
261 fBlock = fBlock->fNext; | 261 fBlock = fBlock->fNext; |
262 fPosition = 0; | 262 fPosition = 0; |
263 } | 263 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 iter->~TBase(); | 337 iter->~TBase(); |
338 } | 338 } |
339 | 339 |
340 // Assume the next time this recorder fills up it will use approximately the
same | 340 // Assume the next time this recorder fills up it will use approximately the
same |
341 // amount of space as last time. Leave enough space for up to ~50% growth; f
ree | 341 // amount of space as last time. Leave enough space for up to ~50% growth; f
ree |
342 // everything else. | 342 // everything else. |
343 if (fTailBlock->fBack <= fTailBlock->fLength / 2) { | 343 if (fTailBlock->fBack <= fTailBlock->fLength / 2) { |
344 MemBlock::Free(fTailBlock->fNext); | 344 MemBlock::Free(fTailBlock->fNext); |
345 } else if (fTailBlock->fNext) { | 345 } else if (fTailBlock->fNext) { |
346 MemBlock::Free(fTailBlock->fNext->fNext); | 346 MemBlock::Free(fTailBlock->fNext->fNext); |
347 fTailBlock->fNext->fNext = NULL; | 347 fTailBlock->fNext->fNext = nullptr; |
348 } | 348 } |
349 | 349 |
350 for (MemBlock* block = fHeadBlock; block; block = block->fNext) { | 350 for (MemBlock* block = fHeadBlock; block; block = block->fNext) { |
351 block->fBack = 0; | 351 block->fBack = 0; |
352 } | 352 } |
353 | 353 |
354 fTailBlock = fHeadBlock; | 354 fTailBlock = fHeadBlock; |
355 fLastItem = NULL; | 355 fLastItem = nullptr; |
356 } | 356 } |
357 | 357 |
358 //////////////////////////////////////////////////////////////////////////////// | 358 //////////////////////////////////////////////////////////////////////////////// |
359 | 359 |
360 template<typename TItem> struct GrTRecorderAllocWrapper { | 360 template<typename TItem> struct GrTRecorderAllocWrapper { |
361 GrTRecorderAllocWrapper() : fDataLength(0) {} | 361 GrTRecorderAllocWrapper() : fDataLength(0) {} |
362 | 362 |
363 template <typename TBase, typename TAlign> | 363 template <typename TBase, typename TAlign> |
364 GrTRecorderAllocWrapper(const GrTRecorder<TBase, TAlign>&, int sizeOfData) | 364 GrTRecorderAllocWrapper(const GrTRecorder<TBase, TAlign>&, int sizeOfData) |
365 : fDataLength(GrTRecorder<TBase, TAlign>::LengthOf(sizeOfData)) {} | 365 : fDataLength(GrTRecorder<TBase, TAlign>::LengthOf(sizeOfData)) {} |
(...skipping 15 matching lines...) Expand all Loading... |
381 SK_CRASH(); | 381 SK_CRASH(); |
382 } | 382 } |
383 | 383 |
384 #define GrNEW_APPEND_TO_RECORDER(recorder, type_name, args) \ | 384 #define GrNEW_APPEND_TO_RECORDER(recorder, type_name, args) \ |
385 (new (recorder, GrTRecorderAllocWrapper<type_name>()) type_name args) | 385 (new (recorder, GrTRecorderAllocWrapper<type_name>()) type_name args) |
386 | 386 |
387 #define GrNEW_APPEND_WITH_DATA_TO_RECORDER(recorder, type_name, args, size_of_da
ta) \ | 387 #define GrNEW_APPEND_WITH_DATA_TO_RECORDER(recorder, type_name, args, size_of_da
ta) \ |
388 (new (recorder, GrTRecorderAllocWrapper<type_name>(recorder, size_of_data))
type_name args) | 388 (new (recorder, GrTRecorderAllocWrapper<type_name>(recorder, size_of_data))
type_name args) |
389 | 389 |
390 #endif | 390 #endif |
OLD | NEW |