Index: src/core/SkTLList.h |
diff --git a/src/core/SkTLList.h b/src/core/SkTLList.h |
index 48e81bdac1803fb18082101e77d7e58654447048..58fa3f4aac8db6dc8a8343d71977f4f2a8007d4e 100644 |
--- a/src/core/SkTLList.h |
+++ b/src/core/SkTLList.h |
@@ -38,14 +38,10 @@ private: |
public: |
class Iter; |
- SkTLList() : fCount(0) { |
- fFirstBlock.fNodesInUse = 0; |
- for (unsigned int i = 0; i < N; ++i) { |
- fFreeList.addToHead(fFirstBlock.fNodes + i); |
- fFirstBlock.fNodes[i].fBlock = &fFirstBlock; |
- } |
- this->validate(); |
- } |
+ // Having fCount initialized to -1 indicates that the first time we attempt to grab a free node |
+ // all the nodes in the pre-allocated first block need to be inserted into the free list. This |
+ // allows us to skip that loop in instances when the list is never populated. |
+ SkTLList() : fCount(-1) {} |
~SkTLList() { |
this->validate(); |
@@ -148,18 +144,19 @@ public: |
this->remove(iter.get()); |
iter = next; |
} |
- SkASSERT(0 == fCount); |
+ SkASSERT(0 == fCount || -1 == fCount); |
this->validate(); |
} |
- int count() const { return fCount; } |
- bool isEmpty() const { this->validate(); return 0 == fCount; } |
+ int count() const { return SkTMax(fCount ,0); } |
+ bool isEmpty() const { this->validate(); return 0 == fCount || -1 == fCount; } |
bool operator== (const SkTLList& list) const { |
if (this == &list) { |
return true; |
} |
- if (fCount != list.fCount) { |
+ // Call count() rather than use fCount because an empty list may have fCount = 0 or -1. |
+ if (this->count() != list.count()) { |
return false; |
} |
for (Iter a(*this, Iter::kHead_IterStart), b(list, Iter::kHead_IterStart); |
@@ -223,7 +220,21 @@ private: |
Node fNodes[N]; |
}; |
+ void delayedInit() { |
+ SkASSERT(-1 == fCount); |
+ fFirstBlock.fNodesInUse = 0; |
+ for (unsigned int i = 0; i < N; ++i) { |
+ fFreeList.addToHead(fFirstBlock.fNodes + i); |
+ fFirstBlock.fNodes[i].fBlock = &fFirstBlock; |
+ } |
+ fCount = 0; |
+ this->validate(); |
+ } |
+ |
Node* createNode() { |
+ if (-1 == fCount) { |
+ this->delayedInit(); |
+ } |
Node* node = fFreeList.head(); |
if (node) { |
fFreeList.remove(node); |
@@ -270,11 +281,17 @@ private: |
void validate() const { |
#ifdef SK_DEBUG |
- SkASSERT((0 == fCount) == fList.isEmpty()); |
- if (0 == fCount) { |
+ bool isEmpty = false; |
+ if (-1 == fCount) { |
+ // We should not yet have initialized the free list. |
+ SkASSERT(fFreeList.isEmpty()); |
+ isEmpty = true; |
+ } else if (0 == fCount) { |
// Should only have the nodes from the first block in the free list. |
SkASSERT(fFreeList.countEntries() == N); |
+ isEmpty = true; |
} |
+ SkASSERT(isEmpty == fList.isEmpty()); |
fList.validate(); |
fFreeList.validate(); |
typename NodeList::Iter iter; |
@@ -318,7 +335,7 @@ private: |
SkASSERT(activeCnt == block->fNodesInUse); |
activeNode = iter.next(); |
} |
- SkASSERT(count == fCount); |
+ SkASSERT(count == fCount || (0 == count && -1 == fCount)); |
#endif |
} |