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

Unified Diff: src/core/SkChunkAlloc.cpp

Issue 967553003: Add rewind capability to SkChunkAlloc (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix variable sizes/signs Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/core/SkChunkAlloc.h ('k') | src/utils/SkDeferredCanvas.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkChunkAlloc.cpp
diff --git a/src/core/SkChunkAlloc.cpp b/src/core/SkChunkAlloc.cpp
index 62cdf1532f75b15738c296cf786d24b23ed1dfa0..4a71c2d2c43576263d00b2aeeac16aef90d50e61 100644
--- a/src/core/SkChunkAlloc.cpp
+++ b/src/core/SkChunkAlloc.cpp
@@ -23,6 +23,18 @@ struct SkChunkAlloc::Block {
char* fFreePtr;
// data[] follows
+ size_t blockSize() {
+ char* start = this->startOfData();
+ size_t bytes = fFreePtr - start;
+ return fFreeSize + bytes;
+ }
+
+ void reset() {
+ fNext = NULL;
+ fFreeSize = this->blockSize();
+ fFreePtr = this->startOfData();
+ }
+
char* startOfData() {
return reinterpret_cast<char*>(this + 1);
}
@@ -53,7 +65,8 @@ SkChunkAlloc::SkChunkAlloc(size_t minSize) {
fChunkSize = fMinSize;
fTotalCapacity = 0;
fTotalUsed = 0;
- fBlockCount = 0;
+ SkDEBUGCODE(fTotalLost = 0;)
+ SkDEBUGCODE(fBlockCount = 0;)
}
SkChunkAlloc::~SkChunkAlloc() {
@@ -66,7 +79,40 @@ void SkChunkAlloc::reset() {
fChunkSize = fMinSize; // reset to our initial minSize
fTotalCapacity = 0;
fTotalUsed = 0;
- fBlockCount = 0;
+ SkDEBUGCODE(fTotalLost = 0;)
+ SkDEBUGCODE(fBlockCount = 0;)
+}
+
+void SkChunkAlloc::rewind() {
+ SkDEBUGCODE(this->validate();)
+
+ Block* largest = fBlock;
+
+ if (largest) {
+ Block* next;
+ for (Block* cur = largest->fNext; cur; cur = next) {
+ next = cur->fNext;
+ if (cur->blockSize() > largest->blockSize()) {
+ sk_free(largest);
+ largest = cur;
+ } else {
+ sk_free(cur);
+ }
+ }
+
+ largest->reset();
+ fTotalCapacity = largest->blockSize();
+ SkDEBUGCODE(fBlockCount = 1;)
+ } else {
+ fTotalCapacity = 0;
+ SkDEBUGCODE(fBlockCount = 0;)
+ }
+
+ fBlock = largest;
+ fChunkSize = fMinSize; // reset to our initial minSize
+ fTotalUsed = 0;
+ SkDEBUGCODE(fTotalLost = 0;)
+ SkDEBUGCODE(this->validate();)
}
SkChunkAlloc::Block* SkChunkAlloc::newBlock(size_t bytes, AllocFailType ftype) {
@@ -79,43 +125,60 @@ SkChunkAlloc::Block* SkChunkAlloc::newBlock(size_t bytes, AllocFailType ftype) {
ftype == kThrow_AllocFailType ? SK_MALLOC_THROW : 0);
if (block) {
- // block->fNext = fBlock;
block->fFreeSize = size;
block->fFreePtr = block->startOfData();
fTotalCapacity += size;
- fBlockCount += 1;
+ SkDEBUGCODE(fBlockCount += 1;)
fChunkSize = increase_next_size(fChunkSize);
}
return block;
}
-void* SkChunkAlloc::alloc(size_t bytes, AllocFailType ftype) {
- fTotalUsed += bytes;
-
- bytes = SkAlign4(bytes);
-
- Block* block = fBlock;
+SkChunkAlloc::Block* SkChunkAlloc::addBlockIfNecessary(size_t bytes, AllocFailType ftype) {
+ SkASSERT(SkIsAlign4(bytes));
- if (block == NULL || bytes > block->fFreeSize) {
- block = this->newBlock(bytes, ftype);
- if (NULL == block) {
+ if (!fBlock || bytes > fBlock->fFreeSize) {
+ Block* block = this->newBlock(bytes, ftype);
+ if (!block) {
return NULL;
}
+#ifdef SK_DEBUG
+ if (fBlock) {
+ fTotalLost += fBlock->fFreeSize;
+ }
+#endif
block->fNext = fBlock;
fBlock = block;
}
- SkASSERT(block && bytes <= block->fFreeSize);
+ SkASSERT(fBlock && bytes <= fBlock->fFreeSize);
+ return fBlock;
+}
+
+void* SkChunkAlloc::alloc(size_t bytes, AllocFailType ftype) {
+ SkDEBUGCODE(this->validate();)
+
+ bytes = SkAlign4(bytes);
+
+ Block* block = this->addBlockIfNecessary(bytes, ftype);
+ if (!block) {
+ return NULL;
+ }
+
char* ptr = block->fFreePtr;
+ fTotalUsed += bytes;
block->fFreeSize -= bytes;
block->fFreePtr = ptr + bytes;
+ SkDEBUGCODE(this->validate();)
return ptr;
}
size_t SkChunkAlloc::unalloc(void* ptr) {
+ SkDEBUGCODE(this->validate();)
+
size_t bytes = 0;
Block* block = fBlock;
if (block) {
@@ -123,10 +186,12 @@ size_t SkChunkAlloc::unalloc(void* ptr) {
char* start = block->startOfData();
if (start <= cPtr && cPtr < block->fFreePtr) {
bytes = block->fFreePtr - cPtr;
+ fTotalUsed -= bytes;
block->fFreeSize += bytes;
block->fFreePtr = cPtr;
}
}
+ SkDEBUGCODE(this->validate();)
return bytes;
}
@@ -140,3 +205,31 @@ bool SkChunkAlloc::contains(const void* addr) const {
}
return false;
}
+
+#ifdef SK_DEBUG
+void SkChunkAlloc::validate() {
+ int numBlocks = 0;
+ size_t totCapacity = 0;
+ size_t totUsed = 0;
+ size_t totLost = 0;
+ size_t totAvailable = 0;
+
+ for (Block* temp = fBlock; temp; temp = temp->fNext) {
+ ++numBlocks;
+ totCapacity += temp->blockSize();
+ totUsed += temp->fFreePtr - temp->startOfData();
+ if (temp == fBlock) {
+ totAvailable += temp->fFreeSize;
+ } else {
+ totLost += temp->fFreeSize;
+ }
+ }
+
+ SkASSERT(fBlockCount == numBlocks);
+ SkASSERT(fTotalCapacity == totCapacity);
+ SkASSERT(fTotalUsed == totUsed);
+ SkASSERT(fTotalLost == totLost);
+ SkASSERT(totCapacity == totUsed + totLost + totAvailable);
+}
+#endif
+
« no previous file with comments | « include/core/SkChunkAlloc.h ('k') | src/utils/SkDeferredCanvas.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698