As part of preliminary groundwork for a chromium fix, this changelist is deprecating GrPathFill so that SkPath::FillType is used everywhere in order to remove some code duplication between Skia and Ganesh.
BUG=chromium:135111
TEST=Try path rendering tests from the gm
Review URL: https://codereview.appspot.com/6875058
git-svn-id: http://skia.googlecode.com/svn/trunk@6693 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index 942342d..b85e827 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -88,7 +88,7 @@
}
/** Returns true if the filltype is one of the Inverse variants */
- bool isInverseFillType() const { return (fFillType & 2) != 0; }
+ bool isInverseFillType() const { return IsInverseFill((FillType)fFillType); }
/**
* Toggle between inverse and normal filltypes. This reverse the return
@@ -522,6 +522,28 @@
}
/**
+ * Returns whether or not a fill type is inverted
+ */
+ static bool IsInverseFill(FillType fill) {
+ SK_COMPILE_ASSERT(0 == kWinding_FillType, fill_type_mismatch);
+ SK_COMPILE_ASSERT(1 == kEvenOdd_FillType, fill_type_mismatch);
+ SK_COMPILE_ASSERT(2 == kInverseWinding_FillType, fill_type_mismatch);
+ SK_COMPILE_ASSERT(3 == kInverseEvenOdd_FillType, fill_type_mismatch);
+ return (fill & 2) != 0;
+ }
+
+ /**
+ * Returns the equivalent non-inverted fill type to the given fill type
+ */
+ static FillType NonInverseFill(FillType fill) {
+ SK_COMPILE_ASSERT(0 == kWinding_FillType, fill_type_mismatch);
+ SK_COMPILE_ASSERT(1 == kEvenOdd_FillType, fill_type_mismatch);
+ SK_COMPILE_ASSERT(2 == kInverseWinding_FillType, fill_type_mismatch);
+ SK_COMPILE_ASSERT(3 == kInverseEvenOdd_FillType, fill_type_mismatch);
+ return (FillType)(fill & 1);
+ }
+
+ /**
* Tries to quickly compute the direction of the first non-degenerate
* contour. If it can be computed, return true and set dir to that
* direction. If it cannot be (quickly) determined, return false and ignore
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 08de94f..7b14fdf 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -40,6 +40,7 @@
class GrVertexBuffer;
class GrVertexBufferAllocPool;
class GrSoftwarePathRenderer;
+class SkStroke;
class GR_API GrContext : public GrRefCnt {
public:
@@ -417,11 +418,9 @@
*
* @param paint describes how to color pixels.
* @param path the path to draw
- * @param fill the path filling rule to use.
- * @param translate optional additional translation applied to the
- * path.
+ * @param doHairLine whether the stroke can be optimized as a hairline
*/
- void drawPath(const GrPaint& paint, const SkPath& path, GrPathFill fill);
+ void drawPath(const GrPaint& paint, const SkPath& path, bool doHairLine);
/**
* Draws vertices with a paint.
@@ -849,7 +848,7 @@
GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt);
GrPathRenderer* getPathRenderer(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target,
bool antiAlias,
bool allowSW);
@@ -912,7 +911,7 @@
/// draw state is left unmodified.
GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw);
- void internalDrawPath(const GrPaint& paint, const SkPath& path, GrPathFill fill);
+ void internalDrawPath(const GrPaint& paint, const SkPath& path, const SkStroke& stroke);
GrTexture* createResizedTexture(const GrTextureDesc& desc,
const GrCacheData& cacheData,
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index 3c730df..21ae6de 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -540,53 +540,6 @@
return gNumPoints[cmd];
}
-/**
- * Path filling rules
- */
-enum GrPathFill {
- kWinding_GrPathFill,
- kEvenOdd_GrPathFill,
- kInverseWinding_GrPathFill,
- kInverseEvenOdd_GrPathFill,
- kHairLine_GrPathFill,
-
- kGrPathFillCount
-};
-
-static inline GrPathFill GrNonInvertedFill(GrPathFill fill) {
- static const GrPathFill gNonInvertedFills[] = {
- kWinding_GrPathFill, // kWinding_GrPathFill
- kEvenOdd_GrPathFill, // kEvenOdd_GrPathFill
- kWinding_GrPathFill, // kInverseWinding_GrPathFill
- kEvenOdd_GrPathFill, // kInverseEvenOdd_GrPathFill
- kHairLine_GrPathFill,// kHairLine_GrPathFill
- };
- GR_STATIC_ASSERT(0 == kWinding_GrPathFill);
- GR_STATIC_ASSERT(1 == kEvenOdd_GrPathFill);
- GR_STATIC_ASSERT(2 == kInverseWinding_GrPathFill);
- GR_STATIC_ASSERT(3 == kInverseEvenOdd_GrPathFill);
- GR_STATIC_ASSERT(4 == kHairLine_GrPathFill);
- GR_STATIC_ASSERT(5 == kGrPathFillCount);
- return gNonInvertedFills[fill];
-}
-
-static inline bool GrIsFillInverted(GrPathFill fill) {
- static const bool gIsFillInverted[] = {
- false, // kWinding_GrPathFill
- false, // kEvenOdd_GrPathFill
- true, // kInverseWinding_GrPathFill
- true, // kInverseEvenOdd_GrPathFill
- false, // kHairLine_GrPathFill
- };
- GR_STATIC_ASSERT(0 == kWinding_GrPathFill);
- GR_STATIC_ASSERT(1 == kEvenOdd_GrPathFill);
- GR_STATIC_ASSERT(2 == kInverseWinding_GrPathFill);
- GR_STATIC_ASSERT(3 == kInverseEvenOdd_GrPathFill);
- GR_STATIC_ASSERT(4 == kHairLine_GrPathFill);
- GR_STATIC_ASSERT(5 == kGrPathFillCount);
- return gIsFillInverted[fill];
-}
-
///////////////////////////////////////////////////////////////////////////////
// opaque type for 3D API object handles
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 80ca301..fe95514 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -576,7 +576,7 @@
*isClosed = autoClose;
}
if (result && direction) {
- *direction = firstDirection == (lastDirection + 1 & 3) ? kCCW_Direction : kCW_Direction;
+ *direction = firstDirection == ((lastDirection + 1) & 3) ? kCCW_Direction : kCW_Direction;
}
return result;
}
diff --git a/src/core/SkStroke.h b/src/core/SkStroke.h
index 4880516..33a7ecb 100644
--- a/src/core/SkStroke.h
+++ b/src/core/SkStroke.h
@@ -32,6 +32,7 @@
void setMiterLimit(SkScalar);
void setWidth(SkScalar);
+ SkScalar getWidthIfStroked() const { return fDoFill ? -SK_Scalar1 : fWidth; }
bool getDoFill() const { return SkToBool(fDoFill); }
void setDoFill(bool doFill) { fDoFill = SkToU8(doFill); }
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index ebfcd7b..f8ded78 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -12,9 +12,9 @@
#include "GrDrawState.h"
#include "GrPathUtils.h"
#include "SkString.h"
+#include "SkStroke.h"
#include "SkTrace.h"
-
GrAAConvexPathRenderer::GrAAConvexPathRenderer() {
}
@@ -429,20 +429,15 @@
}
bool GrAAConvexPathRenderer::canDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target,
bool antiAlias) const {
- if (!target->getCaps().shaderDerivativeSupport() || !antiAlias ||
- kHairLine_GrPathFill == fill || GrIsFillInverted(fill) ||
- !path.isConvex()) {
- return false;
- } else {
- return true;
- }
+ return (target->getCaps().shaderDerivativeSupport() && antiAlias &&
+ stroke.getDoFill() && !path.isInverseFillType() && path.isConvex());
}
bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
- GrPathFill fill,
+ const SkStroke&,
GrDrawTarget* target,
bool antiAlias) {
diff --git a/src/gpu/GrAAConvexPathRenderer.h b/src/gpu/GrAAConvexPathRenderer.h
index 7a2fd38..a64596c 100644
--- a/src/gpu/GrAAConvexPathRenderer.h
+++ b/src/gpu/GrAAConvexPathRenderer.h
@@ -14,13 +14,13 @@
GrAAConvexPathRenderer();
virtual bool canDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target,
bool antiAlias) const SK_OVERRIDE;
protected:
virtual bool onDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target,
bool antiAlias) SK_OVERRIDE;
};
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index cd3f774..6424ad5 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -14,6 +14,7 @@
#include "GrIndexBuffer.h"
#include "GrPathUtils.h"
#include "SkGeometry.h"
+#include "SkStroke.h"
#include "SkTemplates.h"
namespace {
@@ -546,10 +547,10 @@
}
bool GrAAHairLinePathRenderer::canDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target,
bool antiAlias) const {
- if (fill != kHairLine_GrPathFill || !antiAlias) {
+ if ((0 != stroke.getWidthIfStroked()) || !antiAlias) {
return false;
}
@@ -563,7 +564,7 @@
}
bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke&,
GrDrawTarget* target,
bool antiAlias) {
diff --git a/src/gpu/GrAAHairLinePathRenderer.h b/src/gpu/GrAAHairLinePathRenderer.h
index 9129a89..653fd01 100644
--- a/src/gpu/GrAAHairLinePathRenderer.h
+++ b/src/gpu/GrAAHairLinePathRenderer.h
@@ -18,13 +18,13 @@
static GrPathRenderer* Create(GrContext* context);
virtual bool canDrawPath(const SkPath& path,
- GrPathFill fill,
- const GrDrawTarget* target,
- bool antiAlias) const SK_OVERRIDE;
+ const SkStroke& stroke,
+ const GrDrawTarget* target,
+ bool antiAlias) const SK_OVERRIDE;
protected:
virtual bool onDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target,
bool antiAlias) SK_OVERRIDE;
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index ff78bf9..5dfc6fa 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -14,6 +14,7 @@
#include "GrPathRenderer.h"
#include "GrPaint.h"
#include "SkRasterClip.h"
+#include "SkStroke.h"
#include "GrAAConvexPathRenderer.h"
#include "GrAAHairLinePathRenderer.h"
#include "GrSWMaskHelper.h"
@@ -57,26 +58,10 @@
bool path_needs_SW_renderer(GrContext* context,
GrGpu* gpu,
const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
bool doAA) {
// last (false) parameter disallows use of the SW path renderer
- return NULL == context->getPathRenderer(path, fill, gpu, doAA, false);
-}
-
-GrPathFill get_path_fill(const SkPath& path) {
- switch (path.getFillType()) {
- case SkPath::kWinding_FillType:
- return kWinding_GrPathFill;
- case SkPath::kEvenOdd_FillType:
- return kEvenOdd_GrPathFill;
- case SkPath::kInverseWinding_FillType:
- return kInverseWinding_GrPathFill;
- case SkPath::kInverseEvenOdd_FillType:
- return kInverseEvenOdd_GrPathFill;
- default:
- GrCrash("Unsupported path fill in clip.");
- return kWinding_GrPathFill; // suppress warning
- }
+ return NULL == context->getPathRenderer(path, stroke, gpu, doAA, false);
}
/**
@@ -117,6 +102,9 @@
SkClipStack::Iter iter(clipIn, SkClipStack::Iter::kBottom_IterStart);
const Element* element = NULL;
+ SkStroke stroke;
+ stroke.setDoFill(true);
+
for (element = iter.skipToTopmost(SkRegion::kReplace_Op);
NULL != element;
element = iter.next()) {
@@ -126,7 +114,7 @@
if (Element::kPath_Type == element->getType() &&
path_needs_SW_renderer(this->getContext(), fGpu,
element->getPath(),
- get_path_fill(element->getPath()),
+ stroke,
element->isAA())) {
useSW = true;
}
@@ -407,13 +395,15 @@
bool draw_path_in_software(GrContext* context,
GrGpu* gpu,
const SkPath& path,
- GrPathFill fill,
bool doAA,
const GrIRect& resultBounds) {
+ SkStroke stroke;
+ stroke.setDoFill(true);
SkAutoTUnref<GrTexture> texture(
GrSWMaskHelper::DrawPathMaskToTexture(context, path,
- resultBounds, fill,
+ stroke,
+ resultBounds,
doAA, NULL));
if (NULL == texture) {
return false;
@@ -424,7 +414,7 @@
GrSWMaskHelper::DrawToTargetWithPathMask(texture, gpu, rect);
- GrAssert(!GrIsFillInverted(fill));
+ GrAssert(!path.isInverseFillType());
return true;
}
@@ -433,16 +423,17 @@
bool draw_path(GrContext* context,
GrGpu* gpu,
const SkPath& path,
- GrPathFill fill,
bool doAA,
const GrIRect& resultBounds) {
+ SkStroke stroke;
+ stroke.setDoFill(true);
- GrPathRenderer* pr = context->getPathRenderer(path, fill, gpu, doAA, false);
+ GrPathRenderer* pr = context->getPathRenderer(path, stroke, gpu, doAA, false);
if (NULL == pr) {
- return draw_path_in_software(context, gpu, path, fill, doAA, resultBounds);
+ return draw_path_in_software(context, gpu, path, doAA, resultBounds);
}
- pr->drawPath(path, fill, gpu, doAA);
+ pr->drawPath(path, stroke, gpu, doAA);
return true;
}
@@ -478,7 +469,6 @@
case Element::kPath_Type:
return draw_path(this->getContext(), fGpu,
element->getPath(),
- get_path_fill(element->getPath()),
element->isAA(),
resultBounds);
default:
@@ -786,7 +776,7 @@
// walk through each clip element and perform its set op
// with the existing clip.
for ( ; NULL != element; element = iter.next()) {
- GrPathFill fill;
+ SkPath::FillType fill;
bool fillInverted = false;
// enabled at bottom of loop
drawState->disableState(GrGpu::kModifyStencilClip_StateBit);
@@ -800,6 +790,9 @@
// resolve in/out status?
bool canRenderDirectToStencil = false;
+ SkStroke stroke;
+ stroke.setDoFill(true);
+
SkRegion::Op op = element->getOp();
if (first) {
first = false;
@@ -807,10 +800,10 @@
}
GrPathRenderer* pr = NULL;
- const SkPath* clipPath = NULL;
+ SkPath clipPath;
if (Element::kRect_Type == element->getType()) {
canRenderDirectToStencil = true;
- fill = kEvenOdd_GrPathFill;
+ fill = SkPath::kEvenOdd_FillType;
fillInverted = false;
// there is no point in intersecting a screen filling
// rectangle.
@@ -820,17 +813,18 @@
}
} else {
GrAssert(Element::kPath_Type == element->getType());
- clipPath = &element->getPath();
- fill = get_path_fill(*clipPath);
- fillInverted = GrIsFillInverted(fill);
- fill = GrNonInvertedFill(fill);
- pr = this->getContext()->getPathRenderer(*clipPath, fill, fGpu, false, true);
+ clipPath = element->getPath();
+ fill = clipPath.getFillType();
+ fillInverted = clipPath.isInverseFillType();
+ fill = SkPath::NonInverseFill(fill);
+ clipPath.setFillType(fill);
+ pr = this->getContext()->getPathRenderer(clipPath, stroke, fGpu, false, true);
if (NULL == pr) {
fGpu->setClip(oldClipData);
return false;
}
canRenderDirectToStencil =
- !pr->requiresStencilPass(*clipPath, fill, fGpu);
+ !pr->requiresStencilPass(clipPath, stroke, fGpu);
}
int passes;
@@ -865,9 +859,9 @@
GrAssert(Element::kPath_Type == element->getType());
if (canRenderDirectToStencil) {
*drawState->stencil() = gDrawToStencil;
- pr->drawPath(*clipPath, fill, fGpu, false);
+ pr->drawPath(clipPath, stroke, fGpu, false);
} else {
- pr->drawPathToStencil(*clipPath, fill, fGpu);
+ pr->drawPathToStencil(clipPath, stroke, fGpu);
}
}
}
@@ -884,7 +878,7 @@
} else {
GrAssert(Element::kPath_Type == element->getType());
SET_RANDOM_COLOR
- pr->drawPath(*clipPath, fill, fGpu, false);
+ pr->drawPath(clipPath, stroke, fGpu, false);
}
} else {
SET_RANDOM_COLOR
@@ -1095,28 +1089,6 @@
}
////////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-GrPathFill invert_fill(GrPathFill fill) {
- static const GrPathFill gInvertedFillTable[] = {
- kInverseWinding_GrPathFill, // kWinding_GrPathFill
- kInverseEvenOdd_GrPathFill, // kEvenOdd_GrPathFill
- kWinding_GrPathFill, // kInverseWinding_GrPathFill
- kEvenOdd_GrPathFill, // kInverseEvenOdd_GrPathFill
- kHairLine_GrPathFill, // kHairLine_GrPathFill
- };
- GR_STATIC_ASSERT(0 == kWinding_GrPathFill);
- GR_STATIC_ASSERT(1 == kEvenOdd_GrPathFill);
- GR_STATIC_ASSERT(2 == kInverseWinding_GrPathFill);
- GR_STATIC_ASSERT(3 == kInverseEvenOdd_GrPathFill);
- GR_STATIC_ASSERT(4 == kHairLine_GrPathFill);
- GR_STATIC_ASSERT(5 == kGrPathFillCount);
- return gInvertedFillTable[fill];
-}
-
-}
-
bool GrClipMaskManager::createSoftwareClipMask(const GrClipData& clipDataIn,
GrTexture** result,
GrIRect* devResultBounds) {
@@ -1139,6 +1111,9 @@
SkIntToScalar(-clipDataIn.fOrigin.fY));
helper.init(*devResultBounds, &matrix);
+ SkStroke stroke;
+ stroke.setDoFill(true);
+
bool clearToInside;
SkRegion::Op firstOp = SkRegion::kReplace_Op; // suppress warning
@@ -1183,15 +1158,17 @@
// convert the rect to a path so we can invert the fill
SkPath temp;
temp.addRect(element->getRect());
+ temp.setFillType(SkPath::kInverseEvenOdd_FillType);
- helper.draw(temp, SkRegion::kReplace_Op,
- kInverseEvenOdd_GrPathFill, element->isAA(),
+ helper.draw(temp, stroke, SkRegion::kReplace_Op,
+ element->isAA(),
0x00);
} else {
GrAssert(Element::kPath_Type == element->getType());
- helper.draw(element->getPath(),
+ SkPath clipPath = element->getPath();
+ clipPath.toggleInverseFillType();
+ helper.draw(clipPath, stroke,
SkRegion::kReplace_Op,
- invert_fill(get_path_fill(element->getPath())),
element->isAA(),
0x00);
}
@@ -1205,10 +1182,7 @@
helper.draw(element->getRect(), op, element->isAA(), 0xFF);
} else {
GrAssert(Element::kPath_Type == element->getType());
- helper.draw(element->getPath(),
- op,
- get_path_fill(element->getPath()),
- element->isAA(), 0xFF);
+ helper.draw(element->getPath(), stroke, op, element->isAA(), 0xFF);
}
}
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 1292b51..9c209b3 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -26,6 +26,7 @@
#include "SkTLazy.h"
#include "SkTLS.h"
#include "SkTrace.h"
+#include "SkStroke.h"
SK_DEFINE_INST_COUNT(GrContext)
SK_DEFINE_INST_COUNT(GrDrawState)
@@ -985,9 +986,14 @@
rect.height() != rect.width()) {
SkPath path;
path.addOval(rect);
- GrPathFill fill = (strokeWidth == 0) ?
- kHairLine_GrPathFill : kWinding_GrPathFill;
- this->internalDrawPath(paint, path, fill);
+ path.setFillType(SkPath::kWinding_FillType);
+ SkStroke stroke;
+ if (strokeWidth < 0) {
+ stroke.setDoFill(true);
+ } else {
+ stroke.setWidth(strokeWidth);
+ }
+ this->internalDrawPath(paint, path, stroke);
return;
}
@@ -1057,26 +1063,33 @@
target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4);
}
-void GrContext::drawPath(const GrPaint& paint, const SkPath& path, GrPathFill fill) {
+void GrContext::drawPath(const GrPaint& paint, const SkPath& path, bool doHairLine) {
if (path.isEmpty()) {
- if (GrIsFillInverted(fill)) {
+ if (path.isInverseFillType()) {
this->drawPaint(paint);
}
return;
}
SkRect ovalRect;
- if (!GrIsFillInverted(fill) && path.isOval(&ovalRect)) {
- SkScalar width = (fill == kHairLine_GrPathFill) ? 0 : -SK_Scalar1;
+ if (!path.isInverseFillType() && path.isOval(&ovalRect)) {
+ SkScalar width = doHairLine ? 0 : -SK_Scalar1;
this->drawOval(paint, ovalRect, width);
return;
}
- this->internalDrawPath(paint, path, fill);
+ SkStroke stroke;
+ if (doHairLine) {
+ stroke.setWidth(0);
+ } else {
+ stroke.setDoFill(true);
+ }
+
+ this->internalDrawPath(paint, path, stroke);
}
-void GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path, GrPathFill fill) {
+void GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path, const SkStroke& stroke) {
// Note that below we may sw-rasterize the path into a scratch texture.
// Scratch textures can be recycled after they are returned to the texture
@@ -1099,7 +1112,7 @@
prAA = false;
}
- GrPathRenderer* pr = this->getPathRenderer(path, fill, target, prAA, true);
+ GrPathRenderer* pr = this->getPathRenderer(path, stroke, target, prAA, true);
if (NULL == pr) {
#if GR_DEBUG
GrPrintf("Unable to find path renderer compatible with path.\n");
@@ -1107,7 +1120,7 @@
return;
}
- pr->drawPath(path, fill, target, prAA);
+ pr->drawPath(path, stroke, target, prAA);
}
////////////////////////////////////////////////////////////////////////////////
@@ -1598,7 +1611,7 @@
* can be individually allowed/disallowed via the "allowSW" boolean.
*/
GrPathRenderer* GrContext::getPathRenderer(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target,
bool antiAlias,
bool allowSW) {
@@ -1608,7 +1621,8 @@
(this, GrPathRendererChain::kNone_UsageFlag));
}
- GrPathRenderer* pr = fPathRendererChain->getPathRenderer(path, fill,
+ GrPathRenderer* pr = fPathRendererChain->getPathRenderer(path,
+ stroke,
target,
antiAlias);
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index 521afd3..f80b4d7 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -12,6 +12,7 @@
#include "GrDrawState.h"
#include "GrPathUtils.h"
#include "SkString.h"
+#include "SkStroke.h"
#include "SkTrace.h"
@@ -150,11 +151,11 @@
#define STENCIL_OFF 0 // Always disable stencil (even when needed)
-static inline bool single_pass_path(const SkPath& path, GrPathFill fill) {
+static inline bool single_pass_path(const SkPath& path, const SkStroke& stroke) {
#if STENCIL_OFF
return true;
#else
- if (kEvenOdd_GrPathFill == fill || kWinding_GrPathFill == fill) {
+ if ((0 != stroke.getWidthIfStroked()) && !path.isInverseFillType()) {
return path.isConvex();
}
return false;
@@ -162,19 +163,19 @@
}
bool GrDefaultPathRenderer::requiresStencilPass(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target) const {
- return !single_pass_path(path, fill);
+ return !single_pass_path(path, stroke);
}
-static inline void append_countour_edge_indices(GrPathFill fillType,
+static inline void append_countour_edge_indices(bool hairLine,
uint16_t fanCenterIdx,
uint16_t edgeV0Idx,
uint16_t** indices) {
// when drawing lines we're appending line segments along
// the contour. When applying the other fill rules we're
// drawing triangle fans around fanCenterIdx.
- if (kHairLine_GrPathFill != fillType) {
+ if (!hairLine) {
*((*indices)++) = fanCenterIdx;
}
*((*indices)++) = edgeV0Idx;
@@ -182,7 +183,7 @@
}
bool GrDefaultPathRenderer::createGeom(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
SkScalar srcSpaceTol,
GrDrawTarget* target,
GrPrimitiveType* primType,
@@ -208,8 +209,10 @@
GrVertexLayout layout = 0;
bool indexed = contourCnt > 1;
+ const bool isHairline = 0 == stroke.getWidthIfStroked();
+
int maxIdxs = 0;
- if (kHairLine_GrPathFill == fill) {
+ if (isHairline) {
if (indexed) {
maxIdxs = 2 * maxPts;
*primType = kLines_GrPrimitiveType;
@@ -260,7 +263,7 @@
case kLine_PathCmd:
if (indexed) {
uint16_t prevIdx = (uint16_t)(vert - base) - 1;
- append_countour_edge_indices(fill, subpathIdxStart,
+ append_countour_edge_indices(isHairline, subpathIdxStart,
prevIdx, &idx);
}
*(vert++) = pts[1];
@@ -275,7 +278,7 @@
GrPathUtils::quadraticPointCount(pts, srcSpaceTol));
if (indexed) {
for (uint16_t i = 0; i < numPts; ++i) {
- append_countour_edge_indices(fill, subpathIdxStart,
+ append_countour_edge_indices(isHairline, subpathIdxStart,
firstQPtIdx + i, &idx);
}
}
@@ -290,7 +293,7 @@
GrPathUtils::cubicPointCount(pts, srcSpaceTol));
if (indexed) {
for (uint16_t i = 0; i < numPts; ++i) {
- append_countour_edge_indices(fill, subpathIdxStart,
+ append_countour_edge_indices(isHairline, subpathIdxStart,
firstCPtIdx + i, &idx);
}
}
@@ -316,7 +319,7 @@
}
bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target,
bool stencilOnly) {
@@ -329,7 +332,7 @@
GrPrimitiveType primType;
GrDrawTarget::AutoReleaseGeometry arg;
if (!this->createGeom(path,
- fill,
+ stroke,
tol,
target,
&primType,
@@ -352,7 +355,7 @@
bool reverse = false;
bool lastPassIsBounds;
- if (kHairLine_GrPathFill == fill) {
+ if (0 == stroke.getWidthIfStroked()) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
@@ -362,7 +365,7 @@
lastPassIsBounds = false;
drawFace[0] = GrDrawState::kBoth_DrawFace;
} else {
- if (single_pass_path(path, fill)) {
+ if (single_pass_path(path, stroke)) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
@@ -372,11 +375,11 @@
drawFace[0] = GrDrawState::kBoth_DrawFace;
lastPassIsBounds = false;
} else {
- switch (fill) {
- case kInverseEvenOdd_GrPathFill:
+ switch (path.getFillType()) {
+ case SkPath::kInverseEvenOdd_FillType:
reverse = true;
// fallthrough
- case kEvenOdd_GrPathFill:
+ case SkPath::kEvenOdd_FillType:
passes[0] = &gEOStencilPass;
if (stencilOnly) {
passCount = 1;
@@ -393,10 +396,10 @@
drawFace[0] = drawFace[1] = GrDrawState::kBoth_DrawFace;
break;
- case kInverseWinding_GrPathFill:
+ case SkPath::kInverseWinding_FillType:
reverse = true;
// fallthrough
- case kWinding_GrPathFill:
+ case SkPath::kWinding_FillType:
if (fSeparateStencil) {
if (fStencilWrapOps) {
passes[0] = &gWindStencilSeparateWithWrap;
@@ -487,28 +490,28 @@
}
bool GrDefaultPathRenderer::canDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target,
bool antiAlias) const {
// this class can draw any path with any fill but doesn't do any
// anti-aliasing.
- return !antiAlias;
+ return (stroke.getWidthIfStroked() <= 0) && !antiAlias;
}
bool GrDefaultPathRenderer::onDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target,
bool antiAlias) {
return this->internalDrawPath(path,
- fill,
+ stroke,
target,
false);
}
void GrDefaultPathRenderer::drawPathToStencil(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target) {
- GrAssert(kInverseEvenOdd_GrPathFill != fill);
- GrAssert(kInverseWinding_GrPathFill != fill);
- this->internalDrawPath(path, fill, target, true);
+ GrAssert(SkPath::kInverseEvenOdd_FillType != path.getFillType());
+ GrAssert(SkPath::kInverseWinding_FillType != path.getFillType());
+ this->internalDrawPath(path, stroke, target, true);
}
diff --git a/src/gpu/GrDefaultPathRenderer.h b/src/gpu/GrDefaultPathRenderer.h
index c516552..e98f2d7 100644
--- a/src/gpu/GrDefaultPathRenderer.h
+++ b/src/gpu/GrDefaultPathRenderer.h
@@ -22,32 +22,32 @@
virtual bool requiresStencilPass(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target) const SK_OVERRIDE;
virtual bool canDrawPath(const SkPath& path,
- GrPathFill fill,
- const GrDrawTarget* target,
- bool antiAlias) const SK_OVERRIDE;
+ const SkStroke& stroke,
+ const GrDrawTarget* target,
+ bool antiAlias) const SK_OVERRIDE;
virtual void drawPathToStencil(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target) SK_OVERRIDE;
private:
virtual bool onDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target,
bool antiAlias) SK_OVERRIDE;
bool internalDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target,
bool stencilOnly);
bool createGeom(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
SkScalar srcSpaceTol,
GrDrawTarget* target,
GrPrimitiveType* primType,
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 8fa39d2..6927895 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -15,6 +15,8 @@
#include "GrTexture.h"
#include "GrVertexBuffer.h"
+#include "SkStroke.h"
+
SK_DEFINE_INST_COUNT(GrDrawTarget)
namespace {
@@ -783,13 +785,13 @@
}
}
-void GrDrawTarget::stencilPath(const GrPath* path, GrPathFill fill) {
+void GrDrawTarget::stencilPath(const GrPath* path, const SkStroke& stroke, SkPath::FillType fill) {
// TODO: extract portions of checkDraw that are relevant to path stenciling.
GrAssert(NULL != path);
GrAssert(fCaps.pathStencilingSupport());
- GrAssert(kHairLine_GrPathFill != fill);
- GrAssert(!GrIsFillInverted(fill));
- this->onStencilPath(path, fill);
+ GrAssert(0 != stroke.getWidthIfStroked());
+ GrAssert(!SkPath::IsInverseFill(fill));
+ this->onStencilPath(path, stroke, fill);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 4d652f6..6e0af43 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -17,6 +17,7 @@
#include "GrRefCnt.h"
#include "GrTemplates.h"
+#include "SkPath.h"
#include "SkXfermode.h"
#include "SkTLazy.h"
#include "SkTArray.h"
@@ -25,6 +26,8 @@
class GrPath;
class GrVertexBuffer;
+class SkStroke;
+
class GrDrawTarget : public GrRefCnt {
protected:
/** This helper class allows GrDrawTarget subclasses to set the caps values without having to be
@@ -452,7 +455,7 @@
* winding (not inverse or hairline). It will respect the HW antialias flag
* on the draw state (if possible in the 3D API).
*/
- void stencilPath(const GrPath*, GrPathFill);
+ void stencilPath(const GrPath*, const SkStroke& stroke, SkPath::FillType fill);
/**
* Helper function for drawing rects. This does not use the current index
@@ -981,7 +984,7 @@
virtual void onDrawNonIndexed(GrPrimitiveType type,
int startVertex,
int vertexCount) = 0;
- virtual void onStencilPath(const GrPath*, GrPathFill) = 0;
+ virtual void onStencilPath(const GrPath*, const SkStroke& stroke, SkPath::FillType fill) = 0;
// subclass overrides to be notified when clip is set. Must call
// INHERITED::clipwillBeSet
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 4602298..18013c1 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -410,7 +410,7 @@
this->onGpuDrawNonIndexed(type, sVertex, vertexCount);
}
-void GrGpu::onStencilPath(const GrPath* path, GrPathFill fill) {
+void GrGpu::onStencilPath(const GrPath* path, const SkStroke& stroke, SkPath::FillType fill) {
this->handleDirtyContext();
// TODO: make this more effecient (don't copy and copy back)
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index f9fd779..d3a0012 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -15,6 +15,8 @@
#include "GrRefCnt.h"
#include "GrClipMaskManager.h"
+#include "SkPath.h"
+
class GrContext;
class GrIndexBufferAllocPool;
class GrPath;
@@ -473,10 +475,10 @@
// necessary to stencil the path. These are still subject to filtering by
// the clip mask manager.
virtual void setStencilPathSettings(const GrPath&,
- GrPathFill,
+ SkPath::FillType,
GrStencilSettings* settings) = 0;
// overridden by backend-specific derived class to perform the path stenciling.
- virtual void onGpuStencilPath(const GrPath*, GrPathFill) = 0;
+ virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) = 0;
// overridden by backend-specific derived class to perform flush
virtual void onForceRenderTargetFlush() = 0;
@@ -568,7 +570,8 @@
virtual void onDrawNonIndexed(GrPrimitiveType type,
int startVertex,
int vertexCount) SK_OVERRIDE;
- virtual void onStencilPath(const GrPath* path, GrPathFill fill) SK_OVERRIDE;
+ virtual void onStencilPath(const GrPath* path, const SkStroke& stroke,
+ SkPath::FillType) SK_OVERRIDE;
// readies the pools to provide vertex/index data.
void prepareVertexPool();
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index b2f7963..4147b3b 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -487,7 +487,8 @@
draw->fIndexBuffer = NULL;
}
-void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, GrPathFill fill) {
+void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, const SkStroke& stroke,
+ SkPath::FillType fill) {
if (this->needsNewClip()) {
this->recordClip();
}
@@ -499,6 +500,7 @@
sp->fPath.reset(path);
path->ref();
sp->fFill = fill;
+ sp->fStroke = stroke;
}
void GrInOrderDrawBuffer::clear(const GrIRect* rect,
@@ -610,7 +612,7 @@
}
case kStencilPath_Cmd: {
const StencilPath& sp = fStencilPaths[currStencilPath];
- target->stencilPath(sp.fPath.get(), sp.fFill);
+ target->stencilPath(sp.fPath.get(), sp.fStroke, sp.fFill);
++currStencilPath;
break;
}
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index e80a2b4..20f0c84 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -17,6 +17,7 @@
#include "GrPath.h"
#include "SkClipStack.h"
+#include "SkStroke.h"
#include "SkTemplates.h"
class GrGpu;
@@ -158,7 +159,8 @@
struct StencilPath {
SkAutoTUnref<const GrPath> fPath;
- GrPathFill fFill;
+ SkStroke fStroke;
+ SkPath::FillType fFill;
};
struct Clear {
@@ -179,7 +181,7 @@
virtual void onDrawNonIndexed(GrPrimitiveType primitiveType,
int startVertex,
int vertexCount) SK_OVERRIDE;
- virtual void onStencilPath(const GrPath*, GrPathFill) SK_OVERRIDE;
+ virtual void onStencilPath(const GrPath*, const SkStroke& stroke, SkPath::FillType) SK_OVERRIDE;
virtual bool onReserveVertexSpace(GrVertexLayout layout,
int vertexCount,
void** vertices) SK_OVERRIDE;
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index fc3d672..afcd3c9 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -16,6 +16,7 @@
#include "SkTArray.h"
class SkPath;
+class SkStroke;
struct GrPoint;
@@ -57,10 +58,9 @@
* the target's stencil settings but use those already set on target. The
* target is passed as a param in case the answer depends upon draw state.
*
- * @param target target that the path will be rendered to
- * @param path the path that will be drawn
- * @param fill the fill rule that will be used, will never be an inverse
- * rule.
+ * @param target target that the path will be rendered to
+ * @param path the path that will be drawn
+ * @param stroke the stroke information (width, join, cap).
*
* @return false if this path renderer can generate interior-only fragments
* without changing the stencil settings on the target. If it
@@ -68,7 +68,7 @@
* clips.
*/
virtual bool requiresStencilPass(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target) const {
return false;
}
@@ -80,14 +80,14 @@
* rendering a path.
*
* @param path The path to draw
- * @param fill The fill rule to use
+ * @param stroke The stroke information (width, join, cap)
* @param target The target that the path will be rendered to
* @param antiAlias True if anti-aliasing is required.
*
* @return true if the path can be drawn by this object, false otherwise.
*/
virtual bool canDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target,
bool antiAlias) const = 0;
/**
@@ -96,22 +96,22 @@
* path renderer didn't claim that it needs to use the stencil internally).
*
* @param path the path to draw.
- * @param fill the path filling rule to use.
+ * @param stroke the stroke information (width, join, cap)
* @param target target that the path will be rendered to
* @param antiAlias true if anti-aliasing is required.
*/
virtual bool drawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target,
bool antiAlias) {
- GrAssert(this->canDrawPath(path, fill, target, antiAlias));
- return this->onDrawPath(path, fill, target, antiAlias);
+ GrAssert(this->canDrawPath(path, stroke, target, antiAlias));
+ return this->onDrawPath(path, stroke, target, antiAlias);
}
/**
* Draws the path to the stencil buffer. Assume the writable stencil bits
* are already initialized to zero. Fill will always be either
- * kWinding_GrPathFill or kEvenOdd_GrPathFill.
+ * kWinding_FillType or kEvenOdd_FillType.
*
* Only called if requiresStencilPass returns true for the same combo of
* target, path, and fill. Never called with an inverse fill.
@@ -121,7 +121,7 @@
*
*/
virtual void drawPathToStencil(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target) {
GrCrash("Unexpected call to drawPathToStencil.");
}
@@ -131,12 +131,12 @@
* Draws the path into the draw target.
*
* @param path the path to draw.
- * @param fill the path filling rule to use.
+ * @param stroke the stroke information (width, join, cap)
* @param target target that the path will be rendered to
* @param antiAlias whether antialiasing is enabled or not.
*/
virtual bool onDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target,
bool antiAlias) = 0;
diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp
index 2814f99..8ccafcf 100644
--- a/src/gpu/GrPathRendererChain.cpp
+++ b/src/gpu/GrPathRendererChain.cpp
@@ -34,14 +34,14 @@
}
GrPathRenderer* GrPathRendererChain::getPathRenderer(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target,
bool antiAlias) {
if (!fInit) {
this->init();
}
for (int i = 0; i < fChain.count(); ++i) {
- if (fChain[i]->canDrawPath(path, fill, target, antiAlias)) {
+ if (fChain[i]->canDrawPath(path, stroke, target, antiAlias)) {
return fChain[i];
}
}
diff --git a/src/gpu/GrPathRendererChain.h b/src/gpu/GrPathRendererChain.h
index e5ccabb..dfc696d 100644
--- a/src/gpu/GrPathRendererChain.h
+++ b/src/gpu/GrPathRendererChain.h
@@ -17,6 +17,7 @@
class GrContext;
class SkPath;
+class SkStroke;
class GrPathRenderer;
/**
@@ -42,7 +43,7 @@
GrPathRenderer* addPathRenderer(GrPathRenderer* pr);
GrPathRenderer* getPathRenderer(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target,
bool antiAlias);
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 4aad051..02868ef 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -9,6 +9,8 @@
#include "GrDrawState.h"
#include "GrGpu.h"
+#include "SkStroke.h"
+
// TODO: try to remove this #include
#include "GrContext.h"
@@ -30,23 +32,6 @@
return modeMap[op];
}
-////////////////////////////////////////////////////////////////////////////////
-SkPath::FillType gr_fill_to_sk_fill(GrPathFill fill) {
- switch (fill) {
- case kWinding_GrPathFill:
- return SkPath::kWinding_FillType;
- case kEvenOdd_GrPathFill:
- return SkPath::kEvenOdd_FillType;
- case kInverseWinding_GrPathFill:
- return SkPath::kInverseWinding_FillType;
- case kInverseEvenOdd_GrPathFill:
- return SkPath::kInverseEvenOdd_FillType;
- default:
- GrCrash("Unexpected fill.");
- return SkPath::kWinding_FillType;
- }
-}
-
}
/**
@@ -70,22 +55,22 @@
/**
* Draw a single path element of the clip stack into the accumulation bitmap
*/
-void GrSWMaskHelper::draw(const SkPath& path, SkRegion::Op op,
- GrPathFill fill, bool antiAlias, uint8_t alpha) {
+void GrSWMaskHelper::draw(const SkPath& path, const SkStroke& stroke, SkRegion::Op op,
+ bool antiAlias, uint8_t alpha) {
SkPaint paint;
- SkPath tmpPath;
- const SkPath* pathToDraw = &path;
- if (kHairLine_GrPathFill == fill) {
+ SkScalar width = stroke.getWidthIfStroked();
+ if (0 == width) {
paint.setStyle(SkPaint::kStroke_Style);
paint.setStrokeWidth(SK_Scalar1);
} else {
- paint.setStyle(SkPaint::kFill_Style);
- SkPath::FillType skfill = gr_fill_to_sk_fill(fill);
- if (skfill != pathToDraw->getFillType()) {
- tmpPath = *pathToDraw;
- tmpPath.setFillType(skfill);
- pathToDraw = &tmpPath;
+ if (stroke.getDoFill()) {
+ paint.setStyle(SkPaint::kFill_Style);
+ } else {
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeJoin(stroke.getJoin());
+ paint.setStrokeCap(stroke.getCap());
+ paint.setStrokeWidth(width);
}
}
SkXfermode* mode = SkXfermode::Create(op_to_mode(op));
@@ -94,7 +79,7 @@
paint.setAntiAlias(antiAlias);
paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
- fDraw.drawPath(*pathToDraw, paint);
+ fDraw.drawPath(path, paint);
SkSafeUnref(mode);
}
@@ -174,8 +159,8 @@
*/
GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context,
const SkPath& path,
+ const SkStroke& stroke,
const GrIRect& resultBounds,
- GrPathFill fill,
bool antiAlias,
SkMatrix* matrix) {
GrAutoScratchTexture ast;
@@ -186,7 +171,7 @@
return NULL;
}
- helper.draw(path, SkRegion::kReplace_Op, fill, antiAlias, 0xFF);
+ helper.draw(path, stroke, SkRegion::kReplace_Op, antiAlias, 0xFF);
if (!helper.getTexture(&ast)) {
return NULL;
diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h
index 3c35794..3ceaad3 100644
--- a/src/gpu/GrSWMaskHelper.h
+++ b/src/gpu/GrSWMaskHelper.h
@@ -21,6 +21,7 @@
class GrContext;
class GrTexture;
class SkPath;
+class SkStroke;
class GrDrawTarget;
/**
@@ -54,8 +55,8 @@
bool antiAlias, uint8_t alpha);
// Draw a single path into the accumuation bitmap using the specified op
- void draw(const SkPath& path, SkRegion::Op op,
- GrPathFill fill, bool antiAlias, uint8_t alpha);
+ void draw(const SkPath& path, const SkStroke& stroke, SkRegion::Op op,
+ bool antiAlias, uint8_t alpha);
// Helper function to get a scratch texture suitable for capturing the
// result (i.e., right size & format)
@@ -74,8 +75,8 @@
// to the GPU. The result is returned in "result".
static GrTexture* DrawPathMaskToTexture(GrContext* context,
const SkPath& path,
+ const SkStroke& stroke,
const GrIRect& resultBounds,
- GrPathFill fill,
bool antiAlias,
SkMatrix* matrix);
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index 6d91ef9..a521eef 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -12,7 +12,7 @@
////////////////////////////////////////////////////////////////////////////////
bool GrSoftwarePathRenderer::canDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target,
bool antiAlias) const {
if (!antiAlias || NULL == fContext) {
@@ -107,7 +107,7 @@
////////////////////////////////////////////////////////////////////////////////
// return true on success; false on failure
bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target,
bool antiAlias) {
@@ -122,15 +122,15 @@
GrIRect devPathBounds, devClipBounds;
if (!get_path_and_clip_bounds(target, path, vm,
&devPathBounds, &devClipBounds)) {
- if (GrIsFillInverted(fill)) {
+ if (path.isInverseFillType()) {
draw_around_inv_path(target, devClipBounds, devPathBounds);
}
return true;
}
SkAutoTUnref<GrTexture> texture(
- GrSWMaskHelper::DrawPathMaskToTexture(fContext, path,
- devPathBounds, fill,
+ GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke,
+ devPathBounds,
antiAlias, &vm));
if (NULL == texture) {
return false;
@@ -138,7 +138,7 @@
GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, devPathBounds);
- if (GrIsFillInverted(fill)) {
+ if (path.isInverseFillType()) {
draw_around_inv_path(target, devClipBounds, devPathBounds);
}
diff --git a/src/gpu/GrSoftwarePathRenderer.h b/src/gpu/GrSoftwarePathRenderer.h
index fdcc7bd..7c7382c 100644
--- a/src/gpu/GrSoftwarePathRenderer.h
+++ b/src/gpu/GrSoftwarePathRenderer.h
@@ -25,12 +25,12 @@
}
virtual bool canDrawPath(const SkPath& path,
- GrPathFill fill,
- const GrDrawTarget* target,
- bool antiAlias) const SK_OVERRIDE;
+ const SkStroke& stroke,
+ const GrDrawTarget* target,
+ bool antiAlias) const SK_OVERRIDE;
protected:
virtual bool onDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target,
bool antiAlias) SK_OVERRIDE;
diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp
index 9749f1d..28e18ed 100644
--- a/src/gpu/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp
@@ -11,6 +11,7 @@
#include "GrContext.h"
#include "GrGpu.h"
#include "GrPath.h"
+#include "SkStroke.h"
GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrContext* context) {
GrAssert(NULL != context);
@@ -33,42 +34,42 @@
}
bool GrStencilAndCoverPathRenderer::canDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target,
bool antiAlias) const {
- return kHairLine_GrPathFill != fill &&
+ return stroke.getDoFill() &&
!antiAlias && // doesn't do per-path AA, relies on the target having MSAA
target->getDrawState().getStencil().isDisabled();
}
bool GrStencilAndCoverPathRenderer::requiresStencilPass(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target) const {
return true;
}
void GrStencilAndCoverPathRenderer::drawPathToStencil(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target) {
- GrAssert(kEvenOdd_GrPathFill == fill || kWinding_GrPathFill == fill);
+ GrAssert(!path.isInverseFillType());
SkAutoTUnref<GrPath> p(fGpu->createPath(path));
- target->stencilPath(p, fill);
+ target->stencilPath(p, stroke, path.getFillType());
}
bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target,
bool antiAlias) {
GrAssert(!antiAlias);
- GrAssert(kHairLine_GrPathFill != fill);
+ GrAssert(0 != stroke.getWidthIfStroked());
GrDrawState* drawState = target->drawState();
GrAssert(drawState->getStencil().isDisabled());
SkAutoTUnref<GrPath> p(fGpu->createPath(path));
- GrPathFill nonInvertedFill = GrNonInvertedFill(fill);
- target->stencilPath(p, nonInvertedFill);
+ SkPath::FillType nonInvertedFill = SkPath::NonInverseFill(path.getFillType());
+ target->stencilPath(p, stroke, nonInvertedFill);
// TODO: Use built in cover operation rather than a rect draw. This will require making our
// fragment shaders be able to eat varyings generated by a matrix.
@@ -78,7 +79,7 @@
SkScalar bloat = drawState->getViewMatrix().getMaxStretch() * SK_ScalarHalf;
GrDrawState::AutoDeviceCoordDraw adcd;
- if (nonInvertedFill == fill) {
+ if (nonInvertedFill == path.getFillType()) {
GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
kZero_StencilOp,
kZero_StencilOp,
diff --git a/src/gpu/GrStencilAndCoverPathRenderer.h b/src/gpu/GrStencilAndCoverPathRenderer.h
index e44ddb2..9a8dd57 100644
--- a/src/gpu/GrStencilAndCoverPathRenderer.h
+++ b/src/gpu/GrStencilAndCoverPathRenderer.h
@@ -26,21 +26,21 @@
virtual ~GrStencilAndCoverPathRenderer();
virtual bool canDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target,
bool antiAlias) const SK_OVERRIDE;
virtual bool requiresStencilPass(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
const GrDrawTarget* target) const SK_OVERRIDE;
virtual void drawPathToStencil(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target) SK_OVERRIDE;
protected:
virtual bool onDrawPath(const SkPath& path,
- GrPathFill fill,
+ const SkStroke& stroke,
GrDrawTarget* target,
bool antiAlias) SK_OVERRIDE;
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index bb434b6..fdb5d37 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -179,7 +179,7 @@
SkFixedToScalar(vy - SkIntToFixed(glyph->fBounds.fTop)));
GrPaint tmpPaint(fPaint);
am.setPreConcat(fContext, translate, &tmpPaint);
- fContext->drawPath(tmpPaint, *glyph->fPath, kWinding_GrPathFill);
+ fContext->drawPath(tmpPaint, *glyph->fPath, false);
return;
}
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 13fb99c..5d04995 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -741,22 +741,6 @@
// helpers for applying mask filters
namespace {
-GrPathFill skToGrFillType(SkPath::FillType fillType) {
- switch (fillType) {
- case SkPath::kWinding_FillType:
- return kWinding_GrPathFill;
- case SkPath::kEvenOdd_FillType:
- return kEvenOdd_GrPathFill;
- case SkPath::kInverseWinding_FillType:
- return kInverseWinding_GrPathFill;
- case SkPath::kInverseEvenOdd_FillType:
- return kInverseEvenOdd_GrPathFill;
- default:
- SkDebugf("Unsupported path fill type\n");
- return kHairLine_GrPathFill;
- }
-}
-
// We prefer to blur small rect with small radius via CPU.
#define MIN_GPU_BLUR_SIZE SkIntToScalar(64)
#define MIN_GPU_BLUR_RADIUS SkIntToScalar(32)
@@ -769,9 +753,9 @@
return false;
}
-bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath,
+bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, bool doHairLine,
SkMaskFilter* filter, const SkRegion& clip,
- SkBounder* bounder, GrPaint* grp, GrPathFill pathFillType) {
+ SkBounder* bounder, GrPaint* grp) {
SkMaskFilter::BlurInfo info;
SkMaskFilter::BlurType blurType = filter->asABlur(&info);
if (SkMaskFilter::kNone_BlurType == blurType) {
@@ -854,7 +838,7 @@
SkMatrix translate;
translate.setTranslate(offset.fX, offset.fY);
am.set(context, translate);
- context->drawPath(tempPaint, devPath, pathFillType);
+ context->drawPath(tempPaint, devPath, doHairLine);
// If we're doing a normal blur, we can clobber the pathTexture in the
// gaussianBlur. Otherwise, we need to save it for later compositing.
@@ -980,7 +964,7 @@
CHECK_FOR_NODRAW_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw, false);
- bool doFill = true;
+ bool doHairLine = false;
GrPaint grPaint;
SkAutoCachedTexture textures[GrPaint::kMaxColorStages];
@@ -996,7 +980,7 @@
// if we can, we draw lots faster (raster device does this same test)
SkScalar hairlineCoverage;
if (SkDrawTreatAsHairline(paint, fContext->getMatrix(), &hairlineCoverage)) {
- doFill = false;
+ doHairLine = true;
grPaint.setCoverage(SkScalarRoundToInt(hairlineCoverage * grPaint.getCoverage()));
}
@@ -1022,11 +1006,11 @@
SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
if (paint.getPathEffect() ||
- (doFill && paint.getStyle() != SkPaint::kFill_Style)) {
+ (!doHairLine && paint.getStyle() != SkPaint::kFill_Style)) {
// it is safe to use tmpPath here, even if we already used it for the
// prepathmatrix, since getFillPath can take the same object for its
// input and output safely.
- doFill = paint.getFillPath(*pathPtr, &tmpPath);
+ doHairLine = !paint.getFillPath(*pathPtr, &tmpPath);
pathPtr = &tmpPath;
}
@@ -1036,41 +1020,17 @@
// transform the path into device space
pathPtr->transform(fContext->getMatrix(), devPathPtr);
- GrPathFill pathFillType = doFill ?
- skToGrFillType(devPathPtr->getFillType()) : kHairLine_GrPathFill;
- if (!drawWithGPUMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(),
- *draw.fClip, draw.fBounder, &grPaint, pathFillType)) {
- SkPaint::Style style = doFill ? SkPaint::kFill_Style :
- SkPaint::kStroke_Style;
+ if (!drawWithGPUMaskFilter(fContext, *devPathPtr, doHairLine, paint.getMaskFilter(),
+ *draw.fClip, draw.fBounder, &grPaint)) {
+ SkPaint::Style style = doHairLine ? SkPaint::kStroke_Style :
+ SkPaint::kFill_Style;
drawWithMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(),
*draw.fClip, draw.fBounder, &grPaint, style);
}
return;
}
- GrPathFill fill = kHairLine_GrPathFill;
-
- if (doFill) {
- switch (pathPtr->getFillType()) {
- case SkPath::kWinding_FillType:
- fill = kWinding_GrPathFill;
- break;
- case SkPath::kEvenOdd_FillType:
- fill = kEvenOdd_GrPathFill;
- break;
- case SkPath::kInverseWinding_FillType:
- fill = kInverseWinding_GrPathFill;
- break;
- case SkPath::kInverseEvenOdd_FillType:
- fill = kInverseEvenOdd_GrPathFill;
- break;
- default:
- SkDebugf("Unsupported path fill type\n");
- return;
- }
- }
-
- fContext->drawPath(grPaint, *pathPtr, fill);
+ fContext->drawPath(grPaint, *pathPtr, doHairLine);
}
namespace {
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index eb60539..f01fd3f 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1681,13 +1681,13 @@
void GrGpuGL::setStencilPathSettings(const GrPath&,
- GrPathFill fill,
+ SkPath::FillType fill,
GrStencilSettings* settings) {
switch (fill) {
- case kEvenOdd_GrPathFill:
+ case SkPath::kEvenOdd_FillType:
*settings = even_odd_nv_path_stencil_settings();
return;
- case kWinding_GrPathFill:
+ case SkPath::kWinding_FillType:
*settings = winding_nv_path_stencil_settings();
return;
default:
@@ -1695,7 +1695,7 @@
}
}
-void GrGpuGL::onGpuStencilPath(const GrPath* path, GrPathFill fill) {
+void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) {
GrAssert(fCaps.pathStencilingSupport());
GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
@@ -1711,14 +1711,14 @@
GrAssert(!fStencilSettings.isTwoSided());
GrGLenum fillMode;
switch (fill) {
- case kWinding_GrPathFill:
+ case SkPath::kWinding_FillType:
fillMode = GR_GL_COUNT_UP;
GrAssert(kIncClamp_StencilOp ==
fStencilSettings.passOp(GrStencilSettings::kFront_Face));
GrAssert(kIncClamp_StencilOp ==
fStencilSettings.failOp(GrStencilSettings::kFront_Face));
break;
- case kEvenOdd_GrPathFill:
+ case SkPath::kEvenOdd_FillType:
fillMode = GR_GL_INVERT;
GrAssert(kInvert_StencilOp ==
fStencilSettings.passOp(GrStencilSettings::kFront_Face));
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 7f74d8e..33834cf 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -104,10 +104,10 @@
uint32_t numVertices) SK_OVERRIDE;
virtual void setStencilPathSettings(const GrPath&,
- GrPathFill,
+ SkPath::FillType,
GrStencilSettings* settings)
SK_OVERRIDE;
- virtual void onGpuStencilPath(const GrPath*, GrPathFill) SK_OVERRIDE;
+ virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
virtual void clearStencil() SK_OVERRIDE;
virtual void clearStencilClip(const GrIRect& rect,