Chromium Code Reviews| Index: src/gpu/GrStencilAndCoverPathRenderer.cpp |
| diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp |
| index 5f55c1a21412eaa43c523f96afbe52049013dbb3..ca425ef1dfa0942fd2e97741bd4893e7466ab6d4 100644 |
| --- a/src/gpu/GrStencilAndCoverPathRenderer.cpp |
| +++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp |
| @@ -14,6 +14,22 @@ |
| #include "GrPath.h" |
| #include "SkStrokeRec.h" |
| +/* |
| + * For now paths only natively support winding and even odd fill types |
| + */ |
| +static GrPathRendering::FillType convert_skpath_filltype(SkPath::FillType fill) { |
| + switch (fill) { |
| + default: |
| + SkFAIL("Incomplete Switch\n"); |
| + case SkPath::kWinding_FillType: |
| + case SkPath::kInverseWinding_FillType: |
| + return GrPathRendering::kWinding_FillType; |
| + case SkPath::kEvenOdd_FillType: |
| + case SkPath::kInverseEvenOdd_FillType: |
| + return GrPathRendering::kEvenOdd_FillType; |
| + } |
| +} |
| + |
| GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrContext* context) { |
| SkASSERT(context); |
| SkASSERT(context->getGpu()); |
| @@ -44,10 +60,10 @@ bool GrStencilAndCoverPathRenderer::canDrawPath(const SkPath& path, |
| target->getDrawState().getStencil().isDisabled(); |
| } |
| -GrPathRenderer::StencilSupport GrStencilAndCoverPathRenderer::onGetStencilSupport( |
| - const SkPath&, |
| - const SkStrokeRec& , |
| - const GrDrawTarget*) const { |
| +GrPathRenderer::StencilSupport |
| +GrStencilAndCoverPathRenderer::onGetStencilSupport(const SkPath&, |
| + const SkStrokeRec& , |
| + const GrDrawTarget*) const { |
| return GrPathRenderer::kStencilOnly_StencilSupport; |
| } |
| @@ -67,7 +83,7 @@ void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path, |
| GrDrawTarget* target) { |
| SkASSERT(!path.isInverseFillType()); |
| SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke)); |
| - target->stencilPath(p, path.getFillType()); |
| + target->stencilPath(p, convert_skpath_filltype(path.getFillType())); |
|
bsalomon
2014/10/30 20:11:01
This function is used by GrCMM to draw paths into
joshualitt
2014/10/30 21:24:33
Would the SkASSERT(!path.isInverseFillType()) catc
|
| } |
| bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, |
| @@ -94,7 +110,30 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, |
| 0x0000, |
| 0xffff); |
| - *drawState->stencil() = kInvertedStencilPass; |
| + drawState->setStencil(kInvertedStencilPass); |
|
bsalomon
2014/10/30 20:11:01
prolly want to remove this line
joshualitt
2014/10/30 21:24:33
Acknowledged.
|
| + |
| + // fake inverse with a stencil and cover |
| + target->stencilPath(p, convert_skpath_filltype(path.getFillType())); |
| + |
| + // now draw bounding rectangle |
| + drawState->setStencil(kInvertedStencilPass); |
| + |
| + GrDrawState::AutoViewMatrixRestore avmr; |
| + SkRect bounds = SkRect::MakeLTRB(0, 0, |
| + SkIntToScalar(drawState->getRenderTarget()->width()), |
| + SkIntToScalar(drawState->getRenderTarget()->height())); |
| + SkMatrix vmi; |
| + // mapRect through persp matrix may not be correct |
| + if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) { |
| + vmi.mapRect(&bounds); |
| + // theoretically could set bloat = 0, instead leave it because of matrix inversion |
| + // precision. |
| + SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf; |
| + bounds.outset(bloat, bloat); |
| + } else { |
| + avmr.setIdentity(drawState); |
| + } |
| + target->drawSimpleRect(bounds); |
| } else { |
| GR_STATIC_CONST_SAME_STENCIL(kStencilPass, |
| kZero_StencilOp, |
| @@ -104,11 +143,10 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, |
| 0x0000, |
| 0xffff); |
| - *drawState->stencil() = kStencilPass; |
| + drawState->setStencil(kStencilPass); |
| + target->drawPath(p, convert_skpath_filltype(path.getFillType())); |
| } |
| - target->drawPath(p, path.getFillType()); |
| - |
| target->drawState()->stencil()->setDisabled(); |
| return true; |
| } |