diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkBBoxRecord.cpp | 7 | ||||
-rw-r--r-- | src/core/SkBBoxRecord.h | 3 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 41 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 13 | ||||
-rw-r--r-- | src/core/SkPictureFlat.h | 5 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 7 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 28 | ||||
-rw-r--r-- | src/core/SkPictureRecord.h | 1 | ||||
-rw-r--r-- | src/pipe/SkGPipePriv.h | 1 | ||||
-rw-r--r-- | src/pipe/SkGPipeRead.cpp | 11 | ||||
-rw-r--r-- | src/pipe/SkGPipeWrite.cpp | 15 |
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); |