diff options
32 files changed, 274 insertions, 84 deletions
diff --git a/gm/patch.cpp b/gm/patch.cpp index 5658ef6a88..3f1e07910b 100644 --- a/gm/patch.cpp +++ b/gm/patch.cpp @@ -16,61 +16,47 @@ #include "GrTest.h" #include "SkPatch.h" -static void draw_control_points(SkCanvas* canvas, SkPatch& patch, SkPaint& paint) { +static void draw_control_points(SkCanvas* canvas, const SkPatch& patch) { //draw control points - SkPaint copy(paint); - SkPoint bottom[4]; + SkPaint paint; + SkPoint bottom[SkPatch::kNumPtsCubic]; patch.getBottomPoints(bottom); - SkPoint top[4]; + SkPoint top[SkPatch::kNumPtsCubic]; patch.getTopPoints(top); - SkPoint left[4]; + SkPoint left[SkPatch::kNumPtsCubic]; patch.getLeftPoints(left); - SkPoint right[4]; + SkPoint right[SkPatch::kNumPtsCubic]; patch.getRightPoints(right); - copy.setColor(SK_ColorBLACK); - copy.setStrokeWidth(0.5); + paint.setColor(SK_ColorBLACK); + paint.setStrokeWidth(0.5); SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] }; - canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, copy); - canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom+1, copy); - canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, copy); - canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, copy); - canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, copy); + canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint); + canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom+1, paint); + canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint); + canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint); + canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint); - canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top+1, copy); - canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left+1, copy); - canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right+1, copy); + canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top+1, paint); + canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left+1, paint); + canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right+1, paint); - copy.setStrokeWidth(2); + paint.setStrokeWidth(2); - copy.setColor(SK_ColorRED); - canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, copy); + paint.setColor(SK_ColorRED); + canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint); - copy.setColor(SK_ColorBLUE); - canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom+1, copy); + paint.setColor(SK_ColorBLUE); + canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom+1, paint); - copy.setColor(SK_ColorCYAN); - canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top+1, copy); + paint.setColor(SK_ColorCYAN); + canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top+1, paint); - copy.setColor(SK_ColorYELLOW); - canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left+1, copy); + paint.setColor(SK_ColorYELLOW); + canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left+1, paint); - copy.setColor(SK_ColorGREEN); - canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right+1, copy); -} - -static void draw_random_patch(SkPoint points[12], SkColor colors[4], SkCanvas* canvas, - SkPaint& paint, SkRandom* rnd) { - SkPoint ptsCpy[12]; - memcpy(ptsCpy, points, 12 * sizeof(SkPoint)); - for (int i = 0; i < 5; i++) { - int index = rnd->nextRangeU(0, 11); - SkScalar dx = rnd->nextRangeScalar(-50, 50), dy = rnd->nextRangeScalar(-50, 50); - ptsCpy[index].offset(dx, dy); - } - SkPatch patch(ptsCpy, colors); - canvas->drawPatch(patch, paint); - draw_control_points(canvas, patch, paint); + paint.setColor(SK_ColorGREEN); + canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right+1, paint); } namespace skiagm { @@ -94,40 +80,51 @@ protected: } virtual uint32_t onGetFlags() const SK_OVERRIDE { - return kSkipTiled_Flag | kSkipPipe_Flag | kSkipPicture_Flag; + return kSkipTiled_Flag; } virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { SkPaint paint; - SkColor colors[4] = { + + // The order of the colors and points is clockwise starting at upper-left corner. + SkColor colors[SkPatch::kNumColors] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN }; - SkPoint points[12] = { + SkPoint points[SkPatch::kNumCtrlPts] = { + //top points {50,50},{75,20},{125,80}, {150,50}, - {120,75},{180,125},{150,150}, - {125,120},{75,180},{50,150}, + //right points + {120,75},{180,125}, + //bottom points + {150,150},{125,120},{75,180},{50,150}, + //left points {20,125},{80,75} }; - SkRandom rnd; - SkScalar scale = 0.5f; + SkPatch patch(points, colors); + static const SkScalar kScale = 0.5f; + canvas->translate(100, 100); canvas->save(); for (SkScalar x = 0; x < 4; x++) { canvas->save(); - canvas->scale(scale * (x + 1), scale * (x + 1)); + canvas->scale(kScale * (x + 1), kScale * (x + 1)); canvas->translate(x * 100, 0); - draw_random_patch(points, colors, canvas, paint, &rnd); + canvas->drawPatch(patch, paint); + draw_control_points(canvas, patch); canvas->restore(); } + canvas->translate(0, 270); - SkScalar skew = 0.1f; + + static const SkScalar kSkew = 0.2f; for (SkScalar x = 0; x < 4; x++) { canvas->save(); - canvas->scale(scale * (x + 1), scale * (x + 1)); - canvas->skew(skew * (x + 1), skew * (x + 1)); + canvas->scale(kScale * (x + 1), kScale * (x + 1)); canvas->translate(x * 100, 0); - draw_random_patch(points, colors, canvas, paint, &rnd); + canvas->skew(kSkew * (x + 1), kSkew * (x + 1)); + canvas->drawPatch(patch, paint); + draw_control_points(canvas, patch); canvas->restore(); } canvas->restore(); diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 5c4db207cc..f74ebb7f56 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -1008,6 +1008,13 @@ public: const uint16_t indices[], int indexCount, const SkPaint& paint); + /** + + Draw a SkPatch + + @param patch specifies the 4 bounding cubic bezier curves of a patch. + @param paint Specifies the shader/texture if present. + */ virtual void drawPatch(const SkPatch& patch, const SkPaint& paint); /** Send a blob of data to the canvas. diff --git a/include/core/SkPatch.h b/include/core/SkPatch.h index 3e06c3fc91..698b1cbf30 100644 --- a/include/core/SkPatch.h +++ b/include/core/SkPatch.h @@ -77,6 +77,12 @@ public: kBottomLeft_CornerColors }; + enum { + kNumCtrlPts = 12, + kNumColors = 4, + kNumPtsCubic = 4 + }; + /** * Points are in the following order: * (top curve) @@ -86,7 +92,8 @@ public: * 9 8 7 6 * (bottom curve) */ - SkPatch(SkPoint points[12], SkColor colors[4]); + SkPatch() { } + SkPatch(const SkPoint points[12], const SkColor colors[4]); /** * Function that evaluates the coons patch interpolation. @@ -138,9 +145,38 @@ public: return fCornerColors; } + void setPoints(const SkPoint points[12]) { + memcpy(fCtrlPoints, points, kNumCtrlPts * sizeof(SkPoint)); + } + + void setColors(const SkColor colors[4]) { + memcpy(fCornerColors, colors, kNumColors * sizeof(SkColor)); + } + + void reset(const SkPoint points[12], const SkColor colors[4]) { + this->setPoints(points); + this->setColors(colors); + } + + /** + * Write the patch to the buffer, and return the number of bytes written. + * If buffer is NULL, it still returns the number of bytes. + */ + size_t writeToMemory(void* buffer) const; + + /** + * Initializes the patch from the buffer + * + * buffer Memory to read from + * length Amount of memory available in the buffer + * returns the number of bytes read (must be a multiple of 4) or + * 0 if there was not enough memory available + */ + size_t readFromMemory(const void* buffer, size_t length); + private: - SkPoint fCtrlPoints[12]; - SkColor fCornerColors[4]; + SkPoint fCtrlPoints[kNumCtrlPts]; + SkColor fCornerColors[kNumColors]; }; #endif diff --git a/include/core/SkReadBuffer.h b/include/core/SkReadBuffer.h index 2beb7ac738..e4f33af038 100644 --- a/include/core/SkReadBuffer.h +++ b/include/core/SkReadBuffer.h @@ -108,6 +108,7 @@ public: virtual void readIRect(SkIRect* rect); virtual void readRect(SkRect* rect); virtual void readRegion(SkRegion* region); + virtual void readPatch(SkPatch* patch); virtual void readPath(SkPath* path); void readPaint(SkPaint* paint) { paint->unflatten(*this); } diff --git a/include/core/SkReader32.h b/include/core/SkReader32.h index 51e28ef146..3ee63bed18 100644 --- a/include/core/SkReader32.h +++ b/include/core/SkReader32.h @@ -15,6 +15,7 @@ #include "SkRegion.h" #include "SkRRect.h" #include "SkScalar.h" +#include "SkPatch.h" class SkString; @@ -105,21 +106,25 @@ public: uint16_t readU16() { return (uint16_t)this->readInt(); } int32_t readS32() { return this->readInt(); } uint32_t readU32() { return this->readInt(); } + + bool readPatch(SkPatch* patch) { + return this->readObjectFromMemory(patch); + } bool readPath(SkPath* path) { - return readObjectFromMemory(path); + return this->readObjectFromMemory(path); } bool readMatrix(SkMatrix* matrix) { - return readObjectFromMemory(matrix); + return this->readObjectFromMemory(matrix); } bool readRRect(SkRRect* rrect) { - return readObjectFromMemory(rrect); + return this->readObjectFromMemory(rrect); } bool readRegion(SkRegion* rgn) { - return readObjectFromMemory(rgn); + return this->readObjectFromMemory(rgn); } /** diff --git a/include/core/SkWriter32.h b/include/core/SkWriter32.h index fd24ba9ddf..737ffd581d 100644 --- a/include/core/SkWriter32.h +++ b/include/core/SkWriter32.h @@ -12,6 +12,7 @@ #include "SkData.h" #include "SkMatrix.h" +#include "SkPatch.h" #include "SkPath.h" #include "SkPoint.h" #include "SkRRect.h" @@ -137,6 +138,12 @@ public: void writeRRect(const SkRRect& rrect) { rrect.writeToMemory(this->reserve(SkRRect::kSizeInMemory)); } + + void writePatch(const SkPatch& patch) { + size_t size = patch.writeToMemory(NULL); + SkASSERT(SkAlign4(size) == size); + patch.writeToMemory(this->reserve(size)); + } void writePath(const SkPath& path) { size_t size = path.writeToMemory(NULL); diff --git a/include/utils/SkDumpCanvas.h b/include/utils/SkDumpCanvas.h index 91d698fa38..53b97554b5 100644 --- a/include/utils/SkDumpCanvas.h +++ b/include/utils/SkDumpCanvas.h @@ -46,6 +46,7 @@ public: kDrawText_Verb, kDrawPicture_Verb, kDrawVertices_Verb, + kDrawPatch_Verb, kDrawData_Verb, kBeginCommentGroup_Verb, @@ -95,6 +96,7 @@ public: const SkColor colors[], SkXfermode* xmode, const uint16_t indices[], int indexCount, const SkPaint& paint) SK_OVERRIDE; + virtual void drawPatch(const SkPatch& patch, const SkPaint& paint) SK_OVERRIDE; virtual void drawData(const void*, size_t) SK_OVERRIDE; virtual void beginCommentGroup(const char* description) SK_OVERRIDE; virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE; diff --git a/include/utils/SkNWayCanvas.h b/include/utils/SkNWayCanvas.h index aabf27436c..a4bfa887f9 100644 --- a/include/utils/SkNWayCanvas.h +++ b/include/utils/SkNWayCanvas.h @@ -48,6 +48,7 @@ public: const SkColor colors[], SkXfermode* xmode, const uint16_t indices[], int indexCount, const SkPaint&) SK_OVERRIDE; + virtual void drawPatch(const SkPatch& patch, const SkPaint& paint) SK_OVERRIDE; virtual void drawData(const void* data, size_t length) SK_OVERRIDE; virtual SkDrawFilter* setDrawFilter(SkDrawFilter*) SK_OVERRIDE; diff --git a/include/utils/SkProxyCanvas.h b/include/utils/SkProxyCanvas.h index 6055db9bed..d31806ff44 100644 --- a/include/utils/SkProxyCanvas.h +++ b/include/utils/SkProxyCanvas.h @@ -47,6 +47,7 @@ public: const SkColor colors[], SkXfermode* xmode, const uint16_t indices[], int indexCount, const SkPaint& paint) SK_OVERRIDE; + virtual void drawPatch(const SkPatch& patch, const SkPaint& paint) SK_OVERRIDE; virtual void drawData(const void* data, size_t length) SK_OVERRIDE; virtual void beginCommentGroup(const char* description) SK_OVERRIDE; diff --git a/src/core/SkBBoxRecord.cpp b/src/core/SkBBoxRecord.cpp index 448e8f65f4..802eb669bf 100644 --- a/src/core/SkBBoxRecord.cpp +++ b/src/core/SkBBoxRecord.cpp @@ -284,6 +284,15 @@ void SkBBoxRecord::drawVertices(VertexMode mode, int vertexCount, } } +void SkBBoxRecord::drawPatch(const SkPatch& patch, const SkPaint& paint) { + const SkPoint* points = patch.getControlPoints(); + SkRect bbox; + bbox.set(points, SkPatch::kNumCtrlPts); + if (this->transformBounds(bbox, &paint)) { + INHERITED::drawPatch(patch, paint); + } +} + void SkBBoxRecord::onDrawPicture(const SkPicture* picture) { if (picture->width() > 0 && picture->height() > 0 && this->transformBounds(SkRect::MakeWH(picture->width(), picture->height()), NULL)) { diff --git a/src/core/SkBBoxRecord.h b/src/core/SkBBoxRecord.h index a6edc98f13..d10626fa50 100644 --- a/src/core/SkBBoxRecord.h +++ b/src/core/SkBBoxRecord.h @@ -55,6 +55,7 @@ public: const SkColor colors[], SkXfermode* xfer, const uint16_t indices[], int indexCount, const SkPaint& paint) SK_OVERRIDE; + virtual void drawPatch(const SkPatch& patch, const SkPaint& paint) SK_OVERRIDE; protected: virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 3320d18fc0..757e711019 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -2258,7 +2258,7 @@ void SkCanvas::drawPatch(const SkPatch& patch, const SkPaint& paint) { // Since a patch is always within the convex hull of the control points, we discard it when its // bounding rectangle is completely outside the current clip. SkRect bounds; - bounds.set(patch.getControlPoints(), 12); + bounds.set(patch.getControlPoints(), SkPatch::kNumCtrlPts); if (this->quickReject(bounds)) { return; } diff --git a/src/core/SkPatch.cpp b/src/core/SkPatch.cpp index cc967d5cee..4cca2bad1d 100644 --- a/src/core/SkPatch.cpp +++ b/src/core/SkPatch.cpp @@ -9,6 +9,7 @@ #include "SkGeometry.h" #include "SkColorPriv.h" +#include "SkBuffer.h" //////////////////////////////////////////////////////////////////////////////// @@ -117,18 +118,12 @@ private: //////////////////////////////////////////////////////////////////////////////// -SkPatch::SkPatch(SkPoint points[12], SkColor colors[4]) { - - for (int i = 0; i < 12; i++) { - fCtrlPoints[i] = points[i]; - } - for (int i = 0; i < 4; i++) { - fCornerColors[i] = colors[i]; - } - +SkPatch::SkPatch(const SkPoint points[12], const SkColor colors[4]) { + this->reset(points, colors); } -uint8_t bilinear(SkScalar tx, SkScalar ty, SkScalar c00, SkScalar c10, SkScalar c01, SkScalar c11) { +static uint8_t bilerp(SkScalar tx, SkScalar ty, SkScalar c00, SkScalar c10, SkScalar c01, + SkScalar c11) { SkScalar a = c00 * (1.f - tx) + c10 * tx; SkScalar b = c01 * (1.f - tx) + c11 * tx; return uint8_t(a * (1.f - ty) + b * ty); @@ -141,8 +136,8 @@ bool SkPatch::getVertexData(SkPatch::VertexData* data, int lodX, int lodY) const } // premultiply colors to avoid color bleeding. - SkPMColor colors[4]; - for (int i = 0; i < 4; i++) { + SkPMColor colors[SkPatch::kNumColors]; + for (int i = 0; i < SkPatch::kNumColors; i++) { colors[i] = SkPreMultiplyColor(fCornerColors[i]); } @@ -157,7 +152,7 @@ bool SkPatch::getVertexData(SkPatch::VertexData* data, int lodX, int lodY) const data->fTexCoords = SkNEW_ARRAY(SkPoint, data->fVertexCount); data->fIndices = SkNEW_ARRAY(uint16_t, data->fIndexCount); - SkPoint pts[4]; + SkPoint pts[SkPatch::kNumPtsCubic]; this->getBottomPoints(pts); FwDCubicEvaluator fBottom(pts); this->getTopPoints(pts); @@ -197,22 +192,22 @@ bool SkPatch::getVertexData(SkPatch::VertexData* data, int lodX, int lodY) const + u * fBottom.getCtrlPoints()[3].y())); data->fPoints[dataIndex] = s0 + s1 - s2; - uint8_t a = bilinear(u, v, + uint8_t a = bilerp(u, v, SkScalar(SkColorGetA(colors[kTopLeft_CornerColors])), SkScalar(SkColorGetA(colors[kTopRight_CornerColors])), SkScalar(SkColorGetA(colors[kBottomLeft_CornerColors])), SkScalar(SkColorGetA(colors[kBottomRight_CornerColors]))); - uint8_t r = bilinear(u, v, + uint8_t r = bilerp(u, v, SkScalar(SkColorGetR(colors[kTopLeft_CornerColors])), SkScalar(SkColorGetR(colors[kTopRight_CornerColors])), SkScalar(SkColorGetR(colors[kBottomLeft_CornerColors])), SkScalar(SkColorGetR(colors[kBottomRight_CornerColors]))); - uint8_t g = bilinear(u, v, + uint8_t g = bilerp(u, v, SkScalar(SkColorGetG(colors[kTopLeft_CornerColors])), SkScalar(SkColorGetG(colors[kTopRight_CornerColors])), SkScalar(SkColorGetG(colors[kBottomLeft_CornerColors])), SkScalar(SkColorGetG(colors[kBottomRight_CornerColors]))); - uint8_t b = bilinear(u, v, + uint8_t b = bilerp(u, v, SkScalar(SkColorGetB(colors[kTopLeft_CornerColors])), SkScalar(SkColorGetB(colors[kTopRight_CornerColors])), SkScalar(SkColorGetB(colors[kBottomLeft_CornerColors])), @@ -236,3 +231,32 @@ bool SkPatch::getVertexData(SkPatch::VertexData* data, int lodX, int lodY) const } return true; } + +size_t SkPatch::writeToMemory(void* storage) const { + int byteCount = kNumCtrlPts * sizeof(SkPoint) + kNumColors * sizeof(SkColor); + + if (NULL == storage) { + return SkAlign4(byteCount); + } + + SkWBuffer buffer(storage); + + buffer.write(fCtrlPoints, kNumCtrlPts * sizeof(SkPoint)); + buffer.write(fCornerColors, kNumColors * sizeof(SkColor)); + + buffer.padToAlign4(); + return buffer.pos(); +} + +size_t SkPatch::readFromMemory(const void* storage, size_t length) { + SkRBufferWithSizeCheck buffer(storage, length); + + if (!buffer.read(fCtrlPoints, kNumCtrlPts * sizeof(SkPoint))) { + return 0; + } + + if (!buffer.read(fCornerColors, kNumColors * sizeof(SkColor))) { + return 0; + } + return kNumCtrlPts * sizeof(SkPoint) + kNumColors * sizeof(SkColor); +} diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h index 5d1a6b52d6..2be929b869 100644 --- a/src/core/SkPictureFlat.h +++ b/src/core/SkPictureFlat.h @@ -67,8 +67,10 @@ enum DrawType { DRAW_DRRECT, PUSH_CULL, POP_CULL, + + DRAW_PATCH, // could not add in aphabetical order - LAST_DRAWTYPE_ENUM = POP_CULL + LAST_DRAWTYPE_ENUM = DRAW_PATCH }; // 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 d16a6353e9..59abe7c114 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -306,6 +306,12 @@ void SkPicturePlayback::handleOp(SkReader32* reader, case DRAW_PAINT: canvas->drawPaint(*fPictureData->getPaint(reader)); break; + case DRAW_PATCH: { + const SkPaint& paint = *fPictureData->getPaint(reader); + SkPatch patch; + reader->readPatch(&patch); + canvas->drawPatch(patch, paint); + } break; case DRAW_PATH: { const SkPaint& paint = *fPictureData->getPaint(reader); canvas->drawPath(fPictureData->getPath(reader), paint); diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index ab4c3fa38e..72c537bd75 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -122,6 +122,7 @@ static inline size_t getPaintOffset(DrawType op, size_t opSize) { 1, // DRAWDRRECT - right after op code 0, // PUSH_CULL - no paint 0, // POP_CULL - no paint + 1, // DRAW_PATCH - right after op code }; SK_COMPILE_ASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1, @@ -1480,6 +1481,21 @@ void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount, this->validate(initialOffset, size); } +void SkPictureRecord::drawPatch(const SkPatch& patch, const SkPaint& paint) { +#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE + fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType); +#endif + + // op + paint index + patch 12 control points + patch 4 colors + size_t size = 2 * kUInt32Size + SkPatch::kNumCtrlPts * sizeof(SkPoint) + + SkPatch::kNumColors * sizeof(SkColor); + size_t initialOffset = this->addDraw(DRAW_PATCH, &size); + SkASSERT(initialOffset+getPaintOffset(DRAW_PATCH, size) == fWriter.bytesWritten()); + this->addPaint(paint); + this->addPatch(patch); + this->validate(initialOffset, size); +} + void SkPictureRecord::drawData(const void* data, size_t length) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE @@ -1613,6 +1629,10 @@ void SkPictureRecord::addPath(const SkPath& path) { this->addInt(this->addPathToHeap(path)); } +void SkPictureRecord::addPatch(const SkPatch& patch) { + fWriter.writePatch(patch); +} + void SkPictureRecord::addPicture(const SkPicture* picture) { int index = fPictureRefs.find(picture); if (index < 0) { // not found diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index a1b52fb195..140558d147 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -61,6 +61,7 @@ public: const SkColor colors[], SkXfermode*, const uint16_t indices[], int indexCount, const SkPaint&) SK_OVERRIDE; + virtual void drawPatch(const SkPatch& patch, const SkPaint& paint) SK_OVERRIDE; virtual void drawData(const void*, size_t) SK_OVERRIDE; virtual void beginCommentGroup(const char* description) SK_OVERRIDE; virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE; @@ -177,6 +178,7 @@ private: const SkFlatData* addPaint(const SkPaint& paint) { return this->addPaintPtr(&paint); } const SkFlatData* addPaintPtr(const SkPaint* paint); void addFlatPaint(const SkFlatData* flatPaint); + void addPatch(const SkPatch& patch); void addPath(const SkPath& path); void addPicture(const SkPicture* picture); void addPoint(const SkPoint& point); diff --git a/src/core/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp index 43587862b9..27f2d2b3ac 100644 --- a/src/core/SkReadBuffer.cpp +++ b/src/core/SkReadBuffer.cpp @@ -148,6 +148,10 @@ void SkReadBuffer::readRegion(SkRegion* region) { fReader.readRegion(region); } +void SkReadBuffer::readPatch(SkPatch* patch) { + fReader.readPatch(patch); +} + void SkReadBuffer::readPath(SkPath* path) { fReader.readPath(path); } diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index 89efb8e18b..ac463194a6 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -63,6 +63,7 @@ DRAW(DrawDRRect, drawDRRect(r.outer, r.inner, r.paint)); DRAW(DrawOval, drawOval(r.oval, r.paint)); DRAW(DrawPaint, drawPaint(r.paint)); DRAW(DrawPath, drawPath(r.path, r.paint)); +DRAW(DrawPatch, drawPatch(r.patch, r.paint)); DRAW(DrawPoints, drawPoints(r.mode, r.count, r.pts, r.paint)); DRAW(DrawPosText, drawPosText(r.text, r.byteLength, r.pos, r.paint)); DRAW(DrawPosTextH, drawPosTextH(r.text, r.byteLength, r.xpos, r.y, r.paint)); diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 4c02a35c9f..255eb393b3 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -206,6 +206,10 @@ void SkRecorder::drawVertices(VertexMode vmode, indexCount); } +void SkRecorder::drawPatch(const SkPatch& patch, const SkPaint& paint) { + APPEND(DrawPatch, delay_copy(paint), delay_copy(patch)); +} + void SkRecorder::willSave() { APPEND(Save); INHERITED(willSave); diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index 0eb11d7af8..6eba19e5e7 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -61,6 +61,7 @@ public: const uint16_t indices[], int indexCount, const SkPaint& paint) SK_OVERRIDE; + void drawPatch(const SkPatch& patch, const SkPaint& paint) SK_OVERRIDE; void willSave() SK_OVERRIDE; SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SkCanvas::SaveFlags) SK_OVERRIDE; diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h index 02cfc64032..e6d98f7a1d 100644 --- a/src/core/SkRecords.h +++ b/src/core/SkRecords.h @@ -45,6 +45,7 @@ namespace SkRecords { M(DrawOval) \ M(DrawPaint) \ M(DrawPath) \ + M(DrawPatch) \ M(DrawPoints) \ M(DrawPosText) \ M(DrawPosTextH) \ @@ -217,6 +218,7 @@ RECORD3(DrawDRRect, SkPaint, paint, SkRRect, outer, SkRRect, inner); RECORD2(DrawOval, SkPaint, paint, SkRect, oval); RECORD1(DrawPaint, SkPaint, paint); RECORD2(DrawPath, SkPaint, paint, SkPath, path); +RECORD2(DrawPatch, SkPaint, paint, SkPatch, patch); RECORD4(DrawPoints, SkPaint, paint, SkCanvas::PointMode, mode, size_t, count, SkPoint*, pts); RECORD4(DrawPosText, SkPaint, paint, PODArray<char>, text, diff --git a/src/core/SkValidatingReadBuffer.cpp b/src/core/SkValidatingReadBuffer.cpp index 037a99465b..8202149cc1 100644 --- a/src/core/SkValidatingReadBuffer.cpp +++ b/src/core/SkValidatingReadBuffer.cpp @@ -171,6 +171,17 @@ void SkValidatingReadBuffer::readPath(SkPath* path) { } } +void SkValidatingReadBuffer::readPatch(SkPatch* patch) { + size_t size = 0; + if (!fError) { + size = patch->readFromMemory(fReader.peek(), fReader.available()); + this->validate((SkAlign4(size) == size) && (0 != size)); + } + if (!fError) { + (void)this->skip(size); + } +} + bool SkValidatingReadBuffer::readArray(void* value, size_t size, size_t elementSize) { const uint32_t count = this->getArrayCount(); this->validate(size == count); diff --git a/src/core/SkValidatingReadBuffer.h b/src/core/SkValidatingReadBuffer.h index 5cf3abed68..8850a07646 100644 --- a/src/core/SkValidatingReadBuffer.h +++ b/src/core/SkValidatingReadBuffer.h @@ -46,6 +46,7 @@ public: virtual void readIRect(SkIRect* rect) SK_OVERRIDE; virtual void readRect(SkRect* rect) SK_OVERRIDE; virtual void readRegion(SkRegion* region) SK_OVERRIDE; + virtual void readPatch(SkPatch* patch) SK_OVERRIDE; virtual void readPath(SkPath* path) SK_OVERRIDE; // binary data and arrays diff --git a/src/pipe/SkGPipePriv.h b/src/pipe/SkGPipePriv.h index 58cafe80b1..821da0ff25 100644 --- a/src/pipe/SkGPipePriv.h +++ b/src/pipe/SkGPipePriv.h @@ -48,6 +48,7 @@ enum DrawOps { kDrawDRRect_DrawOp, kDrawOval_DrawOp, kDrawPaint_DrawOp, + kDrawPatch_DrawOp, kDrawPath_DrawOp, kDrawPicture_DrawOp, kDrawPoints_DrawOp, diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp index 9047e8293f..35b0a94570 100644 --- a/src/pipe/SkGPipeRead.cpp +++ b/src/pipe/SkGPipeRead.cpp @@ -404,6 +404,15 @@ static void drawDRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, } } +static void drawPatch_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, + SkGPipeState* state) { + SkPatch patch; + reader->readPatch(&patch); + if (state->shouldDraw()) { + canvas->drawPatch(patch, state->paint()); + } +} + static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { SkPath path; @@ -775,6 +784,7 @@ static const ReadProc gReadTable[] = { drawDRRect_rp, drawOval_rp, drawPaint_rp, + drawPatch_rp, drawPath_rp, drawPicture_rp, drawPoints_rp, diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp index 46e4260f31..186b66cd98 100644 --- a/src/pipe/SkGPipeWrite.cpp +++ b/src/pipe/SkGPipeWrite.cpp @@ -254,6 +254,7 @@ public: const SkColor colors[], SkXfermode*, const uint16_t indices[], int indexCount, const SkPaint&) SK_OVERRIDE; + virtual void drawPatch(const SkPatch& patch, const SkPaint& paint) SK_OVERRIDE; virtual void drawData(const void*, size_t) SK_OVERRIDE; virtual void beginCommentGroup(const char* description) SK_OVERRIDE; virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE; @@ -997,6 +998,15 @@ void SkGPipeCanvas::drawVertices(VertexMode vmode, int vertexCount, } } +void SkGPipeCanvas::drawPatch(const SkPatch& patch, const SkPaint& paint) { + NOTIFY_SETUP(this); + this->writePaint(paint); + if (this->needOpBytes(patch.writeToMemory(NULL))) { + this->writeOp(kDrawPatch_DrawOp); + fWriter.writePatch(patch); + } +} + void SkGPipeCanvas::drawData(const void* ptr, size_t size) { if (size && ptr) { NOTIFY_SETUP(this); diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp index 2820bac48d..17a1f6c461 100644 --- a/src/utils/SkDeferredCanvas.cpp +++ b/src/utils/SkDeferredCanvas.cpp @@ -917,7 +917,9 @@ void SkDeferredCanvas::drawVertices(VertexMode vmode, int vertexCount, } void SkDeferredCanvas::drawPatch(const SkPatch& patch, const SkPaint& paint) { - //TODO + AutoImmediateDrawIfNeeded autoDraw(*this, &paint); + this->drawingCanvas()->drawPatch(patch, paint); + this->recordedDrawCommand(); } SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp index b12928fbbb..3c683e67c5 100644 --- a/src/utils/SkDumpCanvas.cpp +++ b/src/utils/SkDumpCanvas.cpp @@ -442,6 +442,19 @@ void SkDumpCanvas::drawVertices(VertexMode vmode, int vertexCount, SkScalarToFloat(vertices[0].fY)); } +void SkDumpCanvas::drawPatch(const SkPatch& patch, const SkPaint& paint) { + const SkPoint* points = patch.getControlPoints(); + const SkColor* color = patch.getColors(); + //dumps corner points and colors in clockwise order starting on upper-left corner + this->dump(kDrawPatch_Verb, &paint, "drawPatch(Vertices{[%f, %f], [%f, %f], [%f, %f], [%f, %f]}\ + | Colors{[0x%x], [0x%x], [0x%x], [0x%x]})", + points[SkPatch::kTopP0_CubicCtrlPts].fX, points[SkPatch::kTopP0_CubicCtrlPts].fY, + points[SkPatch::kTopP3_CubicCtrlPts].fX, points[SkPatch::kTopP3_CubicCtrlPts].fY, + points[SkPatch::kBottomP3_CubicCtrlPts].fX,points[SkPatch::kBottomP3_CubicCtrlPts].fY, + points[SkPatch::kBottomP0_CubicCtrlPts].fX,points[SkPatch::kBottomP0_CubicCtrlPts].fY, + color[0], color[1], color[2], color[3]); +} + void SkDumpCanvas::drawData(const void* data, size_t length) { // this->dump(kDrawData_Verb, NULL, "drawData(%d)", length); this->dump(kDrawData_Verb, NULL, "drawData(%d) %.*s", length, diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp index 11e4a65349..b33c99ea4f 100644 --- a/src/utils/SkNWayCanvas.cpp +++ b/src/utils/SkNWayCanvas.cpp @@ -284,6 +284,13 @@ void SkNWayCanvas::drawVertices(VertexMode vmode, int vertexCount, } } +void SkNWayCanvas::drawPatch(const SkPatch& patch, const SkPaint& paint) { + Iter iter(fList); + while (iter.next()) { + iter->drawPatch(patch, paint); + } +} + void SkNWayCanvas::drawData(const void* data, size_t length) { Iter iter(fList); while (iter.next()) { diff --git a/src/utils/SkPatchUtils.cpp b/src/utils/SkPatchUtils.cpp index 7dd0a09d97..ab15290a34 100644 --- a/src/utils/SkPatchUtils.cpp +++ b/src/utils/SkPatchUtils.cpp @@ -7,10 +7,8 @@ #include "SkPatchUtils.h" -#include "SkGeometry.h" - // size in pixels of each partition per axis, adjust this knob -static const int kPartitionSize = 30; +static const int kPartitionSize = 15; /** * Calculate the approximate arc length given a bezier curve's control points. diff --git a/src/utils/SkProxyCanvas.cpp b/src/utils/SkProxyCanvas.cpp index 3aa459cdfa..1029f4005f 100644 --- a/src/utils/SkProxyCanvas.cpp +++ b/src/utils/SkProxyCanvas.cpp @@ -149,6 +149,10 @@ void SkProxyCanvas::drawVertices(VertexMode vmode, int vertexCount, xmode, indices, indexCount, paint); } +void SkProxyCanvas::drawPatch(const SkPatch& patch, const SkPaint& paint) { + fProxy->drawPatch(patch, paint); +} + void SkProxyCanvas::drawData(const void* data, size_t length) { fProxy->drawData(data, length); } |