Change growth function for SkWriter32
Add setCountExact to SkTDArray to allow external control of array growth. Use it to allow SkWriter to control the buffer growth pattern. Change buffer growth pattern to 1.5n+4096 BUG=skia:2125 R=tomhudson@google.com, mtklein@google.com, reed@google.com Author: iancottrell@google.com Review URL: https://codereview.chromium.org/150663014 git-svn-id: http://skia.googlecode.com/svn/trunk@13401 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
ac14aac67b
commit
93d5ffda58
@ -151,25 +151,43 @@ public:
|
||||
fCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of elements in the array.
|
||||
* If the array does not have space for count elements, it will increase
|
||||
* the storage allocated to some amount greater than that required.
|
||||
* It will never shrink the shrink the storage.
|
||||
*/
|
||||
void setCount(int count) {
|
||||
// TODO(mtklein): eliminate this method, setCountExact -> setCount
|
||||
SkASSERT(count >= 0);
|
||||
if (count > fReserve) {
|
||||
this->growBy(count - fCount);
|
||||
} else {
|
||||
fCount = count;
|
||||
resizeStorageToAtLeast(count);
|
||||
}
|
||||
fCount = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of elements in the array.
|
||||
* If the array does not have space for count elements, it will increase
|
||||
* the storage allocated to exactly the amount required, with no remaining
|
||||
* reserved space.
|
||||
* It will never shrink the shrink the storage.
|
||||
*/
|
||||
void setCountExact(int count) {
|
||||
if (count > fReserve) {
|
||||
this->resizeStorageToExact(count);
|
||||
}
|
||||
fCount = count;
|
||||
}
|
||||
|
||||
void setReserve(int reserve) {
|
||||
if (reserve > fReserve) {
|
||||
SkASSERT(reserve > fCount);
|
||||
int count = fCount;
|
||||
this->growBy(reserve - fCount);
|
||||
fCount = count;
|
||||
resizeStorageToAtLeast(reserve);
|
||||
}
|
||||
}
|
||||
|
||||
T* prepend() {
|
||||
this->growBy(1);
|
||||
this->adjustCount(1);
|
||||
memmove(fArray + 1, fArray, (fCount - 1) * sizeof(T));
|
||||
return fArray;
|
||||
}
|
||||
@ -183,7 +201,7 @@ public:
|
||||
SkASSERT(src == NULL || fArray == NULL ||
|
||||
src + count <= fArray || fArray + oldCount <= src);
|
||||
|
||||
this->growBy(count);
|
||||
this->adjustCount(count);
|
||||
if (src) {
|
||||
memcpy(fArray + oldCount, src, sizeof(T) * count);
|
||||
}
|
||||
@ -204,7 +222,7 @@ public:
|
||||
SkASSERT(count);
|
||||
SkASSERT(index <= fCount);
|
||||
size_t oldCount = fCount;
|
||||
this->growBy(count);
|
||||
this->adjustCount(count);
|
||||
T* dst = fArray + index;
|
||||
memmove(dst + count, dst, sizeof(T) * (oldCount - index));
|
||||
if (src) {
|
||||
@ -356,20 +374,43 @@ private:
|
||||
int fReserve;
|
||||
int fCount;
|
||||
|
||||
void growBy(int extra) {
|
||||
SkASSERT(extra);
|
||||
/**
|
||||
* Adjusts the number of elements in the array.
|
||||
* This is the same as calling setCount(count() + delta).
|
||||
*/
|
||||
void adjustCount(int delta) {
|
||||
setCount(fCount + delta);
|
||||
}
|
||||
|
||||
if (fCount + extra > fReserve) {
|
||||
int size = fCount + extra + 4;
|
||||
size += size >> 2;
|
||||
|
||||
fArray = (T*)sk_realloc_throw(fArray, size * sizeof(T));
|
||||
/**
|
||||
* This resizes the storage to *exactly* count elements, growing or
|
||||
* shrinking the allocation as needed. It does not ASSERT anything about
|
||||
* the previous allocation size, or about fCount.
|
||||
*
|
||||
* note: does NOT modify fCount
|
||||
*/
|
||||
void resizeStorageToExact(int count) {
|
||||
SkASSERT(count >= 0);
|
||||
fArray = (T*)sk_realloc_throw(fArray, count * sizeof(T));
|
||||
#ifdef SK_DEBUG
|
||||
fData = (ArrayT*)fArray;
|
||||
fData = (ArrayT*)fArray;
|
||||
#endif
|
||||
fReserve = size;
|
||||
}
|
||||
fCount += extra;
|
||||
fReserve = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the storage allocation such that it can hold (fCount + extra)
|
||||
* elements.
|
||||
* It never shrinks the allocation, and it may increase the allocation by
|
||||
* more than is strictly required, based on a private growth heuristic.
|
||||
*
|
||||
* note: does NOT modify fCount
|
||||
*/
|
||||
void resizeStorageToAtLeast(int count) {
|
||||
SkASSERT(count > fReserve);
|
||||
int space = count + 4;
|
||||
space += space>>2;
|
||||
resizeStorageToExact(space);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -67,20 +67,20 @@ size_t SkWriter32::WriteStringSize(const char* str, size_t len) {
|
||||
return SkAlign4(lenBytes + len + 1);
|
||||
}
|
||||
|
||||
const size_t kMinBufferBytes=4096;
|
||||
|
||||
void SkWriter32::growToAtLeast(size_t size) {
|
||||
bool wasExternal = (fExternal != NULL) && (fData == fExternal);
|
||||
fCapacity = kMinBufferBytes +
|
||||
SkTMax(size, fCapacity + (fCapacity >> 1));
|
||||
|
||||
// cause the buffer to grow
|
||||
fInternal.setCount(size);
|
||||
fInternal.setCountExact(fCapacity);
|
||||
fData = fInternal.begin();
|
||||
if (wasExternal) {
|
||||
// we were external, so copy in the data
|
||||
memcpy(fData, fExternal, fUsed);
|
||||
}
|
||||
// Find out the size the buffer grew to, it may be more than we asked for.
|
||||
fCapacity = fInternal.reserved();
|
||||
// Expand the array so all reserved space is "used", we maintain the
|
||||
// amount we have written manually outside the array
|
||||
fInternal.setCount(fCapacity);
|
||||
SkASSERT(fInternal.count() == (int)fCapacity);
|
||||
SkASSERT(fInternal.reserved() == (int)fCapacity);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user