Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: src/gpu/GrTRecorder.h

Issue 1035083004: Add ReverseIter to GrTRecorder (Closed) Base URL: https://skia.googlesource.com/skia.git@upload_ongetblendmode
Patch Set: Rearrange headers Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/GrTRecorderTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 28 matching lines...) Expand all
39 * on an obscure compiler) may not be compatible. This is runtime asserted 39 * on an obscure compiler) may not be compatible. This is runtime asserted
40 * in debug builds. 40 * in debug builds.
41 * 41 *
42 * @param TAlign A type whose size is the desired memory alignment for object a llocations. 42 * @param TAlign A type whose size is the desired memory alignment for object a llocations.
43 * This should be the largest known alignment requirement for all objects 43 * This should be the largest known alignment requirement for all objects
44 * that may be stored in the list. 44 * that may be stored in the list.
45 */ 45 */
46 template<typename TBase, typename TAlign> class GrTRecorder : SkNoncopyable { 46 template<typename TBase, typename TAlign> class GrTRecorder : SkNoncopyable {
47 public: 47 public:
48 class Iter; 48 class Iter;
49 class ReverseIter;
49 50
50 /** 51 /**
51 * Create a recorder. 52 * Create a recorder.
52 * 53 *
53 * @param initialSizeInBytes The amount of memory reserved by the recorder initially, 54 * @param initialSizeInBytes The amount of memory reserved by the recorder initially,
54 and after calls to reset(). 55 and after calls to reset().
55 */ 56 */
56 GrTRecorder(int initialSizeInBytes) 57 GrTRecorder(int initialSizeInBytes)
57 : fHeadBlock(MemBlock::Alloc(LengthOf(initialSizeInBytes), NULL)), 58 : fHeadBlock(MemBlock::Alloc(LengthOf(initialSizeInBytes), NULL)),
58 fTailBlock(fHeadBlock), 59 fTailBlock(fHeadBlock),
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 156
156 TBase* fLastItem; 157 TBase* fLastItem;
157 158
158 template<typename TItem> friend struct GrTRecorderAllocWrapper; 159 template<typename TItem> friend struct GrTRecorderAllocWrapper;
159 160
160 template <typename UBase, typename UAlign, typename UItem> 161 template <typename UBase, typename UAlign, typename UItem>
161 friend void* operator new(size_t, GrTRecorder<UBase, UAlign>&, 162 friend void* operator new(size_t, GrTRecorder<UBase, UAlign>&,
162 const GrTRecorderAllocWrapper<UItem>&); 163 const GrTRecorderAllocWrapper<UItem>&);
163 164
164 friend class Iter; 165 friend class Iter;
166 friend class ReverseIter;
165 }; 167 };
166 168
167 //////////////////////////////////////////////////////////////////////////////// 169 ////////////////////////////////////////////////////////////////////////////////
168 170
169 template<typename TBase, typename TAlign> 171 template<typename TBase, typename TAlign>
170 void GrTRecorder<TBase, TAlign>::pop_back() { 172 void GrTRecorder<TBase, TAlign>::pop_back() {
171 SkASSERT(fLastItem); 173 SkASSERT(fLastItem);
172 Header* header = reinterpret_cast<Header*>( 174 Header* header = reinterpret_cast<Header*>(
173 reinterpret_cast<TAlign*>(fLastItem) - length_of<Header>::kValue); 175 reinterpret_cast<TAlign*>(fLastItem) - length_of<Header>::kValue);
174 fTailBlock->fBack -= header->fTotalLength; 176 fTailBlock->fBack -= header->fTotalLength;
175 fLastItem->~TBase(); 177 fLastItem->~TBase();
176 178
177 int lastItemLength = header->fPrevLength; 179 int lastItemLength = header->fPrevLength;
178 180
179 if (!header->fPrevLength) { 181 if (!header->fPrevLength) {
180 // We popped the first entry in the recorder. 182 // We popped the first entry in the recorder.
181 SkASSERT(0 == fTailBlock->fBack); 183 SkASSERT(0 == fTailBlock->fBack);
182 fLastItem = NULL; 184 fLastItem = NULL;
183 return; 185 return;
184 } 186 }
185 if (!fTailBlock->fBack) { 187 while (!fTailBlock->fBack) {
186 // We popped the last entry in a block that isn't the head block. Move b ack a block but 188 // We popped the last entry in a block that isn't the head block. Move b ack a block but
187 // don't free it since we'll probably grow into it shortly. 189 // don't free it since we'll probably grow into it shortly.
188 fTailBlock = fTailBlock->fPrev; 190 fTailBlock = fTailBlock->fPrev;
189 SkASSERT(fTailBlock); 191 SkASSERT(fTailBlock);
190 } 192 }
191 fLastItem = reinterpret_cast<TBase*>( 193 fLastItem = reinterpret_cast<TBase*>(
192 &(*fTailBlock)[fTailBlock->fBack - lastItemLength + length_of<Header>::k Value]); 194 &(*fTailBlock)[fTailBlock->fBack - lastItemLength + length_of<Header>::k Value]);
193 } 195 }
194 196
195 template<typename TBase, typename TAlign> 197 template<typename TBase, typename TAlign>
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 // multiple inheritance or a base class that doesn't have virtual methods (w hen the 234 // multiple inheritance or a base class that doesn't have virtual methods (w hen the
233 // subclass does). It would be ideal to find a more robust solution that com es at no 235 // subclass does). It would be ideal to find a more robust solution that com es at no
234 // extra cost to performance or code generality. 236 // extra cost to performance or code generality.
235 SkDEBUGCODE(void* baseAddr = fLastItem; 237 SkDEBUGCODE(void* baseAddr = fLastItem;
236 void* subclassAddr = rawPtr); 238 void* subclassAddr = rawPtr);
237 SkASSERT(baseAddr == subclassAddr); 239 SkASSERT(baseAddr == subclassAddr);
238 240
239 return rawPtr; 241 return rawPtr;
240 } 242 }
241 243
244 /**
245 * Iterates through a recorder from front to back. The initial state of the iter ator is
246 * to not have the front item loaded yet; next() must be called first. Usage mod el:
247 *
248 * GrTRecorder<TBase, TAlign>::Iter iter(recorder);
249 * while (iter.next()) {
250 * iter->doSomething();
251 * }
252 */
242 template<typename TBase, typename TAlign> 253 template<typename TBase, typename TAlign>
243 class GrTRecorder<TBase, TAlign>::Iter { 254 class GrTRecorder<TBase, TAlign>::Iter {
244 public: 255 public:
245 Iter(GrTRecorder& recorder) : fBlock(recorder.fHeadBlock), fPosition(0), fIt em(NULL) {} 256 Iter(GrTRecorder& recorder) : fBlock(recorder.fHeadBlock), fPosition(0), fIt em(NULL) {}
246 257
247 bool next() { 258 bool next() {
248 while (fPosition >= fBlock->fBack) { 259 while (fPosition >= fBlock->fBack) {
249 SkASSERT(fPosition == fBlock->fBack); 260 SkASSERT(fPosition == fBlock->fBack);
250 if (!fBlock->fNext) { 261 if (!fBlock->fNext) {
251 return false; 262 return false;
(...skipping 14 matching lines...) Expand all
266 } 277 }
267 278
268 TBase* operator->() const { return this->get(); } 279 TBase* operator->() const { return this->get(); }
269 280
270 private: 281 private:
271 MemBlock* fBlock; 282 MemBlock* fBlock;
272 int fPosition; 283 int fPosition;
273 TBase* fItem; 284 TBase* fItem;
274 }; 285 };
275 286
287 /**
288 * Iterates through a recorder in reverse, from back to front. This version mirr ors "Iter",
289 * so the initial state is to have recorder.back() loaded already. (Note that th is will
290 * assert if the recorder is empty.) Usage model:
291 *
292 * GrTRecorder<TBase, TAlign>::ReverseIter reverseIter(recorder);
293 * do {
294 * reverseIter->doSomething();
295 * } while (reverseIter.previous());
296 */
297 template<typename TBase, typename TAlign>
298 class GrTRecorder<TBase, TAlign>::ReverseIter {
299 public:
300 ReverseIter(GrTRecorder& recorder)
301 : fBlock(recorder.fTailBlock),
302 fItem(&recorder.back()) {
303 Header* lastHeader = reinterpret_cast<Header*>(
304 reinterpret_cast<TAlign*>(fItem) - length_of<Header>::kValue);
305 fPosition = fBlock->fBack - lastHeader->fTotalLength;
306 }
307
308 bool previous() {
309 Header* header = reinterpret_cast<Header*>(&(*fBlock)[fPosition]);
310
311 while (0 == fPosition) {
312 if (!fBlock->fPrev) {
313 // We've reached the front of the recorder.
314 return false;
315 }
316 fBlock = fBlock->fPrev;
317 fPosition = fBlock->fBack;
318 }
319
320 fPosition -= header->fPrevLength;
321 SkASSERT(fPosition >= 0);
322
323 fItem = reinterpret_cast<TBase*>(&(*fBlock)[fPosition + length_of<Header >::kValue]);
324 return true;
325 }
326
327 TBase* get() const { return fItem; }
328 TBase* operator->() const { return this->get(); }
329
330 private:
331 MemBlock* fBlock;
332 int fPosition;
333 TBase* fItem;
334 };
335
276 template<typename TBase, typename TAlign> 336 template<typename TBase, typename TAlign>
277 void GrTRecorder<TBase, TAlign>::reset() { 337 void GrTRecorder<TBase, TAlign>::reset() {
278 Iter iter(*this); 338 Iter iter(*this);
279 while (iter.next()) { 339 while (iter.next()) {
280 iter->~TBase(); 340 iter->~TBase();
281 } 341 }
282 342
283 // Assume the next time this recorder fills up it will use approximately the same 343 // Assume the next time this recorder fills up it will use approximately the same
284 // amount of space as last time. Leave enough space for up to ~50% growth; f ree 344 // amount of space as last time. Leave enough space for up to ~50% growth; f ree
285 // everything else. 345 // everything else.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 SK_CRASH(); 384 SK_CRASH();
325 } 385 }
326 386
327 #define GrNEW_APPEND_TO_RECORDER(recorder, type_name, args) \ 387 #define GrNEW_APPEND_TO_RECORDER(recorder, type_name, args) \
328 (new (recorder, GrTRecorderAllocWrapper<type_name>()) type_name args) 388 (new (recorder, GrTRecorderAllocWrapper<type_name>()) type_name args)
329 389
330 #define GrNEW_APPEND_WITH_DATA_TO_RECORDER(recorder, type_name, args, size_of_da ta) \ 390 #define GrNEW_APPEND_WITH_DATA_TO_RECORDER(recorder, type_name, args, size_of_da ta) \
331 (new (recorder, GrTRecorderAllocWrapper<type_name>(recorder, size_of_data)) type_name args) 391 (new (recorder, GrTRecorderAllocWrapper<type_name>(recorder, size_of_data)) type_name args)
332 392
333 #endif 393 #endif
OLDNEW
« no previous file with comments | « no previous file | tests/GrTRecorderTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698