зеркало из https://github.com/mozilla/moz-skia.git
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:
Родитель
0b6dc190bb
Коммит
f56225c848
|
@ -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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче