| Index: src/gpu/GrStencilAndCoverPathRenderer.cpp
|
| diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp
|
| index 5f55c1a21412eaa43c523f96afbe52049013dbb3..6ed4b9e61c3e3dc40a8a7d7b4afaaf1a992816f3 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()));
|
| }
|
|
|
| bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
|
| @@ -94,7 +110,27 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
|
| 0x0000,
|
| 0xffff);
|
|
|
| - *drawState->stencil() = kInvertedStencilPass;
|
| + drawState->setStencil(kInvertedStencilPass);
|
| +
|
| + // fake inverse with a stencil and cover
|
| + target->stencilPath(p, convert_skpath_filltype(path.getFillType()));
|
| +
|
| + 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 +140,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;
|
| }
|
|
|