| Index: src/core/SkPictureFlat.h
|
| diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
|
| index c3623eec699e2946c9780ccc32eec25120c3f76a..8db9609b977825393444154c74048eccc564637e 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:
|
|
|