aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/patch.cpp105
-rw-r--r--include/core/SkCanvas.h7
-rw-r--r--include/core/SkPatch.h42
-rw-r--r--include/core/SkReadBuffer.h1
-rw-r--r--include/core/SkReader32.h13
-rw-r--r--include/core/SkWriter32.h7
-rw-r--r--include/utils/SkDumpCanvas.h2
-rw-r--r--include/utils/SkNWayCanvas.h1
-rw-r--r--include/utils/SkProxyCanvas.h1
-rw-r--r--src/core/SkBBoxRecord.cpp9
-rw-r--r--src/core/SkBBoxRecord.h1
-rw-r--r--src/core/SkCanvas.cpp2
-rw-r--r--src/core/SkPatch.cpp58
-rw-r--r--src/core/SkPictureFlat.h4
-rw-r--r--src/core/SkPicturePlayback.cpp6
-rw-r--r--src/core/SkPictureRecord.cpp20
-rw-r--r--src/core/SkPictureRecord.h2
-rw-r--r--src/core/SkReadBuffer.cpp4
-rw-r--r--src/core/SkRecordDraw.cpp1
-rw-r--r--src/core/SkRecorder.cpp4
-rw-r--r--src/core/SkRecorder.h1
-rw-r--r--src/core/SkRecords.h2
-rw-r--r--src/core/SkValidatingReadBuffer.cpp11
-rw-r--r--src/core/SkValidatingReadBuffer.h1
-rw-r--r--src/pipe/SkGPipePriv.h1
-rw-r--r--src/pipe/SkGPipeRead.cpp10
-rw-r--r--src/pipe/SkGPipeWrite.cpp10
-rw-r--r--src/utils/SkDeferredCanvas.cpp4
-rw-r--r--src/utils/SkDumpCanvas.cpp13
-rw-r--r--src/utils/SkNWayCanvas.cpp7
-rw-r--r--src/utils/SkPatchUtils.cpp4
-rw-r--r--src/utils/SkProxyCanvas.cpp4
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);
}