Index: src/gpu/GrTRecorder.h |
diff --git a/src/gpu/GrTRecorder.h b/src/gpu/GrTRecorder.h |
index 17c4213993d8a994db47718bc6f89ff37e297b6e..ab559e4a5962b5abb5f59ec981e21c131fd90b39 100644 |
--- a/src/gpu/GrTRecorder.h |
+++ b/src/gpu/GrTRecorder.h |
@@ -151,10 +151,12 @@ template<typename TItem> |
TItem* GrTRecorder<TBase, TAlign>::alloc_back(int dataLength) { |
const int totalLength = length_of<Header>::kValue + length_of<TItem>::kValue + dataLength; |
- if (fTailBlock->fBack + totalLength > fTailBlock->fLength) { |
- SkASSERT(!fTailBlock->fNext); |
- fTailBlock->fNext = MemBlock::Alloc(SkTMax(2 * fTailBlock->fLength, totalLength)); |
+ while (fTailBlock->fBack + totalLength > fTailBlock->fLength) { |
+ if (!fTailBlock->fNext) { |
+ fTailBlock->fNext = MemBlock::Alloc(SkTMax(2 * fTailBlock->fLength, totalLength)); |
+ } |
fTailBlock = fTailBlock->fNext; |
+ SkASSERT(0 == fTailBlock->fBack); |
} |
Header* header = reinterpret_cast<Header*>(&(*fTailBlock)[fTailBlock->fBack]); |
@@ -183,12 +185,11 @@ public: |
Iter(GrTRecorder& recorder) : fBlock(recorder.fHeadBlock), fPosition(0), fItem(NULL) {} |
bool next() { |
- if (fPosition >= fBlock->fBack) { |
+ while (fPosition >= fBlock->fBack) { |
SkASSERT(fPosition == fBlock->fBack); |
if (!fBlock->fNext) { |
return false; |
} |
- SkASSERT(0 != fBlock->fNext->fBack); |
fBlock = fBlock->fNext; |
fPosition = 0; |
} |
@@ -218,9 +219,22 @@ void GrTRecorder<TBase, TAlign>::reset() { |
while (iter.next()) { |
iter->~TBase(); |
} |
- fHeadBlock->fBack = 0; |
- MemBlock::Free(fHeadBlock->fNext); |
- fHeadBlock->fNext = NULL; |
+ |
+ // 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.
|
+ // amount of space as last time. Leave enough space for up to ~50% growth; free |
+ // everything else. |
+ if (fTailBlock->fBack <= fTailBlock->fLength / 2) { |
+ MemBlock::Free(fTailBlock->fNext); |
+ fTailBlock->fNext = NULL; |
+ } else if (fTailBlock->fNext) { |
+ MemBlock::Free(fTailBlock->fNext->fNext); |
+ fTailBlock->fNext->fNext = NULL; |
+ } |
+ |
+ for (MemBlock* block = fHeadBlock; block; block = block->fNext) { |
+ block->fBack = 0; |
+ } |
+ |
fTailBlock = fHeadBlock; |
fLastItem = NULL; |
} |