From 12b4e27ae1a29460e91a59f38122483e1faec697 Mon Sep 17 00:00:00 2001 From: "sugoi@google.com" Date: Thu, 6 Dec 2012 20:13:11 +0000 Subject: 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 --- src/core/SkPath.cpp | 2 +- src/core/SkStroke.h | 1 + src/gpu/GrAAConvexPathRenderer.cpp | 15 ++-- src/gpu/GrAAConvexPathRenderer.h | 4 +- src/gpu/GrAAHairLinePathRenderer.cpp | 7 +- src/gpu/GrAAHairLinePathRenderer.h | 8 +-- src/gpu/GrClipMaskManager.cpp | 112 ++++++++++++------------------ src/gpu/GrContext.cpp | 40 +++++++---- src/gpu/GrDefaultPathRenderer.cpp | 59 ++++++++-------- src/gpu/GrDefaultPathRenderer.h | 16 ++--- src/gpu/GrDrawTarget.cpp | 10 +-- src/gpu/GrDrawTarget.h | 7 +- src/gpu/GrGpu.cpp | 2 +- src/gpu/GrGpu.h | 9 ++- src/gpu/GrInOrderDrawBuffer.cpp | 6 +- src/gpu/GrInOrderDrawBuffer.h | 6 +- src/gpu/GrPathRenderer.h | 30 ++++---- src/gpu/GrPathRendererChain.cpp | 4 +- src/gpu/GrPathRendererChain.h | 3 +- src/gpu/GrSWMaskHelper.cpp | 47 +++++-------- src/gpu/GrSWMaskHelper.h | 7 +- src/gpu/GrSoftwarePathRenderer.cpp | 12 ++-- src/gpu/GrSoftwarePathRenderer.h | 8 +-- src/gpu/GrStencilAndCoverPathRenderer.cpp | 23 +++--- src/gpu/GrStencilAndCoverPathRenderer.h | 8 +-- src/gpu/GrTextContext.cpp | 2 +- src/gpu/SkGpuDevice.cpp | 64 ++++------------- src/gpu/gl/GrGpuGL.cpp | 12 ++-- src/gpu/gl/GrGpuGL.h | 4 +- 29 files changed, 238 insertions(+), 290 deletions(-) (limited to 'src') diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp index 80ca3011e3..fe9551492d 100644 --- a/src/core/SkPath.cpp +++ b/src/core/SkPath.cpp @@ -576,7 +576,7 @@ bool SkPath::isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts *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 48805165cb..33a7ecba5c 100644 --- a/src/core/SkStroke.h +++ b/src/core/SkStroke.h @@ -32,6 +32,7 @@ public: 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 ebfcd7bdc3..f8ded78d46 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 @@ void create_vertices(const SegmentArray& segments, } 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 7a2fd38b06..a64596c8dd 100644 --- a/src/gpu/GrAAConvexPathRenderer.h +++ b/src/gpu/GrAAConvexPathRenderer.h @@ -14,13 +14,13 @@ public: 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 cd3f774803..6424ad5115 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::createGeom( } 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::canDrawPath(const SkPath& path, } 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 9129a89674..653fd01873 100644 --- a/src/gpu/GrAAHairLinePathRenderer.h +++ b/src/gpu/GrAAHairLinePathRenderer.h @@ -18,13 +18,13 @@ public: 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 ff78bf9d8c..5dfc6faa35 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 @@ void setup_drawstate_aaclip(GrGpu* gpu, 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 @@ bool GrClipMaskManager::useSWOnlyPath(const SkClipStack& clipIn) { 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 @@ bool GrClipMaskManager::useSWOnlyPath(const SkClipStack& clipIn) { 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 @@ void setup_boolean_blendcoeffs(GrDrawState* drawState, SkRegion::Op op) { 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 texture( GrSWMaskHelper::DrawPathMaskToTexture(context, path, - resultBounds, fill, + stroke, + resultBounds, doAA, NULL)); if (NULL == texture) { return false; @@ -424,7 +414,7 @@ bool draw_path_in_software(GrContext* context, GrSWMaskHelper::DrawToTargetWithPathMask(texture, gpu, rect); - GrAssert(!GrIsFillInverted(fill)); + GrAssert(!path.isInverseFillType()); return true; } @@ -433,16 +423,17 @@ bool draw_path_in_software(GrContext* context, 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 @@ bool GrClipMaskManager::drawClipShape(GrTexture* target, 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 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn, // 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 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn, // 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 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn, } 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 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn, } } 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 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn, 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 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn, } 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 @@ void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, } //////////////////////////////////////////////////////////////////////////////// - -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 @@ bool GrClipMaskManager::createSoftwareClipMask(const GrClipData& clipDataIn, 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 @@ bool GrClipMaskManager::createSoftwareClipMask(const GrClipData& clipDataIn, // 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 @@ bool GrClipMaskManager::createSoftwareClipMask(const GrClipData& clipDataIn, 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 1292b51afc..9c209b3a62 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 @@ void GrContext::drawOval(const GrPaint& paint, 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 @@ void GrContext::drawOval(const GrPaint& paint, 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 @@ void GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path, GrPat 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 @@ void GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path, GrPat return; } - pr->drawPath(path, fill, target, prAA); + pr->drawPath(path, stroke, target, prAA); } //////////////////////////////////////////////////////////////////////////////// @@ -1598,7 +1611,7 @@ GrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint, BufferedDraw buffer * 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 @@ GrPathRenderer* GrContext::getPathRenderer(const SkPath& path, (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 521afd3744..f80b4d793f 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 @@ GR_STATIC_CONST_SAME_STENCIL(gDirectToStencil, #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 @@ static inline bool single_pass_path(const SkPath& path, GrPathFill fill) { } 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 @@ static inline void append_countour_edge_indices(GrPathFill fillType, } bool GrDefaultPathRenderer::createGeom(const SkPath& path, - GrPathFill fill, + const SkStroke& stroke, SkScalar srcSpaceTol, GrDrawTarget* target, GrPrimitiveType* primType, @@ -208,8 +209,10 @@ bool GrDefaultPathRenderer::createGeom(const SkPath& path, 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 @@ bool GrDefaultPathRenderer::createGeom(const SkPath& path, 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 @@ bool GrDefaultPathRenderer::createGeom(const SkPath& path, 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 @@ bool GrDefaultPathRenderer::createGeom(const SkPath& path, 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 @@ FINISHED: } bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path, - GrPathFill fill, + const SkStroke& stroke, GrDrawTarget* target, bool stencilOnly) { @@ -329,7 +332,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path, GrPrimitiveType primType; GrDrawTarget::AutoReleaseGeometry arg; if (!this->createGeom(path, - fill, + stroke, tol, target, &primType, @@ -352,7 +355,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path, bool reverse = false; bool lastPassIsBounds; - if (kHairLine_GrPathFill == fill) { + if (0 == stroke.getWidthIfStroked()) { passCount = 1; if (stencilOnly) { passes[0] = &gDirectToStencil; @@ -362,7 +365,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path, 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 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path, 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 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path, 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::internalDrawPath(const SkPath& path, } 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 c516552a47..e98f2d77fc 100644 --- a/src/gpu/GrDefaultPathRenderer.h +++ b/src/gpu/GrDefaultPathRenderer.h @@ -22,32 +22,32 @@ public: 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 8fa39d2d43..692789537c 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::drawNonIndexed(GrPrimitiveType type, } } -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 4d652f6016..6e0af4330c 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 GrClipData; 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 @@ public: * 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 @@ protected: 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 46022989f9..18013c1019 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -410,7 +410,7 @@ void GrGpu::onDrawNonIndexed(GrPrimitiveType type, 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 f9fd779ca7..d3a0012928 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 @@ protected: // 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 @@ private: 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 b2f79636a7..4147b3b246 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -487,7 +487,8 @@ void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType, 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 @@ void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, GrPathFill fill) { sp->fPath.reset(path); path->ref(); sp->fFill = fill; + sp->fStroke = stroke; } void GrInOrderDrawBuffer::clear(const GrIRect* rect, @@ -610,7 +612,7 @@ bool GrInOrderDrawBuffer::playback(GrDrawTarget* target) { } 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 e80a2b498e..20f0c84583 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 @@ private: struct StencilPath { SkAutoTUnref fPath; - GrPathFill fFill; + SkStroke fStroke; + SkPath::FillType fFill; }; struct Clear { @@ -179,7 +181,7 @@ private: 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 fc3d67289a..afcd3c9c22 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 @@ public: * 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 @@ public: * clips. */ virtual bool requiresStencilPass(const SkPath& path, - GrPathFill fill, + const SkStroke& stroke, const GrDrawTarget* target) const { return false; } @@ -80,14 +80,14 @@ public: * 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 @@ public: * 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 @@ public: * */ virtual void drawPathToStencil(const SkPath& path, - GrPathFill fill, + const SkStroke& stroke, GrDrawTarget* target) { GrCrash("Unexpected call to drawPathToStencil."); } @@ -131,12 +131,12 @@ protected: * 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 2814f999be..8ccafcfe37 100644 --- a/src/gpu/GrPathRendererChain.cpp +++ b/src/gpu/GrPathRendererChain.cpp @@ -34,14 +34,14 @@ GrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) { } 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 e5ccabb95d..dfc696deb5 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 @@ public: 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 4aad05184e..02868ef9b7 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 @@ SkXfermode::Mode op_to_mode(SkRegion::Op op) { 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 @@ void GrSWMaskHelper::draw(const GrRect& rect, SkRegion::Op op, /** * 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 @@ void GrSWMaskHelper::draw(const SkPath& path, SkRegion::Op op, paint.setAntiAlias(antiAlias); paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha)); - fDraw.drawPath(*pathToDraw, paint); + fDraw.drawPath(path, paint); SkSafeUnref(mode); } @@ -174,8 +159,8 @@ void GrSWMaskHelper::toTexture(GrTexture *texture, uint8_t alpha) { */ 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 @@ GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context, 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 3c35794236..3ceaad36c0 100644 --- a/src/gpu/GrSWMaskHelper.h +++ b/src/gpu/GrSWMaskHelper.h @@ -21,6 +21,7 @@ class GrAutoScratchTexture; class GrContext; class GrTexture; class SkPath; +class SkStroke; class GrDrawTarget; /** @@ -54,8 +55,8 @@ public: 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 @@ public: // 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 6d91ef90d1..a521eefcac 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 @@ void draw_around_inv_path(GrDrawTarget* target, //////////////////////////////////////////////////////////////////////////////// // 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 @@ bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, 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 texture( - GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, - devPathBounds, fill, + GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke, + devPathBounds, antiAlias, &vm)); if (NULL == texture) { return false; @@ -138,7 +138,7 @@ bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, 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 fdcc7bd46a..7c7382cbd6 100644 --- a/src/gpu/GrSoftwarePathRenderer.h +++ b/src/gpu/GrSoftwarePathRenderer.h @@ -25,12 +25,12 @@ public: } 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 9749f1dc60..28e18edf8d 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 @@ GrStencilAndCoverPathRenderer::~GrStencilAndCoverPathRenderer() { } 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 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 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 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, 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 e44ddb26a7..9a8dd57b20 100644 --- a/src/gpu/GrStencilAndCoverPathRenderer.h +++ b/src/gpu/GrStencilAndCoverPathRenderer.h @@ -26,21 +26,21 @@ public: 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 bb434b644a..fdb5d37328 100644 --- a/src/gpu/GrTextContext.cpp +++ b/src/gpu/GrTextContext.cpp @@ -179,7 +179,7 @@ void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed, 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 13fb99c905..5d04995d07 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -741,22 +741,6 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, // 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 @@ inline bool shouldDrawBlurWithCPU(const SkRect& rect, SkScalar radius) { 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 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, 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 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, 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 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, // 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 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, 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 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, // 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 eb60539fbf..f01fd3f082 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -1681,13 +1681,13 @@ const GrStencilSettings& even_odd_nv_path_stencil_settings() { 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::setStencilPathSettings(const GrPath&, } } -void GrGpuGL::onGpuStencilPath(const GrPath* path, GrPathFill fill) { +void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) { GrAssert(fCaps.pathStencilingSupport()); GrGLuint id = static_cast(path)->pathID(); @@ -1711,14 +1711,14 @@ void GrGpuGL::onGpuStencilPath(const GrPath* path, GrPathFill fill) { 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 7f74d8e65c..33834cf709 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -104,10 +104,10 @@ protected: 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, -- cgit v1.2.3