Add a SkRWBuffer reserve mechanism
Currently, Chromium stores segmented data in a SharedBuffer and appends to SkRWBuffer one segment at a time: const char* segment = 0; for (size_t length = data->getSomeData(segment, m_rwBuffer->size()); length; length = data->getSomeData(segment, m_rwBuffer->size())) { m_rwBuffer->append(segment, length, remaining); } This can yield a bunch of just-above-4k allocations => wasted RAM due to internal fragmentation. Ideally, we'd want a SkRWBuffer::reserve(size_t bytes) API, but the current internals don't support that trivially. Alternatively, the caller can pass a reserve hint at append() time. BUG=chromium:651698 R=scroggo@google.com,reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2385803002 Review-Url: https://codereview.chromium.org/2385803002
This commit is contained in:
parent
f6566314f8
commit
5776508126
@ -79,7 +79,15 @@ public:
|
|||||||
~SkRWBuffer();
|
~SkRWBuffer();
|
||||||
|
|
||||||
size_t size() const { return fTotalUsed; }
|
size_t size() const { return fTotalUsed; }
|
||||||
void append(const void* buffer, size_t length);
|
|
||||||
|
/**
|
||||||
|
* Append |length| bytes from |buffer|.
|
||||||
|
*
|
||||||
|
* If the caller knows in advance how much more data they are going to append, they can
|
||||||
|
* pass a |reserve| hint (representing the number of upcoming bytes *in addition* to the
|
||||||
|
* current append), to minimize the number of internal allocations.
|
||||||
|
*/
|
||||||
|
void append(const void* buffer, size_t length, size_t reserve = 0);
|
||||||
|
|
||||||
SkROBuffer* newRBufferSnapshot() const;
|
SkROBuffer* newRBufferSnapshot() const;
|
||||||
SkStreamAsset* newStreamSnapshot() const;
|
SkStreamAsset* newStreamSnapshot() const;
|
||||||
|
@ -199,7 +199,7 @@ SkRWBuffer::~SkRWBuffer() {
|
|||||||
// next, since our reader will be using fCapacity (min'd against its total available) to know how
|
// next, since our reader will be using fCapacity (min'd against its total available) to know how
|
||||||
// many bytes to read from a given block.
|
// many bytes to read from a given block.
|
||||||
//
|
//
|
||||||
void SkRWBuffer::append(const void* src, size_t length) {
|
void SkRWBuffer::append(const void* src, size_t length, size_t reserve) {
|
||||||
this->validate();
|
this->validate();
|
||||||
if (0 == length) {
|
if (0 == length) {
|
||||||
return;
|
return;
|
||||||
@ -208,7 +208,7 @@ void SkRWBuffer::append(const void* src, size_t length) {
|
|||||||
fTotalUsed += length;
|
fTotalUsed += length;
|
||||||
|
|
||||||
if (nullptr == fHead) {
|
if (nullptr == fHead) {
|
||||||
fHead = SkBufferHead::Alloc(length);
|
fHead = SkBufferHead::Alloc(length + reserve);
|
||||||
fTail = &fHead->fBlock;
|
fTail = &fHead->fBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ void SkRWBuffer::append(const void* src, size_t length) {
|
|||||||
length -= written;
|
length -= written;
|
||||||
|
|
||||||
if (length) {
|
if (length) {
|
||||||
SkBufferBlock* block = SkBufferBlock::Alloc(length);
|
SkBufferBlock* block = SkBufferBlock::Alloc(length + reserve);
|
||||||
fTail->fNext = block;
|
fTail->fNext = block;
|
||||||
fTail = block;
|
fTail = block;
|
||||||
written = fTail->append(src, length);
|
written = fTail->append(src, length);
|
||||||
|
Loading…
Reference in New Issue
Block a user