gfx/skia/trunk/src/gpu/GrStencilAndCoverPathRenderer.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/gpu/GrStencilAndCoverPathRenderer.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,103 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2012 Google Inc.
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +
    1.13 +#include "GrStencilAndCoverPathRenderer.h"
    1.14 +#include "GrContext.h"
    1.15 +#include "GrDrawTargetCaps.h"
    1.16 +#include "GrGpu.h"
    1.17 +#include "GrPath.h"
    1.18 +#include "SkStrokeRec.h"
    1.19 +
    1.20 +GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrContext* context) {
    1.21 +    SkASSERT(NULL != context);
    1.22 +    SkASSERT(NULL != context->getGpu());
    1.23 +    if (context->getGpu()->caps()->pathRenderingSupport()) {
    1.24 +        return SkNEW_ARGS(GrStencilAndCoverPathRenderer, (context->getGpu()));
    1.25 +    } else {
    1.26 +        return NULL;
    1.27 +    }
    1.28 +}
    1.29 +
    1.30 +GrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrGpu* gpu) {
    1.31 +    SkASSERT(gpu->caps()->pathRenderingSupport());
    1.32 +    fGpu = gpu;
    1.33 +    gpu->ref();
    1.34 +}
    1.35 +
    1.36 +GrStencilAndCoverPathRenderer::~GrStencilAndCoverPathRenderer() {
    1.37 +    fGpu->unref();
    1.38 +}
    1.39 +
    1.40 +bool GrStencilAndCoverPathRenderer::canDrawPath(const SkPath& path,
    1.41 +                                                const SkStrokeRec& stroke,
    1.42 +                                                const GrDrawTarget* target,
    1.43 +                                                bool antiAlias) const {
    1.44 +    return !stroke.isHairlineStyle() &&
    1.45 +           !antiAlias && // doesn't do per-path AA, relies on the target having MSAA
    1.46 +           NULL != target->getDrawState().getRenderTarget()->getStencilBuffer() &&
    1.47 +           target->getDrawState().getStencil().isDisabled();
    1.48 +}
    1.49 +
    1.50 +GrPathRenderer::StencilSupport GrStencilAndCoverPathRenderer::onGetStencilSupport(
    1.51 +                                                        const SkPath&,
    1.52 +                                                        const SkStrokeRec& ,
    1.53 +                                                        const GrDrawTarget*) const {
    1.54 +    return GrPathRenderer::kStencilOnly_StencilSupport;
    1.55 +}
    1.56 +
    1.57 +void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path,
    1.58 +                                                  const SkStrokeRec& stroke,
    1.59 +                                                  GrDrawTarget* target) {
    1.60 +    SkASSERT(!path.isInverseFillType());
    1.61 +    SkAutoTUnref<GrPath> p(fGpu->getContext()->createPath(path, stroke));
    1.62 +    target->stencilPath(p, path.getFillType());
    1.63 +}
    1.64 +
    1.65 +bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
    1.66 +                                               const SkStrokeRec& stroke,
    1.67 +                                               GrDrawTarget* target,
    1.68 +                                               bool antiAlias) {
    1.69 +    SkASSERT(!antiAlias);
    1.70 +    SkASSERT(!stroke.isHairlineStyle());
    1.71 +
    1.72 +    GrDrawState* drawState = target->drawState();
    1.73 +    SkASSERT(drawState->getStencil().isDisabled());
    1.74 +
    1.75 +    SkAutoTUnref<GrPath> p(fGpu->getContext()->createPath(path, stroke));
    1.76 +
    1.77 +    if (path.isInverseFillType()) {
    1.78 +        GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass,
    1.79 +            kZero_StencilOp,
    1.80 +            kZero_StencilOp,
    1.81 +            // We know our rect will hit pixels outside the clip and the user bits will be 0
    1.82 +            // outside the clip. So we can't just fill where the user bits are 0. We also need to
    1.83 +            // check that the clip bit is set.
    1.84 +            kEqualIfInClip_StencilFunc,
    1.85 +            0xffff,
    1.86 +            0x0000,
    1.87 +            0xffff);
    1.88 +
    1.89 +        *drawState->stencil() = kInvertedStencilPass;
    1.90 +    } else {
    1.91 +        GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
    1.92 +            kZero_StencilOp,
    1.93 +            kZero_StencilOp,
    1.94 +            kNotEqual_StencilFunc,
    1.95 +            0xffff,
    1.96 +            0x0000,
    1.97 +            0xffff);
    1.98 +
    1.99 +        *drawState->stencil() = kStencilPass;
   1.100 +    }
   1.101 +
   1.102 +    target->drawPath(p, path.getFillType());
   1.103 +
   1.104 +    target->drawState()->stencil()->setDisabled();
   1.105 +    return true;
   1.106 +}

mercurial