aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pipe
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2015-05-06 12:56:48 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-05-06 12:56:48 -0700
commita85d4d0814818e4ddabb9237da209d61d6cd5854 (patch)
treea9da064f603bfec832f2150baa566381ddf5e35c /src/pipe
parent44d43d8d6e4f9321c9001f269ff433bd06aa81e1 (diff)
Make drawImage a virtual on SkDevice
Diffstat (limited to 'src/pipe')
-rw-r--r--src/pipe/SkGPipePriv.h20
-rw-r--r--src/pipe/SkGPipeRead.cpp47
-rw-r--r--src/pipe/SkGPipeWrite.cpp94
3 files changed, 155 insertions, 6 deletions
diff --git a/src/pipe/SkGPipePriv.h b/src/pipe/SkGPipePriv.h
index 736930b652..c3919f635b 100644
--- a/src/pipe/SkGPipePriv.h
+++ b/src/pipe/SkGPipePriv.h
@@ -43,6 +43,8 @@ enum DrawOps {
kDrawBitmapNine_DrawOp,
kDrawBitmapRectToRect_DrawOp,
kDrawDRRect_DrawOp,
+ kDrawImage_DrawOp,
+ kDrawImageRect_DrawOp,
kDrawOval_DrawOp,
kDrawPaint_DrawOp,
kDrawPatch_DrawOp,
@@ -79,6 +81,7 @@ enum DrawOps {
// these are signals to playback, not drawing verbs
kReportFlags_DrawOp,
kShareBitmapHeap_DrawOp,
+ kShareImageHeap_DrawOp,
kDone_DrawOp,
};
@@ -141,6 +144,7 @@ enum {
kDrawVertices_HasIndices_DrawOpFlag = 1 << 2,
kDrawVertices_HasXfermode_DrawOpFlag = 1 << 3,
};
+// These are shared between drawbitmap and drawimage
enum {
kDrawBitmap_HasPaint_DrawOpFlag = 1 << 0,
// Specific to drawBitmapRect, but needs to be different from HasPaint,
@@ -213,6 +217,22 @@ static inline bool shouldFlattenBitmaps(uint32_t flags) {
&& !(flags & SkGPipeWriter::kSharedAddressSpace_Flag));
}
+class SkImageHeap : public SkRefCnt {
+public:
+ SkImageHeap();
+ virtual ~SkImageHeap();
+
+ // slot must be "valid" -- 0 is never valid
+ const SkImage* get(int32_t slot) const;
+ // returns 0 if not found, else returns slot
+ int32_t find(const SkImage*) const;
+ // returns non-zero value for where the image was stored
+ int32_t insert(const SkImage*);
+
+private:
+ SkTDArray<const SkImage*> fArray;
+};
+
///////////////////////////////////////////////////////////////////////////////
enum PaintOps {
diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp
index f8411f5aea..917bb50976 100644
--- a/src/pipe/SkGPipeRead.cpp
+++ b/src/pipe/SkGPipeRead.cpp
@@ -178,6 +178,10 @@ public:
this->updateReader();
}
+ void setImageHeap(SkImageHeap* heap) {
+ fImageHeap.reset(SkRef(heap));
+ }
+
/**
* Access the shared heap. Only used in the case when bitmaps are not
* flattened.
@@ -198,6 +202,10 @@ public:
return id ? fTypefaces[id - 1] : NULL;
}
+ const SkImage* getImage(int32_t slot) const {
+ return fImageHeap->get(slot);
+ }
+
private:
void updateReader() {
if (NULL == fReader) {
@@ -227,6 +235,7 @@ private:
bool fSilent;
// Only used when sharing bitmaps with the writer.
SkBitmapHeap* fSharedHeap;
+ SkAutoTUnref<SkImageHeap> fImageHeap;
unsigned fFlags;
};
@@ -629,6 +638,35 @@ static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
}
}
+static void drawImage_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) {
+ unsigned slot = DrawOp_unpackData(op32);
+ unsigned flags = DrawOp_unpackFlags(op32);
+ bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag);
+ SkScalar x = reader->readScalar();
+ SkScalar y = reader->readScalar();
+ const SkImage* image = state->getImage(slot);
+ if (state->shouldDraw()) {
+ canvas->drawImage(image, x, y, hasPaint ? &state->paint() : NULL);
+ }
+}
+
+static void drawImageRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
+ SkGPipeState* state) {
+ unsigned slot = DrawOp_unpackData(op32);
+ unsigned flags = DrawOp_unpackFlags(op32);
+ bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag);
+ bool hasSrc = SkToBool(flags & kDrawBitmap_HasSrcRect_DrawOpFlag);
+ const SkRect* src = NULL;
+ if (hasSrc) {
+ src = skip<SkRect>(reader);
+ }
+ const SkRect* dst = skip<SkRect>(reader);
+ const SkImage* image = state->getImage(slot);
+ if (state->shouldDraw()) {
+ canvas->drawImageRect(image, src, *dst, hasPaint ? &state->paint() : NULL);
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
@@ -774,10 +812,14 @@ static void reportFlags_rp(SkCanvas*, SkReader32*, uint32_t op32,
}
static void shareBitmapHeap_rp(SkCanvas*, SkReader32* reader, uint32_t,
- SkGPipeState* state) {
+ SkGPipeState* state) {
state->setSharedHeap(static_cast<SkBitmapHeap*>(reader->readPtr()));
}
+static void shareImageHeap_rp(SkCanvas*, SkReader32* reader, uint32_t, SkGPipeState* state) {
+ state->setImageHeap(static_cast<SkImageHeap*>(reader->readPtr()));
+}
+
static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
@@ -793,6 +835,8 @@ static const ReadProc gReadTable[] = {
drawBitmapNine_rp,
drawBitmapRect_rp,
drawDRRect_rp,
+ drawImage_rp,
+ drawImageRect_rp,
drawOval_rp,
drawPaint_rp,
drawPatch_rp,
@@ -828,6 +872,7 @@ static const ReadProc gReadTable[] = {
reportFlags_rp,
shareBitmapHeap_rp,
+ shareImageHeap_rp,
done_rp
};
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index 83e5c57d27..2e73be83f1 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -272,12 +272,9 @@ protected:
void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override;
void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*,
DrawBitmapRectFlags flags) override;
-#if 0
- // rely on decomposition into bitmap (for now)
void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*) override;
void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
const SkPaint*) override;
-#endif
void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
const SkPaint*) override;
void onDrawSprite(const SkBitmap&, int left, int top, const SkPaint*) override;
@@ -300,6 +297,7 @@ private:
SkNamedFactorySet* fFactorySet;
SkBitmapHeap* fBitmapHeap;
+ SkImageHeap* fImageHeap;
SkGPipeController* fController;
SkWriter32& fWriter;
size_t fBlockSize; // amount allocated for writer
@@ -348,8 +346,8 @@ private:
// 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);
+ bool commonDrawBitmap(const SkBitmap&, DrawOps, unsigned flags, size_t bytes, const SkPaint*);
+ bool commonDrawImage(const SkImage*, DrawOps, unsigned flags, size_t bytes, const SkPaint*);
SkPaint fPaint;
void writePaint(const SkPaint&);
@@ -462,6 +460,13 @@ SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
}
}
fFlattenableHeap.setBitmapStorage(fBitmapHeap);
+
+ fImageHeap = SkNEW(SkImageHeap);
+ if (this->needOpBytes(sizeof(void*))) {
+ this->writeOp(kShareImageHeap_DrawOp);
+ fWriter.writePtr(static_cast<void*>(fImageHeap));
+ }
+
this->doNotify();
}
@@ -469,6 +474,7 @@ SkGPipeCanvas::~SkGPipeCanvas() {
this->finish(true);
SkSafeUnref(fFactorySet);
SkSafeUnref(fBitmapHeap);
+ SkSafeUnref(fImageHeap);
}
bool SkGPipeCanvas::needOpBytes(size_t needed) {
@@ -823,6 +829,53 @@ void SkGPipeCanvas::onDrawSprite(const SkBitmap& bm, int left, int top, const Sk
}
}
+bool SkGPipeCanvas::commonDrawImage(const SkImage* image, DrawOps op, unsigned flags,
+ size_t opBytesNeeded, const SkPaint* paint) {
+ if (fDone) {
+ return false;
+ }
+
+ if (paint != NULL) {
+ flags |= kDrawBitmap_HasPaint_DrawOpFlag;
+ this->writePaint(*paint);
+ }
+ // This needs to run first so its calls to needOpBytes() and its writes
+ // don't interlace with the needOpBytes() and write below.
+ int32_t slot = fImageHeap->insert(image);
+ SkASSERT(slot != 0);
+ if (this->needOpBytes(opBytesNeeded)) {
+ this->writeOp(op, flags, slot);
+ return true;
+ }
+ return false;
+}
+
+void SkGPipeCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y,
+ const SkPaint* paint) {
+ NOTIFY_SETUP(this);
+ if (this->commonDrawImage(image, kDrawImage_DrawOp, 0, sizeof(SkScalar) * 2, paint)) {
+ fWriter.writeScalar(x);
+ fWriter.writeScalar(y);
+ }
+}
+
+void SkGPipeCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
+ const SkPaint* paint) {
+ NOTIFY_SETUP(this);
+ unsigned flags = 0;
+ size_t opBytesNeeded = sizeof(SkRect); // dst
+ if (src) {
+ flags |= kDrawBitmap_HasSrcRect_DrawOpFlag;
+ opBytesNeeded += sizeof(SkRect); // src
+ }
+ if (this->commonDrawImage(image, kDrawImageRect_DrawOp, flags, opBytesNeeded, paint)) {
+ if (src) {
+ fWriter.writeRect(*src);
+ }
+ fWriter.writeRect(dst);
+ }
+}
+
void SkGPipeCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
const SkPaint& paint) {
if (byteLength) {
@@ -1337,3 +1390,34 @@ void BitmapShuttle::removeCanvas() {
fCanvas->unref();
fCanvas = NULL;
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+SkImageHeap::SkImageHeap() {}
+
+SkImageHeap::~SkImageHeap() {
+ fArray.unrefAll();
+}
+
+const SkImage* SkImageHeap::get(int32_t slot) const {
+ SkASSERT(slot > 0);
+ return fArray[slot - 1];
+}
+
+int32_t SkImageHeap::find(const SkImage* img) const {
+ int index = fArray.find(img);
+ if (index >= 0) {
+ return index + 1; // found
+ }
+ return 0; // not found
+}
+
+int32_t SkImageHeap::insert(const SkImage* img) {
+ int32_t slot = this->find(img);
+ if (slot) {
+ return slot;
+ }
+ *fArray.append() = SkRef(img);
+ return fArray.count(); // slot is always index+1
+}
+