| Index: src/core/SkPictureFlat.h
|
| diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
|
| index 5452501c43f696547c04ad1b3c5b13530906ad30..220ae11c0e8455cbdde60ed9a1dbf6eea8802109 100644
|
| --- a/src/core/SkPictureFlat.h
|
| +++ b/src/core/SkPictureFlat.h
|
| @@ -267,16 +267,49 @@ private:
|
| class SkFlatData {
|
| public:
|
| // Flatten obj into an SkFlatData with this index. controller owns the SkFlatData*.
|
| - static SkFlatData* Create(SkFlatController* controller,
|
| - const void* obj,
|
| - int index,
|
| - void (*flattenProc)(SkOrderedWriteBuffer&, const void*));
|
| -
|
| - // Unflatten this into result, using bitmapHeap and facePlayback for bitmaps and fonts if given.
|
| - void unflatten(void* result,
|
| - void (*unflattenProc)(SkOrderedReadBuffer&, void*),
|
| + template <typename Traits, typename T>
|
| + 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));
|
| +
|
| + buffer.setBitmapHeap(controller->getBitmapHeap());
|
| + buffer.setTypefaceRecorder(controller->getTypefaceSet());
|
| + buffer.setNamedFactoryRecorder(controller->getNamedFactorySet());
|
| + buffer.setFlags(controller->getWriteBufferFlags());
|
| +
|
| + Traits::flatten(buffer, obj);
|
| + uint32_t size = buffer.size();
|
| + SkASSERT(SkIsAlign4(size));
|
| +
|
| + // Allocate enough memory to hold SkFlatData struct and the flat data itself.
|
| + size_t allocSize = sizeof(SkFlatData) + size;
|
| + SkFlatData* result = (SkFlatData*) controller->allocThrow(allocSize);
|
| +
|
| + // Put the serialized contents into the data section of the new allocation.
|
| + buffer.writeToMemory(result->data());
|
| + // Stamp the index, size and checksum in the header.
|
| + result->stampHeader(index, size);
|
| + return result;
|
| + }
|
| +
|
| + // Unflatten this into result, using bitmapHeap and facePlayback for bitmaps and fonts if given
|
| + template <typename Traits, typename T>
|
| + void unflatten(T* result,
|
| SkBitmapHeap* bitmapHeap = NULL,
|
| - SkTypefacePlayback* facePlayback = NULL) const;
|
| + SkTypefacePlayback* facePlayback = NULL) const {
|
| + SkOrderedReadBuffer buffer(this->data(), fFlatSize);
|
| +
|
| + if (bitmapHeap) {
|
| + buffer.setBitmapStorage(bitmapHeap);
|
| + }
|
| + if (facePlayback) {
|
| + facePlayback->setupBuffer(buffer);
|
| + }
|
| +
|
| + Traits::unflatten(buffer, result);
|
| + SkASSERT(fFlatSize == (int32_t)buffer.offset());
|
| + }
|
|
|
| // Do these contain the same data? Ignores index() and topBot().
|
| bool operator==(const SkFlatData& that) const {
|
| @@ -333,19 +366,17 @@ private:
|
| mutable SkScalar fTopBot[2]; // Cache of FontMetrics fTop, fBottom. Starts as [NaN,?].
|
| // uint32_t flattenedData[] implicitly hangs off the end.
|
|
|
| - template <class T> friend class SkFlatDictionary;
|
| + template <typename T, typename Traits, int kScratchSizeGuess> friend class SkFlatDictionary;
|
| };
|
|
|
| -template <class T>
|
| +template <typename T, typename Traits, int kScratchSizeGuess=0>
|
| class SkFlatDictionary {
|
| static const size_t kWriteBufferGrowthBytes = 1024;
|
|
|
| public:
|
| - SkFlatDictionary(SkFlatController* controller, size_t scratchSizeGuess = 0)
|
| - : fFlattenProc(NULL)
|
| - , fUnflattenProc(NULL)
|
| - , fController(SkRef(controller))
|
| - , fScratchSize(scratchSizeGuess)
|
| + explicit SkFlatDictionary(SkFlatController* controller)
|
| + : fController(SkRef(controller))
|
| + , fScratchSize(kScratchSizeGuess)
|
| , fScratch(AllocScratch(fScratchSize))
|
| , fWriteBuffer(kWriteBufferGrowthBytes)
|
| , fWriteBufferReady(false) {
|
| @@ -471,10 +502,6 @@ public:
|
| return this->findAndReturnMutableFlat(element);
|
| }
|
|
|
| -protected:
|
| - void (*fFlattenProc)(SkOrderedWriteBuffer&, const void*);
|
| - void (*fUnflattenProc)(SkOrderedReadBuffer&, void*);
|
| -
|
| private:
|
| // Layout: [ SkFlatData header, 20 bytes ] [ data ..., 4-byte aligned ]
|
| static size_t SizeWithPadding(size_t flatDataSize) {
|
| @@ -523,7 +550,7 @@ private:
|
|
|
| // Flatten element into fWriteBuffer (using fScratch as storage).
|
| fWriteBuffer.reset(fScratch->data(), fScratchSize);
|
| - fFlattenProc(fWriteBuffer, &element);
|
| + 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.
|
| @@ -561,10 +588,9 @@ private:
|
| }
|
|
|
| void unflatten(T* dst, const SkFlatData* element) const {
|
| - element->unflatten(dst,
|
| - fUnflattenProc,
|
| - fController->getBitmapHeap(),
|
| - fController->getTypefacePlayback());
|
| + element->unflatten<Traits>(dst,
|
| + fController->getBitmapHeap(),
|
| + fController->getTypefacePlayback());
|
| }
|
|
|
| // All SkFlatData* stored in fIndexedData and fHash are owned by the controller.
|
| @@ -589,15 +615,37 @@ private:
|
| // Some common dictionaries are defined here for both reference and convenience
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -template <class T>
|
| -static void SkFlattenObjectProc(SkOrderedWriteBuffer& buffer, const void* obj) {
|
| - ((T*)obj)->flatten(buffer);
|
| -}
|
| +struct SkMatrixTraits {
|
| + static void flatten(SkOrderedWriteBuffer& buffer, const SkMatrix& matrix) {
|
| + buffer.getWriter32()->writeMatrix(matrix);
|
| + }
|
| + static void unflatten(SkOrderedReadBuffer& buffer, SkMatrix* matrix) {
|
| + buffer.getReader32()->readMatrix(matrix);
|
| + }
|
| +};
|
| +typedef SkFlatDictionary<SkMatrix, SkMatrixTraits, 36> SkMatrixDictionary;
|
| +
|
| +
|
| +struct SkRegionTraits {
|
| + static void flatten(SkOrderedWriteBuffer& buffer, const SkRegion& region) {
|
| + buffer.getWriter32()->writeRegion(region);
|
| + }
|
| + static void unflatten(SkOrderedReadBuffer& buffer, SkRegion* region) {
|
| + buffer.getReader32()->readRegion(region);
|
| + }
|
| +};
|
| +typedef SkFlatDictionary<SkRegion, SkRegionTraits> SkRegionDictionary;
|
|
|
| -template <class T>
|
| -static void SkUnflattenObjectProc(SkOrderedReadBuffer& buffer, void* obj) {
|
| - ((T*)obj)->unflatten(buffer);
|
| -}
|
| +
|
| +struct SkPaintTraits {
|
| + static void flatten(SkOrderedWriteBuffer& buffer, const SkPaint& paint) {
|
| + paint.flatten(buffer);
|
| + }
|
| + static void unflatten(SkOrderedReadBuffer& buffer, SkPaint* paint) {
|
| + paint->unflatten(buffer);
|
| + }
|
| +};
|
| +typedef SkFlatDictionary<SkPaint, SkPaintTraits, 512> SkPaintDictionary;
|
|
|
| class SkChunkFlatController : public SkFlatController {
|
| public:
|
| @@ -635,49 +683,4 @@ private:
|
| mutable SkTypefacePlayback fTypefacePlayback;
|
| };
|
|
|
| -class SkMatrixDictionary : public SkFlatDictionary<SkMatrix> {
|
| - public:
|
| - // All matrices fit in 36 bytes.
|
| - SkMatrixDictionary(SkFlatController* controller)
|
| - : SkFlatDictionary<SkMatrix>(controller, 36) {
|
| - fFlattenProc = &flattenMatrix;
|
| - fUnflattenProc = &unflattenMatrix;
|
| - }
|
| -
|
| - static void flattenMatrix(SkOrderedWriteBuffer& buffer, const void* obj) {
|
| - buffer.getWriter32()->writeMatrix(*(SkMatrix*)obj);
|
| - }
|
| -
|
| - static void unflattenMatrix(SkOrderedReadBuffer& buffer, void* obj) {
|
| - buffer.getReader32()->readMatrix((SkMatrix*)obj);
|
| - }
|
| -};
|
| -
|
| -class SkPaintDictionary : public SkFlatDictionary<SkPaint> {
|
| - public:
|
| - // The largest paint across ~60 .skps was 500 bytes.
|
| - SkPaintDictionary(SkFlatController* controller)
|
| - : SkFlatDictionary<SkPaint>(controller, 512) {
|
| - fFlattenProc = &SkFlattenObjectProc<SkPaint>;
|
| - fUnflattenProc = &SkUnflattenObjectProc<SkPaint>;
|
| - }
|
| -};
|
| -
|
| -class SkRegionDictionary : public SkFlatDictionary<SkRegion> {
|
| - public:
|
| - SkRegionDictionary(SkFlatController* controller)
|
| - : SkFlatDictionary<SkRegion>(controller) {
|
| - fFlattenProc = &flattenRegion;
|
| - fUnflattenProc = &unflattenRegion;
|
| - }
|
| -
|
| - static void flattenRegion(SkOrderedWriteBuffer& buffer, const void* obj) {
|
| - buffer.getWriter32()->writeRegion(*(SkRegion*)obj);
|
| - }
|
| -
|
| - static void unflattenRegion(SkOrderedReadBuffer& buffer, void* obj) {
|
| - buffer.getReader32()->readRegion((SkRegion*)obj);
|
| - }
|
| -};
|
| -
|
| #endif
|
|
|