| 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 |