aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-06-13 17:47:52 +0000
committerGravatar scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-06-13 17:47:52 +0000
commit8ae3c7f67eb3721bb656cffeadc1442332f10159 (patch)
treef47add6f7d7ba4f2325866d0beba3cf83aac1b11
parentaaf1688959ba5dc74007e711599552928d255dfa (diff)
For SkGPipe, store bitmaps in a common location.
Also make a change to SkBitmap::copyTo() so that we do not crash. Review URL: https://codereview.appspot.com/6296066 git-svn-id: http://skia.googlecode.com/svn/trunk@4249 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--src/core/SkBitmap.cpp1
-rw-r--r--src/pipe/SkGPipeRead.cpp12
-rw-r--r--src/pipe/SkGPipeWrite.cpp105
3 files changed, 93 insertions, 25 deletions
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<const SkBitmap*>(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<const SkBitmap*>(reader->readPtr()));
bool hasPaint = reader->readBool();
const SkIRect* center = skip<SkIRect>(reader);
const SkRect* dst = skip<SkRect>(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<const SkBitmap*>(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<const SkBitmap*>(reader->readPtr()));
bool hasPaint = reader->readBool();
const SkIPoint* point = skip<SkIPoint>(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;
+ };
+ SkTDArray<BitmapInfo>fBitmaps;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
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<void*>(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<void*>(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<void*>(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<void*>(ptr));
fWriter.writeBool(paint != NULL);
fWriter.write32(left);
fWriter.write32(top);