aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-01-14 20:51:26 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-01-14 20:51:26 +0000
commit19382421b916aab00be7265815ba4e2690adf2c9 (patch)
tree8e69446ccf2e3548e9f2986a5eba67a641e76b59 /src/core
parentb638a3a941fc9514b3f26165bfaaa7b48a580139 (diff)
Convert SkWriter32 to use an SkTDArray for its internal storage.
This reduces the allocation overhead of a null picture (create, beginRecording(), endRecording) from about 18K to about 1.9K. (There's still lots more to prune.) SkPictureFlat can exploit the fact that Writer32 is contiguous simplify its memory management. The Writer32 itself becomes the scratch buffer. Remove lots and lots of arbitrary magic numbers that were size guesses and minimum allocation sizes. Keep your eyes open for the big obvious DUH why we save 16K per picture! (Spoiler alert. It's because that first save we issue in beginRecording() forces the old SkWriter32 to allocate 16K.) Tests passing, DM passing. bench --match writer: ~20% faster null bench_record: ~30% faster bench_record on buildbot .skps: ~3-6% slower, ranging 25% faster to 20% slower bench_pictures on buildbot .skps: ~1-2% faster, ranging 13% faster to 28% slower BUG=skia:1850 R=reed@google.com Author: mtklein@google.com Review URL: https://codereview.chromium.org/137433003 git-svn-id: http://skia.googlecode.com/svn/trunk@13073 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkFlattenableSerialization.cpp2
-rw-r--r--src/core/SkOrderedWriteBuffer.cpp7
-rw-r--r--src/core/SkOrderedWriteBuffer.h12
-rw-r--r--src/core/SkPaint.cpp6
-rw-r--r--src/core/SkPictureFlat.h90
-rw-r--r--src/core/SkPicturePlayback.cpp3
-rw-r--r--src/core/SkPictureRecord.cpp2
-rw-r--r--src/core/SkScalerContext.cpp2
-rw-r--r--src/core/SkWriter32.cpp234
9 files changed, 41 insertions, 317 deletions
diff --git a/src/core/SkFlattenableSerialization.cpp b/src/core/SkFlattenableSerialization.cpp
index b98d935ca7..5c83101eaf 100644
--- a/src/core/SkFlattenableSerialization.cpp
+++ b/src/core/SkFlattenableSerialization.cpp
@@ -12,7 +12,7 @@
#include "SkOrderedWriteBuffer.h"
SkData* SkValidatingSerializeFlattenable(SkFlattenable* flattenable) {
- SkOrderedWriteBuffer writer(1024);
+ SkOrderedWriteBuffer writer;
writer.setFlags(SkOrderedWriteBuffer::kValidation_Flag);
writer.writeFlattenable(flattenable);
uint32_t size = writer.bytesWritten();
diff --git a/src/core/SkOrderedWriteBuffer.cpp b/src/core/SkOrderedWriteBuffer.cpp
index 50fdc72869..9107ecd828 100644
--- a/src/core/SkOrderedWriteBuffer.cpp
+++ b/src/core/SkOrderedWriteBuffer.cpp
@@ -14,21 +14,20 @@
#include "SkStream.h"
#include "SkTypeface.h"
-SkOrderedWriteBuffer::SkOrderedWriteBuffer(size_t minSize)
+SkOrderedWriteBuffer::SkOrderedWriteBuffer()
: INHERITED()
, fFactorySet(NULL)
, fNamedFactorySet(NULL)
- , fWriter(minSize)
, fBitmapHeap(NULL)
, fTFSet(NULL)
, fBitmapEncoder(NULL) {
}
-SkOrderedWriteBuffer::SkOrderedWriteBuffer(size_t minSize, void* storage, size_t storageSize)
+SkOrderedWriteBuffer::SkOrderedWriteBuffer(void* storage, size_t storageSize)
: INHERITED()
, fFactorySet(NULL)
, fNamedFactorySet(NULL)
- , fWriter(minSize, storage, storageSize)
+ , fWriter(storage, storageSize)
, fBitmapHeap(NULL)
, fTFSet(NULL)
, fBitmapEncoder(NULL) {
diff --git a/src/core/SkOrderedWriteBuffer.h b/src/core/SkOrderedWriteBuffer.h
index f3b414e104..1f10152293 100644
--- a/src/core/SkOrderedWriteBuffer.h
+++ b/src/core/SkOrderedWriteBuffer.h
@@ -25,19 +25,17 @@ class SkRefCntSet;
class SkOrderedWriteBuffer : public SkFlattenableWriteBuffer {
public:
- SkOrderedWriteBuffer(size_t minSize);
- SkOrderedWriteBuffer(size_t minSize, void* initialStorage, size_t storageSize);
+ SkOrderedWriteBuffer();
+ SkOrderedWriteBuffer(void* initialStorage, size_t storageSize);
virtual ~SkOrderedWriteBuffer();
virtual bool isOrderedBinaryBuffer() SK_OVERRIDE { return true; }
virtual SkOrderedWriteBuffer* getOrderedBinaryBuffer() SK_OVERRIDE { return this; }
SkWriter32* getWriter32() { return &fWriter; }
- void reset(void* storage, size_t storageSize) { fWriter.reset(storage, storageSize); }
-
- // Returns true if we've written only into the storage passed into constructor or reset.
- // (You may be able to use this to avoid a call to writeToMemory.)
- bool wroteOnlyToStorage() const { return fWriter.wroteOnlyToStorage(); }
+ void reset(void* storage = NULL, size_t storageSize = 0) {
+ fWriter.reset(storage, storageSize);
+ }
void writeToMemory(void* dst) { fWriter.flatten(dst); }
uint32_t* reserve(size_t size) { return fWriter.reserve(size); }
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 94ffa8d31b..af032d001e 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -1815,9 +1815,7 @@ void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties,
SkMaskFilter* mf = this->getMaskFilter();
SkRasterizer* ra = this->getRasterizer();
- SkOrderedWriteBuffer peBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
- SkOrderedWriteBuffer mfBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
- SkOrderedWriteBuffer raBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
+ SkOrderedWriteBuffer peBuffer, mfBuffer, raBuffer;
if (pe) {
peBuffer.writeFlattenable(pe);
@@ -1845,7 +1843,7 @@ void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties,
}
#ifdef SK_BUILD_FOR_ANDROID
- SkOrderedWriteBuffer androidBuffer(128);
+ SkOrderedWriteBuffer androidBuffer;
fPaintOptionsAndroid.flatten(androidBuffer);
descSize += androidBuffer.size();
entryCount += 1;
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index c3623eec69..8db9609b97 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -271,7 +271,7 @@ public:
static SkFlatData* Create(SkFlatController* controller, const T& obj, int index) {
// A buffer of 256 bytes should fit most paints, regions, and matrices.
uint32_t storage[64];
- SkOrderedWriteBuffer buffer(256, storage, sizeof(storage));
+ SkOrderedWriteBuffer buffer(storage, sizeof(storage));
buffer.setBitmapHeap(controller->getBitmapHeap());
buffer.setTypefaceRecorder(controller->getTypefaceSet());
@@ -366,19 +366,14 @@ private:
mutable SkScalar fTopBot[2]; // Cache of FontMetrics fTop, fBottom. Starts as [NaN,?].
// uint32_t flattenedData[] implicitly hangs off the end.
- template <typename T, typename Traits, int kScratchSizeGuess> friend class SkFlatDictionary;
+ template <typename T, typename Traits> friend class SkFlatDictionary;
};
-template <typename T, typename Traits, int kScratchSizeGuess=0>
+template <typename T, typename Traits>
class SkFlatDictionary {
- static const size_t kWriteBufferGrowthBytes = 1024;
-
public:
explicit SkFlatDictionary(SkFlatController* controller)
: fController(SkRef(controller))
- , fScratchSize(0)
- , fScratch(NULL)
- , fWriteBuffer(kWriteBufferGrowthBytes)
, fReady(false) {
this->reset();
}
@@ -391,10 +386,6 @@ public:
fIndexedData.rewind();
}
- ~SkFlatDictionary() {
- sk_free(fScratch);
- }
-
int count() const {
SkASSERT(fHash.count() == fIndexedData.count());
return fHash.count();
@@ -500,35 +491,19 @@ public:
}
private:
- // Layout: [ SkFlatData header, 20 bytes ] [ data ..., 4-byte aligned ]
- static size_t SizeWithPadding(size_t flatDataSize) {
- SkASSERT(SkIsAlign4(flatDataSize));
- return sizeof(SkFlatData) + flatDataSize;
- }
-
- // Allocate a new scratch SkFlatData. Must be sk_freed.
- static SkFlatData* AllocScratch(size_t scratchSize) {
- return (SkFlatData*) sk_malloc_throw(SizeWithPadding(scratchSize));
- }
-
- // We have to delay fWriteBuffer's initialization until its first use; fController might not
- // be fully set up by the time we get it in the constructor. We also delay allocating fScratch
- // to avoid unnecessary heap allocations, since we're paying the price of the conditional
- // anyway.
+ // We have to delay fScratch's initialization until its first use; fController might not
+ // be fully set up by the time we get it in the constructor.
void lazyInit() {
if (fReady) {
return;
}
- fScratchSize = kScratchSizeGuess;
- fScratch = AllocScratch(fScratchSize);
-
// Without a bitmap heap, we'll flatten bitmaps into paints. That's never what you want.
SkASSERT(fController->getBitmapHeap() != NULL);
- fWriteBuffer.setBitmapHeap(fController->getBitmapHeap());
- fWriteBuffer.setTypefaceRecorder(fController->getTypefaceSet());
- fWriteBuffer.setNamedFactoryRecorder(fController->getNamedFactorySet());
- fWriteBuffer.setFlags(fController->getWriteBufferFlags());
+ fScratch.setBitmapHeap(fController->getBitmapHeap());
+ fScratch.setTypefaceRecorder(fController->getTypefaceSet());
+ fScratch.setNamedFactoryRecorder(fController->getNamedFactorySet());
+ fScratch.setFlags(fController->getWriteBufferFlags());
fReady = true;
}
@@ -551,28 +526,17 @@ private:
const SkFlatData& resetScratch(const T& element, int index) {
this->lazyInit();
- // Flatten element into fWriteBuffer (using fScratch as storage).
- fWriteBuffer.reset(fScratch->data(), fScratchSize);
- Traits::flatten(fWriteBuffer, element);
- const size_t bytesWritten = fWriteBuffer.bytesWritten();
-
- // If all the flattened bytes fit into fScratch, we can skip a call to writeToMemory.
- if (!fWriteBuffer.wroteOnlyToStorage()) {
- SkASSERT(bytesWritten > fScratchSize);
- // It didn't all fit. Copy into a larger replacement SkFlatData.
- // We can't just realloc because it might move the pointer and confuse writeToMemory.
- SkFlatData* larger = AllocScratch(bytesWritten);
- fWriteBuffer.writeToMemory(larger->data());
-
- // Carry on with this larger scratch to minimize the likelihood of future resizing.
- sk_free(fScratch);
- fScratchSize = bytesWritten;
- fScratch = larger;
- }
+ // Layout of fScratch: [ SkFlatData header, 20 bytes ] [ data ..., 4-byte aligned ]
+ fScratch.reset();
+ fScratch.reserve(sizeof(SkFlatData));
+ Traits::flatten(fScratch, element);
+ const size_t dataSize = fScratch.bytesWritten() - sizeof(SkFlatData);
- // The data is in fScratch now but we need to stamp its header.
- fScratch->stampHeader(index, bytesWritten);
- return *fScratch;
+ // Reinterpret data in fScratch as an SkFlatData.
+ SkFlatData* scratch = (SkFlatData*)fScratch.getWriter32()->contiguousArray();
+ SkASSERT(scratch != NULL);
+ scratch->stampHeader(index, dataSize);
+ return *scratch;
}
// This result is owned by fController and lives as long as it does (unless unalloc'd).
@@ -580,12 +544,12 @@ private:
// Allocate a new SkFlatData exactly big enough to hold our current scratch.
// We use the controller for this allocation to extend the allocation's lifetime and allow
// the controller to do whatever memory management it wants.
- SkASSERT(fScratch != NULL);
- const size_t paddedSize = SizeWithPadding(fScratch->flatSize());
- SkFlatData* detached = (SkFlatData*)fController->allocThrow(paddedSize);
+ SkFlatData* detached = (SkFlatData*)fController->allocThrow(fScratch.bytesWritten());
// Copy scratch into the new SkFlatData.
- memcpy(detached, fScratch, paddedSize);
+ SkFlatData* scratch = (SkFlatData*)fScratch.getWriter32()->contiguousArray();
+ SkASSERT(scratch != NULL);
+ memcpy(detached, scratch, fScratch.bytesWritten());
// We can now reuse fScratch, and detached will live until fController dies.
return detached;
@@ -599,9 +563,7 @@ private:
// All SkFlatData* stored in fIndexedData and fHash are owned by the controller.
SkAutoTUnref<SkFlatController> fController;
- size_t fScratchSize; // How many bytes fScratch has allocated for data itself.
- SkFlatData* fScratch; // Owned, lazily allocated, must be freed with sk_free.
- SkOrderedWriteBuffer fWriteBuffer;
+ SkOrderedWriteBuffer fScratch;
bool fReady;
// For index -> SkFlatData. 0-based, while all indices in the API are 1-based. Careful!
@@ -624,7 +586,7 @@ struct SkMatrixTraits {
buffer.getReader32()->readMatrix(matrix);
}
};
-typedef SkFlatDictionary<SkMatrix, SkMatrixTraits, 36> SkMatrixDictionary;
+typedef SkFlatDictionary<SkMatrix, SkMatrixTraits> SkMatrixDictionary;
struct SkRegionTraits {
@@ -646,7 +608,7 @@ struct SkPaintTraits {
paint->unflatten(buffer);
}
};
-typedef SkFlatDictionary<SkPaint, SkPaintTraits, 512> SkPaintDictionary;
+typedef SkFlatDictionary<SkPaint, SkPaintTraits> SkPaintDictionary;
class SkChunkFlatController : public SkFlatController {
public:
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 97e566764b..27f0c58c6d 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -438,8 +438,7 @@ void SkPicturePlayback::serialize(SkWStream* stream,
SkRefCntSet typefaceSet;
SkFactorySet factSet;
- SkOrderedWriteBuffer buffer(1024);
-
+ SkOrderedWriteBuffer buffer;
buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
buffer.setTypefaceRecorder(&typefaceSet);
buffer.setFactoryRecorder(&factSet);
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index b7508b3623..4ae1c6b7df 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -13,7 +13,6 @@
#include "SkDevice.h"
#include "SkPictureStateTree.h"
-#define MIN_WRITER_SIZE 16384
#define HEAP_BLOCK_SIZE 4096
enum {
@@ -36,7 +35,6 @@ SkPictureRecord::SkPictureRecord(uint32_t flags, SkBaseDevice* device) :
fMatrices(&fFlattenableHeap),
fPaints(&fFlattenableHeap),
fRegions(&fFlattenableHeap),
- fWriter(MIN_WRITER_SIZE),
fRecordFlags(flags) {
#ifdef SK_DEBUG_SIZE
fPointBytes = fRectBytes = fTextBytes = 0;
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index 04ef2a9222..2a4e9d3d58 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -147,7 +147,7 @@ SkScalerContext* SkScalerContext::allocNextContext() const {
SkAutoTUnref<SkTypeface> aur(newFace);
uint32_t newFontID = newFace->uniqueID();
- SkOrderedWriteBuffer androidBuffer(128);
+ SkOrderedWriteBuffer androidBuffer;
fPaintOptionsAndroid.flatten(androidBuffer);
SkAutoDescriptor ad(sizeof(fRec) + androidBuffer.size() + SkDescriptor::ComputeOverhead(2));
diff --git a/src/core/SkWriter32.cpp b/src/core/SkWriter32.cpp
index e5befbafb4..5e89ed655b 100644
--- a/src/core/SkWriter32.cpp
+++ b/src/core/SkWriter32.cpp
@@ -5,239 +5,9 @@
* found in the LICENSE file.
*/
-#include "SkWriter32.h"
-
-SkWriter32::SkWriter32(size_t minSize, void* storage, size_t storageSize) {
- fMinSize = minSize;
- fSize = 0;
- fWrittenBeforeLastBlock = 0;
- fHead = fTail = NULL;
-
- if (storageSize) {
- this->reset(storage, storageSize);
- }
-}
-
-SkWriter32::~SkWriter32() {
- this->reset();
-}
-
-void SkWriter32::reset() {
- Block* block = fHead;
-
- if (this->isHeadExternallyAllocated()) {
- SkASSERT(block);
- // don't 'free' the first block, since it is owned by the caller
- block = block->fNext;
- }
- while (block) {
- Block* next = block->fNext;
- sk_free(block);
- block = next;
- }
-
- fSize = 0;
- fWrittenBeforeLastBlock = 0;
- fHead = fTail = NULL;
-}
-
-void SkWriter32::reset(void* storage, size_t storageSize) {
- this->reset();
-
- storageSize &= ~3; // trunc down to multiple of 4
- if (storageSize > 0 && SkIsAlign4((intptr_t)storage)) {
- fHead = fTail = fExternalBlock.initFromStorage(storage, storageSize);
- }
-}
-
-SkWriter32::Block* SkWriter32::doReserve(size_t size) {
- SkASSERT(SkAlign4(size) == size);
-
- Block* block = fTail;
- SkASSERT(NULL == block || block->available() < size);
-
- if (NULL == block) {
- SkASSERT(NULL == fHead);
- fHead = fTail = block = Block::Create(SkMax32(size, fMinSize));
- SkASSERT(0 == fWrittenBeforeLastBlock);
- } else {
- fWrittenBeforeLastBlock = fSize;
-
- fTail = Block::Create(SkMax32(size, fMinSize));
- block->fNext = fTail;
- block = fTail;
- }
- return block;
-}
-
-uint32_t* SkWriter32::peek32(size_t offset) {
- SkDEBUGCODE(this->validate();)
-
- SkASSERT(SkAlign4(offset) == offset);
- SkASSERT(offset <= fSize);
-
- // try the fast case, where offset is within fTail
- if (offset >= fWrittenBeforeLastBlock) {
- return fTail->peek32(offset - fWrittenBeforeLastBlock);
- }
-
- Block* block = fHead;
- SkASSERT(NULL != block);
-
- while (offset >= block->fAllocatedSoFar) {
- offset -= block->fAllocatedSoFar;
- block = block->fNext;
- SkASSERT(NULL != block);
- }
- return block->peek32(offset);
-}
-
-void SkWriter32::rewindToOffset(size_t offset) {
- if (offset >= fSize) {
- return;
- }
- if (0 == offset) {
- this->reset();
- return;
- }
-
- SkDEBUGCODE(this->validate();)
-
- SkASSERT(SkAlign4(offset) == offset);
- SkASSERT(offset <= fSize);
- fSize = offset;
-
- // Try the fast case, where offset is within fTail
- if (offset >= fWrittenBeforeLastBlock) {
- fTail->fAllocatedSoFar = offset - fWrittenBeforeLastBlock;
- } else {
- // Similar to peek32, except that we free up any following blocks.
- // We have to re-compute fWrittenBeforeLastBlock as well.
-
- size_t globalOffset = offset;
- Block* block = fHead;
- SkASSERT(NULL != block);
- while (offset >= block->fAllocatedSoFar) {
- offset -= block->fAllocatedSoFar;
- block = block->fNext;
- SkASSERT(NULL != block);
- }
-
- // this has to be recomputed, since we may free up fTail
- fWrittenBeforeLastBlock = globalOffset - offset;
-
- // update the size on the "last" block
- block->fAllocatedSoFar = offset;
- // end our list
- fTail = block;
- Block* next = block->fNext;
- block->fNext = NULL;
- // free up any trailing blocks
- block = next;
- while (block) {
- Block* next = block->fNext;
- sk_free(block);
- block = next;
- }
- }
- SkDEBUGCODE(this->validate();)
-}
-
-void SkWriter32::flatten(void* dst) const {
- const Block* block = fHead;
- SkDEBUGCODE(size_t total = 0;)
-
- while (block) {
- size_t allocated = block->fAllocatedSoFar;
- memcpy(dst, block->base(), allocated);
- dst = (char*)dst + allocated;
- block = block->fNext;
-
- SkDEBUGCODE(total += allocated;)
- SkASSERT(total <= fSize);
- }
- SkASSERT(total == fSize);
-}
-
-uint32_t* SkWriter32::reservePad(size_t size) {
- if (size > 0) {
- size_t alignedSize = SkAlign4(size);
- char* dst = (char*)this->reserve(alignedSize);
- // Pad the last four bytes with zeroes in one step.
- uint32_t* padding = (uint32_t*)(dst + (alignedSize - 4));
- *padding = 0;
- return (uint32_t*) dst;
- }
- return this->reserve(0);
-}
-
-void SkWriter32::writePad(const void* src, size_t size) {
- if (size > 0) {
- char* dst = (char*)this->reservePad(size);
- // Copy the actual data.
- memcpy(dst, src, size);
- }
-}
-
-#include "SkStream.h"
-
-size_t SkWriter32::readFromStream(SkStream* stream, size_t length) {
- char scratch[1024];
- const size_t MAX = sizeof(scratch);
- size_t remaining = length;
-
- while (remaining != 0) {
- size_t n = remaining;
- if (n > MAX) {
- n = MAX;
- }
- size_t bytes = stream->read(scratch, n);
- this->writePad(scratch, bytes);
- remaining -= bytes;
- if (bytes != n) {
- break;
- }
- }
- return length - remaining;
-}
-
-bool SkWriter32::writeToStream(SkWStream* stream) {
- const Block* block = fHead;
- while (block) {
- if (!stream->write(block->base(), block->fAllocatedSoFar)) {
- return false;
- }
- block = block->fNext;
- }
- return true;
-}
-
-#ifdef SK_DEBUG
-void SkWriter32::validate() const {
- SkASSERT(SkIsAlign4(fSize));
-
- size_t accum = 0;
- const Block* block = fHead;
- while (block) {
- SkASSERT(SkIsAlign4(block->fSizeOfBlock));
- SkASSERT(SkIsAlign4(block->fAllocatedSoFar));
- SkASSERT(block->fAllocatedSoFar <= block->fSizeOfBlock);
- if (NULL == block->fNext) {
- SkASSERT(fTail == block);
- SkASSERT(fWrittenBeforeLastBlock == accum);
- }
- accum += block->fAllocatedSoFar;
- SkASSERT(accum <= fSize);
- block = block->fNext;
- }
- SkASSERT(accum == fSize);
-}
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-
#include "SkReader32.h"
#include "SkString.h"
+#include "SkWriter32.h"
/*
* Strings are stored as: length[4-bytes] + string_data + '\0' + pad_to_mul_4
@@ -247,7 +17,7 @@ const char* SkReader32::readString(size_t* outLen) {
size_t len = this->readInt();
const void* ptr = this->peek();
- // skip over teh string + '\0' and then pad to a multiple of 4
+ // skip over the string + '\0' and then pad to a multiple of 4
size_t alignedSize = SkAlign4(len + 1);
this->skip(alignedSize);