speedup peek32() when the offset is in the last block (fTail)

Review URL: https://codereview.appspot.com/6906047

git-svn-id: http://skia.googlecode.com/svn/trunk@6708 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2012-12-07 17:48:04 +00:00
Родитель 0b6dc190bb
Коммит f56225c848
2 изменённых файлов: 47 добавлений и 18 удалений

Просмотреть файл

@ -37,6 +37,7 @@ public:
fSize(0), fSize(0),
fSingleBlock(NULL), fSingleBlock(NULL),
fSingleBlockSize(0), fSingleBlockSize(0),
fWrittenBeforeLastBlock(0),
fHead(NULL), fHead(NULL),
fTail(NULL), fTail(NULL),
fHeadIsExternalStorage(false) {} fHeadIsExternalStorage(false) {}
@ -197,6 +198,9 @@ private:
char* fSingleBlock; char* fSingleBlock;
uint32_t fSingleBlockSize; uint32_t fSingleBlockSize;
// sum of bytes written in all blocks *before* fTail
uint32_t fWrittenBeforeLastBlock;
struct Block; struct Block;
Block* fHead; Block* fHead;
Block* fTail; Block* fTail;

Просмотреть файл

@ -66,6 +66,7 @@ SkWriter32::SkWriter32(size_t minSize, void* storage, size_t storageSize) {
fSize = 0; fSize = 0;
fSingleBlock = NULL; fSingleBlock = NULL;
fSingleBlockSize = 0; fSingleBlockSize = 0;
fWrittenBeforeLastBlock = 0;
storageSize &= ~3; // trunc down to multiple of 4 storageSize &= ~3; // trunc down to multiple of 4
if (storageSize >= MIN_BLOCKSIZE) { if (storageSize >= MIN_BLOCKSIZE) {
@ -96,6 +97,7 @@ void SkWriter32::reset() {
} }
fSize = 0; fSize = 0;
fWrittenBeforeLastBlock = 0;
fSingleBlock = NULL; fSingleBlock = NULL;
if (fHeadIsExternalStorage) { if (fHeadIsExternalStorage) {
SkASSERT(fHead); SkASSERT(fHead);
@ -128,7 +130,11 @@ uint32_t* SkWriter32::reserve(size_t size) {
if (NULL == block) { if (NULL == block) {
SkASSERT(NULL == fHead); SkASSERT(NULL == fHead);
fHead = fTail = block = Block::Create(SkMax32(size, fMinSize)); fHead = fTail = block = Block::Create(SkMax32(size, fMinSize));
SkASSERT(0 == fWrittenBeforeLastBlock);
} else if (block->available() < size) { } else if (block->available() < size) {
SkASSERT(fSize > 0);
fWrittenBeforeLastBlock = fSize;
fTail = Block::Create(SkMax32(size, fMinSize)); fTail = Block::Create(SkMax32(size, fMinSize));
block->fNext = fTail; block->fNext = fTail;
block = fTail; block = fTail;
@ -149,6 +155,11 @@ uint32_t* SkWriter32::peek32(size_t offset) {
return (uint32_t*)(fSingleBlock + offset); return (uint32_t*)(fSingleBlock + offset);
} }
// try the fast case, where offset is within fTail
if (offset >= fWrittenBeforeLastBlock) {
return fTail->peek32(offset - fWrittenBeforeLastBlock);
}
Block* block = fHead; Block* block = fHead;
SkASSERT(NULL != block); SkASSERT(NULL != block);
@ -179,29 +190,39 @@ void SkWriter32::rewindToOffset(size_t offset) {
return; return;
} }
// Similar to peek32, except that we free up any following blocks // Try the fast case, where offset is within fTail
Block* block = fHead; if (offset >= fWrittenBeforeLastBlock) {
SkASSERT(NULL != block); fTail->fAllocatedSoFar = offset - fWrittenBeforeLastBlock;
while (offset >= block->fAllocatedSoFar) { } else {
offset -= block->fAllocatedSoFar; // Similar to peek32, except that we free up any following blocks.
block = block->fNext; // We have to re-compute fWrittenBeforeLastBlock as well.
size_t globalOffset = offset;
Block* block = fHead;
SkASSERT(NULL != block); SkASSERT(NULL != block);
} while (offset >= block->fAllocatedSoFar) {
offset -= block->fAllocatedSoFar;
block = block->fNext;
SkASSERT(NULL != block);
}
// update the size on the "last" block // this has to be recomputed, since we may free up fTail
block->fAllocatedSoFar = offset; fWrittenBeforeLastBlock = globalOffset - offset;
// end our list
fTail = block; // update the size on the "last" block
Block* next = block->fNext; block->fAllocatedSoFar = offset;
block->fNext = NULL; // end our list
// free up any trailing blocks fTail = block;
block = next;
while (block) {
Block* next = block->fNext; Block* next = block->fNext;
sk_free(block); block->fNext = NULL;
// free up any trailing blocks
block = next; block = next;
while (block) {
Block* next = block->fNext;
sk_free(block);
block = next;
}
} }
SkDEBUGCODE(this->validate();) SkDEBUGCODE(this->validate();)
} }
@ -310,6 +331,10 @@ void SkWriter32::validate() const {
SkASSERT(SkIsAlign4(block->fSizeOfBlock)); SkASSERT(SkIsAlign4(block->fSizeOfBlock));
SkASSERT(SkIsAlign4(block->fAllocatedSoFar)); SkASSERT(SkIsAlign4(block->fAllocatedSoFar));
SkASSERT(block->fAllocatedSoFar <= block->fSizeOfBlock); SkASSERT(block->fAllocatedSoFar <= block->fSizeOfBlock);
if (NULL == block->fNext) {
SkASSERT(fTail == block);
SkASSERT(fWrittenBeforeLastBlock == accum);
}
accum += block->fAllocatedSoFar; accum += block->fAllocatedSoFar;
SkASSERT(accum <= fSize); SkASSERT(accum <= fSize);
block = block->fNext; block = block->fNext;