Chromium Code Reviews| 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 |