Stopped skipping tests in dm of SkPatch by implementing the
corresponding drawPath calls on classes that derive from SkCanvas. BUG=skia: R=egdaniel@google.com, bsalomon@google.com, mtklein@google.com, robertphillips@google.com Author: dandov@google.com Review URL: https://codereview.chromium.org/429343004
This commit is contained in:
parent
2dd85a3eb2
commit
963137b75c
105
gm/patch.cpp
105
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();
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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); }
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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*
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -48,6 +48,7 @@ enum DrawOps {
|
||||
kDrawDRRect_DrawOp,
|
||||
kDrawOval_DrawOp,
|
||||
kDrawPaint_DrawOp,
|
||||
kDrawPatch_DrawOp,
|
||||
kDrawPath_DrawOp,
|
||||
kDrawPicture_DrawOp,
|
||||
kDrawPoints_DrawOp,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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()) {
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user