diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp index 6d5942f9a9..a7231135bd 100644 --- a/src/core/SkBitmap.cpp +++ b/src/core/SkBitmap.cpp @@ -925,7 +925,6 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { return false; } - SkAutoLockPixels dstlock(tmpDst); if (!tmpDst.readyToDraw()) { // allocator/lock failed return false; diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp index 85f46fd944..7f05b31414 100644 --- a/src/pipe/SkGPipeRead.cpp +++ b/src/pipe/SkGPipeRead.cpp @@ -347,8 +347,7 @@ static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op3 static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { - unsigned index = DrawOp_unpackData(op32); - SkBitmap* bm = state->getBitmap(index); + const SkBitmap* bm(static_cast(reader->readPtr())); bool hasPaint = reader->readBool(); SkScalar left = reader->readScalar(); SkScalar top = reader->readScalar(); @@ -362,8 +361,7 @@ static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t o static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { - unsigned index = DrawOp_unpackData(op32); - SkBitmap* bm = state->getBitmap(index); + const SkBitmap* bm(static_cast(reader->readPtr())); bool hasPaint = reader->readBool(); const SkIRect* center = skip(reader); const SkRect* dst = skip(reader); @@ -373,8 +371,7 @@ static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader, static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { - unsigned index = DrawOp_unpackData(op32); - SkBitmap* bm = state->getBitmap(index); + const SkBitmap* bm(static_cast(reader->readPtr())); bool hasPaint = reader->readBool(); bool hasSrc = reader->readBool(); const SkIRect* src; @@ -389,8 +386,7 @@ static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { - unsigned index = DrawOp_unpackData(op32); - SkBitmap* bm = state->getBitmap(index); + const SkBitmap* bm(static_cast(reader->readPtr())); bool hasPaint = reader->readBool(); const SkIPoint* point = skip(reader); canvas->drawSprite(*bm, point->fX, point->fY, hasPaint ? &state->paint() : NULL); diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp index 24ca0eac49..b97b98d08a 100644 --- a/src/pipe/SkGPipeWrite.cpp +++ b/src/pipe/SkGPipeWrite.cpp @@ -58,6 +58,62 @@ static size_t writeTypeface(SkWriter32* writer, SkTypeface* typeface) { /////////////////////////////////////////////////////////////////////////////// +/* + * Shared heap for storing large things that can be shared, for a stream + * used by multiple readers. + * TODO: Make the allocations all come from cross process safe address space + * TODO: Store paths (others?) + * TODO: Allow reclaiming of memory. Will require us to know when all readers + * have used the object. + */ +class Heap { +public: + Heap() {} + ~Heap() { + for (int i = 0; i < fBitmaps.count(); i++) { + delete fBitmaps[i].fBitmap; + } + } + + /* + * Add a copy of a bitmap to the heap. + * @param bm The SkBitmap to be copied and placed in the heap. + * @return void* Pointer to the heap's copy of the bitmap. If NULL, + * the bitmap could not be copied. + */ + const SkBitmap* addBitmap(const SkBitmap& bm) { + const uint32_t genID = bm.getGenerationID(); + for (int i = fBitmaps.count() - 1; i >= 0; i--) { + if (genID == fBitmaps[i].fGenID) { + return fBitmaps[i].fBitmap; + } + } + // TODO: Use a flag to determine whether we need the bitmap to be + // in shared cross process address space. If not, we can do a shallow + // copy. + SkBitmap* copy = new SkBitmap(); + if (bm.copyTo(copy, bm.getConfig())) { + BitmapInfo* info = fBitmaps.append(); + info->fBitmap = copy; + info->fGenID = genID; + return copy; + } + delete copy; + return NULL; + } +private: + struct BitmapInfo { + SkBitmap* fBitmap; + // Store the generation ID of the original bitmap, since copying does + // not copy this field, so fBitmap's generation ID will not be useful + // for comparing. + uint32_t fGenID; + }; + SkTDArrayfBitmaps; +}; + +/////////////////////////////////////////////////////////////////////////////// + class SkGPipeCanvas : public SkCanvas { public: SkGPipeCanvas(SkGPipeController*, SkWriter32*, SkFactorySet*); @@ -124,6 +180,7 @@ public: virtual void drawData(const void*, size_t) SK_OVERRIDE; private: + Heap fHeap; SkFactorySet* fFactorySet; // optional, only used if cross-process SkGPipeController* fController; SkWriter32& fWriter; @@ -539,17 +596,19 @@ void SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) { void SkGPipeCanvas::drawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top, const SkPaint* paint) { - // This is the brute-force solution - // TODO: add the notion of a shared, counted for large immutable resources + const void* ptr(fHeap.addBitmap(bm)); + if (NULL == ptr) { + return; + } + NOTIFY_SETUP(this); if (paint) { this->writePaint(*paint); } - int bitmapIndex = this->flattenToIndex(bm); - - if (this->needOpBytes(sizeof(SkScalar) * 2 + sizeof(bool))) { - this->writeOp(kDrawBitmap_DrawOp, 0, bitmapIndex); + if (this->needOpBytes(sizeof(SkScalar) * 2 + sizeof(bool) + sizeof(void*))) { + this->writeOp(kDrawBitmap_DrawOp, 0, 0); + fWriter.writePtr(const_cast(ptr)); fWriter.writeBool(paint != NULL); fWriter.writeScalar(left); fWriter.writeScalar(top); @@ -558,20 +617,24 @@ void SkGPipeCanvas::drawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top, void SkGPipeCanvas::drawBitmapRect(const SkBitmap& bm, const SkIRect* src, const SkRect& dst, const SkPaint* paint) { + const void* ptr(fHeap.addBitmap(bm)); + if (NULL == ptr) { + return; + } + NOTIFY_SETUP(this); if (paint) { this->writePaint(*paint); } - int bitmapIndex = this->flattenToIndex(bm); - - size_t opBytesNeeded = sizeof(SkRect) + sizeof(bool) * 2; + size_t opBytesNeeded = sizeof(SkRect) + sizeof(bool) * 2 + sizeof(void*); bool hasSrc = src != NULL; if (hasSrc) { opBytesNeeded += sizeof(int32_t) * 4; } if (this->needOpBytes(opBytesNeeded)) { - this->writeOp(kDrawBitmapRect_DrawOp, 0, bitmapIndex); + this->writeOp(kDrawBitmapRect_DrawOp, 0, 0); + fWriter.writePtr(const_cast(ptr)); fWriter.writeBool(paint != NULL); fWriter.writeBool(hasSrc); if (hasSrc) { @@ -591,15 +654,20 @@ void SkGPipeCanvas::drawBitmapMatrix(const SkBitmap&, const SkMatrix&, void SkGPipeCanvas::drawBitmapNine(const SkBitmap& bm, const SkIRect& center, const SkRect& dst, const SkPaint* paint) { + const void* ptr(fHeap.addBitmap(bm)); + if (NULL == ptr) { + return; + } + NOTIFY_SETUP(this); if (paint) { this->writePaint(*paint); } - int bitmapIndex = this->flattenToIndex(bm); if (this->needOpBytes(sizeof(int32_t) * 4 + sizeof(bool) - + sizeof(SkRect))) { - this->writeOp(kDrawBitmapNine_DrawOp, 0, bitmapIndex); + + sizeof(SkRect) + sizeof(void*))) { + this->writeOp(kDrawBitmapNine_DrawOp, 0, 0); + fWriter.writePtr(const_cast(ptr)); fWriter.writeBool(paint != NULL); fWriter.write32(center.fLeft); fWriter.write32(center.fTop); @@ -611,14 +679,19 @@ void SkGPipeCanvas::drawBitmapNine(const SkBitmap& bm, const SkIRect& center, void SkGPipeCanvas::drawSprite(const SkBitmap& bm, int left, int top, const SkPaint* paint) { + const void* ptr(fHeap.addBitmap(bm)); + if (NULL == ptr) { + return; + } + NOTIFY_SETUP(this); if (paint) { this->writePaint(*paint); } - int bitmapIndex = this->flattenToIndex(bm); - if (this->needOpBytes(sizeof(int32_t) * 2 + sizeof(bool))) { - this->writeOp(kDrawSprite_DrawOp, 0, bitmapIndex); + if (this->needOpBytes(sizeof(int32_t) * 2 + sizeof(bool) + sizeof(void*))) { + this->writeOp(kDrawSprite_DrawOp, 0, 0); + fWriter.writePtr(const_cast(ptr)); fWriter.writeBool(paint != NULL); fWriter.write32(left); fWriter.write32(top);