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