diff options
author | scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-08-13 16:39:42 +0000 |
---|---|---|
committer | scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-08-13 16:39:42 +0000 |
commit | 92967e9677ac0416c9c858ed19e4883aa1726046 (patch) | |
tree | 75c9ba47c12cc4f2a950f5dd114088fcb272bce4 /src/pipe | |
parent | b8bf9ce1034cc5d50ff0945ba9841e113522b26c (diff) |
Use the SkBitmapHeap to handle SkBitmaps in SkGPipe cross process.
Required moving the LRU handles from SkBitmapHeapEntry to LookupEntry.
Allows simplification of drawBitmap* calls in SkGPipeCanvas.
Review URL: https://codereview.appspot.com/6460073
git-svn-id: http://skia.googlecode.com/svn/trunk@5063 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/pipe')
-rw-r--r-- | src/pipe/SkGPipeRead.cpp | 3 | ||||
-rw-r--r-- | src/pipe/SkGPipeWrite.cpp | 172 |
2 files changed, 79 insertions, 96 deletions
diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp index e6013db49e..3655107229 100644 --- a/src/pipe/SkGPipeRead.cpp +++ b/src/pipe/SkGPipeRead.cpp @@ -113,7 +113,6 @@ public: } void addBitmap(int index) { - index--; SkBitmap* bm; if(fBitmaps.count() == index) { bm = SkNEW(SkBitmap); @@ -125,7 +124,7 @@ public: } SkBitmap* getBitmap(unsigned index) { - return fBitmaps[index - 1]; + return fBitmaps[index]; } void setSharedHeap(SkBitmapHeap* heap) { diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp index 128a458c9e..fbb67bedec 100644 --- a/src/pipe/SkGPipeWrite.cpp +++ b/src/pipe/SkGPipeWrite.cpp @@ -163,6 +163,15 @@ public: if (this->needOpBytes()) { this->writeOp(kDone_DrawOp); this->doNotify(); + if (shouldFlattenBitmaps(fFlags)) { + // In this case, a BitmapShuttle is reffed by the SharedHeap + // and refs this canvas. Unref the SharedHeap to end the + // circular reference. When shouldFlattenBitmaps is false, + // there is no circular reference, so the SharedHeap can be + // safely unreffed in the destructor. + fSharedHeap->unref(); + fSharedHeap = NULL; + } } fDone = true; } @@ -172,11 +181,6 @@ public: size_t freeMemoryIfPossible(size_t bytesToFree); size_t storageAllocatedForRecording() { - // FIXME: This can be removed once fSharedHeap is used by cross process - // case. - if (NULL == fSharedHeap) { - return 0; - } return fSharedHeap->bytesAllocated(); } @@ -231,6 +235,11 @@ public: const SkPaint&) SK_OVERRIDE; virtual void drawData(const void*, size_t) SK_OVERRIDE; + /** + * Flatten an SkBitmap to send to the reader, where it will be referenced + * according to slot. + */ + bool shuttleBitmap(const SkBitmap&, int32_t slot); private: enum { kNoSaveLayer = -1, @@ -243,7 +252,7 @@ private: size_t fBlockSize; // amount allocated for writer size_t fBytesNotified; bool fDone; - uint32_t fFlags; + const uint32_t fFlags; SkRefCntSet fTypefaceSet; @@ -273,27 +282,15 @@ private: // if a new SkFlatData was added when in cross process mode void flattenFactoryNames(); - // These are only used when in cross process, but with no shared address - // space, so bitmaps are flattened. - FlattenableHeap fBitmapHeap; - SkBitmapDictionary fBitmapDictionary; - int flattenToIndex(const SkBitmap&); - FlattenableHeap fFlattenableHeap; FlatDictionary fFlatDictionary; int fCurrFlatIndex[kCount_PaintFlats]; int flattenToIndex(SkFlattenable* obj, PaintFlats); - // Common code used by drawBitmap* when flattening. - bool commonDrawBitmapFlatten(const SkBitmap& bm, DrawOps op, unsigned flags, - size_t opBytesNeeded, const SkPaint* paint); - // Common code used by drawBitmap* when storing in the heap. - bool commonDrawBitmapHeap(const SkBitmap& bm, DrawOps op, unsigned flags, - size_t opBytesNeeded, const SkPaint* paint); - // Convenience type for function pointer - typedef bool (SkGPipeCanvas::*BitmapCommonFunction)(const SkBitmap&, - DrawOps, unsigned, - size_t, const SkPaint*); + // Common code used by drawBitmap*. Behaves differently depending on the + // type of SkBitmapHeap being used, which is determined by the flags used. + bool commonDrawBitmap(const SkBitmap& bm, DrawOps op, unsigned flags, + size_t opBytesNeeded, const SkPaint* paint); SkPaint fPaint; void writePaint(const SkPaint&); @@ -321,23 +318,20 @@ void SkGPipeCanvas::flattenFactoryNames() { } } -int SkGPipeCanvas::flattenToIndex(const SkBitmap & bitmap) { +bool SkGPipeCanvas::shuttleBitmap(const SkBitmap& bm, int32_t slot) { SkASSERT(shouldFlattenBitmaps(fFlags)); - uint32_t flags = SkFlattenableWriteBuffer::kCrossProcess_Flag; - bool added, replaced; - const SkFlatData* flat = fBitmapDictionary.findAndReplace( - bitmap, flags, fBitmapHeap.flatToReplace(), &added, &replaced); - - int index = flat->index(); - if (added) { - this->flattenFactoryNames(); - size_t flatSize = flat->flatSize(); - if (this->needOpBytes(flatSize)) { - this->writeOp(kDef_Bitmap_DrawOp, 0, index); - fWriter.write(flat->data(), flatSize); - } + SkOrderedWriteBuffer buffer(1024); + buffer.setNamedFactoryRecorder(fFactorySet); + bm.flatten(buffer); + this->flattenFactoryNames(); + uint32_t size = buffer.size(); + if (this->needOpBytes(size)) { + this->writeOp(kDef_Bitmap_DrawOp, 0, slot); + void* dst = static_cast<void*>(fWriter.reserve(size)); + buffer.writeToMemory(dst); + return true; } - return index; + return false; } // return 0 for NULL (or unflattenable obj), or index-base-1 @@ -377,6 +371,24 @@ int SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) { /////////////////////////////////////////////////////////////////////////////// +/** + * If SkBitmaps are to be flattened to send to the reader, this class is + * provided to the SkBitmapHeap to tell the SkGPipeCanvas to do so. + */ +class BitmapShuttle : public SkBitmapHeap::ExternalStorage { +public: + BitmapShuttle(SkGPipeCanvas*); + + ~BitmapShuttle(); + + virtual bool insert(const SkBitmap& bitmap, int32_t slot) SK_OVERRIDE; + +private: + SkGPipeCanvas* fCanvas; +}; + +/////////////////////////////////////////////////////////////////////////////// + #define MIN_BLOCK_SIZE (16 * 1024) #define BITMAPS_TO_KEEP 5 #define FLATTENABLES_TO_KEEP 10 @@ -386,8 +398,6 @@ SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller, : fFactorySet(isCrossProcess(flags) ? SkNEW(SkNamedFactorySet) : NULL) , fWriter(*writer) , fFlags(flags) -, fBitmapHeap(BITMAPS_TO_KEEP, fFactorySet) -, fBitmapDictionary(&fBitmapHeap) , fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet) , fFlatDictionary(&fFlattenableHeap) { fController = controller; @@ -411,10 +421,12 @@ SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller, } if (shouldFlattenBitmaps(flags)) { - // TODO: Use the shared heap for cross process case as well. - fSharedHeap = NULL; + BitmapShuttle* shuttle = SkNEW_ARGS(BitmapShuttle, (this)); + fSharedHeap = SkNEW_ARGS(SkBitmapHeap, (shuttle, BITMAPS_TO_KEEP)); + shuttle->unref(); } else { - fSharedHeap = SkNEW_ARGS(SkBitmapHeap, (5, controller->numberOfReaders())); + fSharedHeap = SkNEW_ARGS(SkBitmapHeap, + (BITMAPS_TO_KEEP, controller->numberOfReaders())); if (this->needOpBytes(sizeof(void*))) { this->writeOp(kShareHeap_DrawOp); fWriter.writePtr(static_cast<void*>(fSharedHeap)); @@ -426,8 +438,6 @@ SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller, SkGPipeCanvas::~SkGPipeCanvas() { this->finish(); SkSafeUnref(fFactorySet); - // FIXME: This can be changed to unref() once fSharedHeap is used by cross - // process case. SkSafeUnref(fSharedHeap); } @@ -682,26 +692,10 @@ void SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) { } } -bool SkGPipeCanvas::commonDrawBitmapFlatten(const SkBitmap& bm, DrawOps op, - unsigned flags, - size_t opBytesNeeded, - const SkPaint* paint) { - if (paint != NULL) { - flags |= kDrawBitmap_HasPaint_DrawOpsFlag; - this->writePaint(*paint); - } - int bitmapIndex = this->flattenToIndex(bm); - if (this->needOpBytes(opBytesNeeded)) { - this->writeOp(op, flags, bitmapIndex); - return true; - } - return false; -} - -bool SkGPipeCanvas::commonDrawBitmapHeap(const SkBitmap& bm, DrawOps op, - unsigned flags, - size_t opBytesNeeded, - const SkPaint* paint) { +bool SkGPipeCanvas::commonDrawBitmap(const SkBitmap& bm, DrawOps op, + unsigned flags, + size_t opBytesNeeded, + const SkPaint* paint) { int32_t bitmapIndex = fSharedHeap->insert(bm); if (SkBitmapHeap::INVALID_SLOT == bitmapIndex) { return false; @@ -722,11 +716,7 @@ void SkGPipeCanvas::drawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top, NOTIFY_SETUP(this); size_t opBytesNeeded = sizeof(SkScalar) * 2; - BitmapCommonFunction bitmapCommon = shouldFlattenBitmaps(fFlags) ? - &SkGPipeCanvas::commonDrawBitmapFlatten : - &SkGPipeCanvas::commonDrawBitmapHeap; - - if ((*this.*bitmapCommon)(bm, kDrawBitmap_DrawOp, 0, opBytesNeeded, paint)) { + if (this->commonDrawBitmap(bm, kDrawBitmap_DrawOp, 0, opBytesNeeded, paint)) { fWriter.writeScalar(left); fWriter.writeScalar(top); } @@ -744,12 +734,8 @@ void SkGPipeCanvas::drawBitmapRect(const SkBitmap& bm, const SkIRect* src, } else { flags = 0; } - - BitmapCommonFunction bitmapCommon = shouldFlattenBitmaps(fFlags) ? - &SkGPipeCanvas::commonDrawBitmapFlatten : - &SkGPipeCanvas::commonDrawBitmapHeap; - if ((*this.*bitmapCommon)(bm, kDrawBitmapRect_DrawOp, flags, opBytesNeeded, paint)) { + if (this->commonDrawBitmap(bm, kDrawBitmapRect_DrawOp, flags, opBytesNeeded, paint)) { if (hasSrc) { fWriter.write32(src->fLeft); fWriter.write32(src->fTop); @@ -765,11 +751,7 @@ void SkGPipeCanvas::drawBitmapMatrix(const SkBitmap& bm, const SkMatrix& matrix, NOTIFY_SETUP(this); size_t opBytesNeeded = matrix.writeToMemory(NULL); - BitmapCommonFunction bitmapCommon = shouldFlattenBitmaps(fFlags) ? - &SkGPipeCanvas::commonDrawBitmapFlatten : - &SkGPipeCanvas::commonDrawBitmapHeap; - - if ((*this.*bitmapCommon)(bm, kDrawBitmapMatrix_DrawOp, 0, opBytesNeeded, paint)) { + if (this->commonDrawBitmap(bm, kDrawBitmapMatrix_DrawOp, 0, opBytesNeeded, paint)) { fWriter.writeMatrix(matrix); } } @@ -779,11 +761,7 @@ void SkGPipeCanvas::drawBitmapNine(const SkBitmap& bm, const SkIRect& center, NOTIFY_SETUP(this); size_t opBytesNeeded = sizeof(int32_t) * 4 + sizeof(SkRect); - BitmapCommonFunction bitmapCommon = shouldFlattenBitmaps(fFlags) ? - &SkGPipeCanvas::commonDrawBitmapFlatten : - &SkGPipeCanvas::commonDrawBitmapHeap; - - if ((*this.*bitmapCommon)(bm, kDrawBitmapNine_DrawOp, 0, opBytesNeeded, paint)) { + if (this->commonDrawBitmap(bm, kDrawBitmapNine_DrawOp, 0, opBytesNeeded, paint)) { fWriter.write32(center.fLeft); fWriter.write32(center.fTop); fWriter.write32(center.fRight); @@ -797,11 +775,7 @@ void SkGPipeCanvas::drawSprite(const SkBitmap& bm, int left, int top, NOTIFY_SETUP(this); size_t opBytesNeeded = sizeof(int32_t) * 2; - BitmapCommonFunction bitmapCommon = shouldFlattenBitmaps(fFlags) ? - &SkGPipeCanvas::commonDrawBitmapFlatten : - &SkGPipeCanvas::commonDrawBitmapHeap; - - if ((*this.*bitmapCommon)(bm, kDrawSprite_DrawOp, 0, opBytesNeeded, paint)) { + if (this->commonDrawBitmap(bm, kDrawSprite_DrawOp, 0, opBytesNeeded, paint)) { fWriter.write32(left); fWriter.write32(top); } @@ -960,11 +934,6 @@ void SkGPipeCanvas::flushRecording(bool detachCurrentBlock) { } size_t SkGPipeCanvas::freeMemoryIfPossible(size_t bytesToFree) { - // FIXME: This can be removed once fSharedHeap is used by cross process - // case. - if (NULL == fSharedHeap) { - return 0; - } return fSharedHeap->freeMemoryIfPossible(bytesToFree); } @@ -1145,3 +1114,18 @@ size_t SkGPipeWriter::storageAllocatedForRecording() const { return NULL == fCanvas ? 0 : fCanvas->storageAllocatedForRecording(); } +/////////////////////////////////////////////////////////////////////////////// + +BitmapShuttle::BitmapShuttle(SkGPipeCanvas* canvas) { + SkASSERT(canvas != NULL); + fCanvas = canvas; + fCanvas->ref(); +} + +BitmapShuttle::~BitmapShuttle() { + fCanvas->unref(); +} + +bool BitmapShuttle::insert(const SkBitmap& bitmap, int32_t slot) { + return fCanvas->shuttleBitmap(bitmap, slot); +} |