aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/SkBBoxRecord.cpp7
-rw-r--r--src/core/SkBBoxRecord.h3
-rw-r--r--src/core/SkCanvas.cpp41
-rw-r--r--src/core/SkDevice.cpp13
-rw-r--r--src/core/SkPictureFlat.h5
-rw-r--r--src/core/SkPicturePlayback.cpp7
-rw-r--r--src/core/SkPictureRecord.cpp28
-rw-r--r--src/core/SkPictureRecord.h1
-rw-r--r--src/pipe/SkGPipePriv.h1
-rw-r--r--src/pipe/SkGPipeRead.cpp11
-rw-r--r--src/pipe/SkGPipeWrite.cpp15
11 files changed, 129 insertions, 3 deletions
diff --git a/src/core/SkBBoxRecord.cpp b/src/core/SkBBoxRecord.cpp
index a757a245ce..7075cd1651 100644
--- a/src/core/SkBBoxRecord.cpp
+++ b/src/core/SkBBoxRecord.cpp
@@ -26,6 +26,13 @@ void SkBBoxRecord::drawRect(const SkRect& rect, const SkPaint& paint) {
}
}
+void SkBBoxRecord::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
+ const SkPaint& paint) {
+ if (this->transformBounds(outer.rect(), &paint)) {
+ this->INHERITED::onDrawDRRect(outer, inner, paint);
+ }
+}
+
void SkBBoxRecord::drawPath(const SkPath& path, const SkPaint& paint) {
if (path.isInverseFillType()) {
// If path is inverse filled, use the current clip bounds as the
diff --git a/src/core/SkBBoxRecord.h b/src/core/SkBBoxRecord.h
index 2a34320148..862e48e5b5 100644
--- a/src/core/SkBBoxRecord.h
+++ b/src/core/SkBBoxRecord.h
@@ -64,6 +64,9 @@ public:
const SkPaint& paint) SK_OVERRIDE;
virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
+protected:
+ virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE;
+
private:
/**
* Takes a bounding box in current canvas view space, accounts for stroking and effects, and
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 93dc14bd1e..f903fd40ce 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1594,6 +1594,26 @@ GrContext* SkCanvas::getGrContext() {
}
+void SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner,
+ const SkPaint& paint) {
+ if (outer.isEmpty()) {
+ return;
+ }
+ if (inner.isEmpty()) {
+ this->drawRRect(outer, paint);
+ return;
+ }
+
+ // We don't have this method (yet), but technically this is what we should
+ // be able to assert...
+ // SkASSERT(outer.contains(inner));
+ //
+ // For now at least check for containment of bounds
+ SkASSERT(outer.getBounds().contains(inner.getBounds()));
+
+ this->onDrawDRRect(outer, inner, paint);
+}
+
//////////////////////////////////////////////////////////////////////////////
// These are the virtual drawing methods
//////////////////////////////////////////////////////////////////////////////
@@ -1729,6 +1749,27 @@ void SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
LOOPER_END
}
+void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
+ const SkPaint& paint) {
+ CHECK_SHADER_NOSETCONTEXT(paint);
+
+ SkRect storage;
+ const SkRect* bounds = NULL;
+ if (paint.canComputeFastBounds()) {
+ bounds = &paint.computeFastBounds(outer.getBounds(), &storage);
+ if (this->quickReject(*bounds)) {
+ return;
+ }
+ }
+
+ LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds)
+
+ while (iter.next()) {
+ iter.fDevice->drawDRRect(iter, outer, inner, looper.paint());
+ }
+
+ LOOPER_END
+}
void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
CHECK_SHADER_NOSETCONTEXT(paint);
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 40663b2e03..4316c0ca3f 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -158,3 +158,16 @@ bool SkBaseDevice::readPixels(SkBitmap* bitmap, int x, int y,
SkSurface* SkBaseDevice::newSurface(const SkImageInfo&) { return NULL; }
const void* SkBaseDevice::peekPixels(SkImageInfo*, size_t*) { return NULL; }
+
+void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
+ const SkRRect& inner, const SkPaint& paint) {
+ SkPath path;
+ path.addRRect(outer);
+ path.addRRect(inner);
+ path.setFillType(SkPath::kEvenOdd_FillType);
+
+ const SkMatrix* preMatrix = NULL;
+ const bool pathIsMutable = true;
+ this->drawPath(draw, path, paint, preMatrix, pathIsMutable);
+}
+
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index 6b4af13840..68b398482a 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -63,7 +63,10 @@ enum DrawType {
COMMENT,
END_COMMENT_GROUP,
- LAST_DRAWTYPE_ENUM = END_COMMENT_GROUP
+ // new ops -- feel free to re-alphabetize on next version bump
+ DRAW_DRRECT,
+
+ LAST_DRAWTYPE_ENUM = DRAW_DRRECT
};
// In the 'match' method, this constant will match any flavor of DRAW_BITMAP*
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 8b8c6b0862..57356459ee 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -910,6 +910,13 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback)
canvas.drawData(reader.skip(length), length);
// skip handles padding the read out to a multiple of 4
} break;
+ case DRAW_DRRECT: {
+ const SkPaint& paint = *getPaint(reader);
+ SkRRect outer, inner;
+ reader.readRRect(&outer);
+ reader.readRRect(&inner);
+ canvas.drawDRRect(outer, inner, paint);
+ } break;
case BEGIN_COMMENT_GROUP: {
const char* desc = reader.readString();
canvas.beginCommentGroup(desc);
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index c14328b7a8..aedb7dfd56 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -111,9 +111,11 @@ static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) {
0, // BEGIN_GROUP - no paint
0, // COMMENT - no paint
0, // END_GROUP - no paint
+ 1, // DRAWDRRECT - right after op code
};
- SkASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1);
+ SK_COMPILE_ASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1,
+ need_to_be_in_sync);
SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM);
int overflow = 0;
@@ -463,6 +465,10 @@ static bool remove_save_layer2(SkWriter32* writer, int32_t offset,
result[0], result[3]);
}
+static bool is_drawing_op(DrawType op) {
+ return (op > CONCAT && op < ROTATE) || DRAW_DRRECT == op;
+}
+
/*
* Restore has just been called (but not recorded), so look back at the
* matching save(), and see if we can eliminate the pair of them, due to no
@@ -511,7 +517,7 @@ static bool collapse_save_clip_restore(SkWriter32* writer, int32_t offset,
offset += opSize;
while (offset < restoreOffset) {
op = peek_op_and_size(writer, offset, &opSize);
- if ((op > CONCAT && op < ROTATE) || (SAVE_LAYER == op)) {
+ if (is_drawing_op(op) || (SAVE_LAYER == op)) {
// drawing verb, abort
return false;
}
@@ -1068,6 +1074,24 @@ void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
}
}
+void SkPictureRecord::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
+ const SkPaint& paint) {
+
+#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
+ fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
+#endif
+
+ // op + paint index + rrects
+ uint32_t initialOffset, size;
+ size = 2 * kUInt32Size + SkRRect::kSizeInMemory * 2;
+ initialOffset = this->addDraw(DRAW_DRRECT, &size);
+ SkASSERT(initialOffset+getPaintOffset(DRAW_DRRECT, size) == fWriter.bytesWritten());
+ this->addPaint(paint);
+ this->addRRect(outer);
+ this->addRRect(inner);
+ this->validate(initialOffset, size);
+}
+
void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) {
#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index c000f113ba..2fb99faf37 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -222,6 +222,7 @@ protected:
const void* onPeekPixels(SkImageInfo*, size_t*) SK_OVERRIDE {
return NULL;
}
+ virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE;
// Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been
// tweaked by paint.computeFastBounds().
diff --git a/src/pipe/SkGPipePriv.h b/src/pipe/SkGPipePriv.h
index d1970c4a69..5e0b1893cd 100644
--- a/src/pipe/SkGPipePriv.h
+++ b/src/pipe/SkGPipePriv.h
@@ -45,6 +45,7 @@ enum DrawOps {
kDrawBitmapRectToRect_DrawOp,
kDrawClear_DrawOp,
kDrawData_DrawOp,
+ kDrawDRRect_DrawOp,
kDrawOval_DrawOp,
kDrawPaint_DrawOp,
kDrawPath_DrawOp,
diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp
index 513a34d639..8827adc73f 100644
--- a/src/pipe/SkGPipeRead.cpp
+++ b/src/pipe/SkGPipeRead.cpp
@@ -396,6 +396,16 @@ static void drawRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
}
}
+static void drawDRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
+ SkGPipeState* state) {
+ SkRRect outer, inner;
+ reader->readRRect(&outer);
+ reader->readRRect(&inner);
+ if (state->shouldDraw()) {
+ canvas->drawDRRect(outer, inner, state->paint());
+ }
+}
+
static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
SkGPipeState* state) {
SkPath path;
@@ -763,6 +773,7 @@ static const ReadProc gReadTable[] = {
drawBitmapRect_rp,
drawClear_rp,
drawData_rp,
+ drawDRRect_rp,
drawOval_rp,
drawPaint_rp,
drawPath_rp,
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index 17305bf24b..879ce8288b 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -290,6 +290,10 @@ public:
* according to slot.
*/
bool shuttleBitmap(const SkBitmap&, int32_t slot);
+
+protected:
+ virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE;
+
private:
enum {
kNoSaveLayer = -1,
@@ -738,6 +742,17 @@ void SkGPipeCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
}
}
+void SkGPipeCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
+ const SkPaint& paint) {
+ NOTIFY_SETUP(this);
+ this->writePaint(paint);
+ if (this->needOpBytes(kSizeOfFlatRRect * 2)) {
+ this->writeOp(kDrawDRRect_DrawOp);
+ fWriter.writeRRect(outer);
+ fWriter.writeRRect(inner);
+ }
+}
+
void SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
NOTIFY_SETUP(this);
this->writePaint(paint);