1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com */
7dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com
8dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com#ifndef GrPathRenderer_DEFINED
9dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com#define GrPathRenderer_DEFINED
10dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com
115fa7f30331585f78cf0f81ac185abbff1fee1152robertphillips#include "GrCaps.h"
121105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman#include "GrRenderTargetContext.h"
13976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips#include "GrPaint.h"
14976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips#include "GrResourceProvider.h"
158acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon#include "GrShape.h"
16dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com
17e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org#include "SkDrawProcs.h"
1849313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com#include "SkTArray.h"
1949313f6b4391d0f74ab1964c295634e8830680f6bsalomon@google.com
2007f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.comclass SkPath;
21976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillipsclass GrFixedClip;
22dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.comstruct GrPoint;
23dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com
24dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com/**
25f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips *  Base class for drawing paths into a GrOpList.
26bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com *
278dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel *  Derived classes can use stages GrPaint::kTotalStages through GrPipelineBuilder::kNumStages-1.
288dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel *  The stages before GrPaint::kTotalStages are reserved for setting up the draw (i.e., textures and
2945a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com *  filter masks).
30dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com */
31a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.orgclass SK_API GrPathRenderer : public SkRefCnt {
32dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.compublic:
33c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com    GrPathRenderer();
34dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com
35dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com    /**
3645a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     * A caller may wish to use a path renderer to draw a path into the stencil buffer. However,
3745a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     * the path renderer itself may require use of the stencil buffer. Also a path renderer may
38b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * use a GrProcessor coverage stage that sets coverage to zero to eliminate pixels that are
39b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * covered by bounding geometry but outside the path. These exterior pixels would still be
40b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * rendered into the stencil.
4145a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     *
4245a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     * A GrPathRenderer can provide three levels of support for stenciling paths:
4382125e9aa22b17e540edd6963781e56031c9b221Brian Salomon     * 1) kNoRestriction: This is the most general. The caller sets up the GrPipelineBuilder on the
4482125e9aa22b17e540edd6963781e56031c9b221Brian Salomon     *                    target and calls drawPath(). The path is rendered exactly as the draw
4582125e9aa22b17e540edd6963781e56031c9b221Brian Salomon     *                    state indicates including support for simultaneous color and stenciling
4682125e9aa22b17e540edd6963781e56031c9b221Brian Salomon     *                    with arbitrary stenciling rules. Pixels partially covered by AA paths are
4745a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     *                    affected by the stencil settings.
4845a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules nor shade and stencil
4945a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     *                  simultaneously. The path renderer does support the stencilPath() function
5045a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     *                  which performs no color writes and writes a non-zero stencil value to pixels
5145a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     *                  covered by the path.
5245a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     * 3) kNoSupport: This path renderer cannot be used to stencil the path.
5345a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     */
54687378229aecefc0ab7e639181593774ec8a4290robertphillips    enum StencilSupport {
55687378229aecefc0ab7e639181593774ec8a4290robertphillips        kNoSupport_StencilSupport,
56687378229aecefc0ab7e639181593774ec8a4290robertphillips        kStencilOnly_StencilSupport,
57687378229aecefc0ab7e639181593774ec8a4290robertphillips        kNoRestriction_StencilSupport,
58687378229aecefc0ab7e639181593774ec8a4290robertphillips    };
5945a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com
6045a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com    /**
61e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com     * This function is to get the stencil support for a particular path. The path's fill must
62d6f25bf0ef353da39859fb4173d2cf60d52277e4bsalomon     * not be an inverse type. The path will always be filled and not stroked.
63dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com     *
648acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon     * @param shape   the shape that will be drawn. Must be simple fill styled and non-inverse
658acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon     *                filled.
66dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com     */
678acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    StencilSupport getStencilSupport(const GrShape& shape) const {
688acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon        SkDEBUGCODE(SkPath path;)
698acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon        SkDEBUGCODE(shape.asPath(&path);)
708acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon        SkASSERT(shape.style().isSimpleFill());
71e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com        SkASSERT(!path.isInverseFillType());
728acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon        return this->onGetStencilSupport(shape);
73c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com    }
74ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com
750aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    /** Args to canDrawPath()
760aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     *
77e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips     * fShaderCaps       The shader caps
780aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     * fPipelineBuilder  The pipelineBuilder
790aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     * fViewMatrix       The viewMatrix
808acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon     * fShape            The shape to draw
810e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon     * fAntiAlias        The type of anti aliasing required.
820aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     */
830aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    struct CanDrawPathArgs {
84e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips        const GrShaderCaps*         fShaderCaps;
850aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon        const SkMatrix*             fViewMatrix;
868acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon        const GrShape*              fShape;
870e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon        GrAAType                    fAAType;
88e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips
89687378229aecefc0ab7e639181593774ec8a4290robertphillips        // These next two are only used by GrStencilAndCoverPathRenderer
9093a379bd4d6b30d86c270b879cf172d80172a72bcdalton        bool                        fHasUserStencilSettings;
91687378229aecefc0ab7e639181593774ec8a4290robertphillips
928acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon#ifdef SK_DEBUG
93e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips        void validate() const {
94e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips            SkASSERT(fShaderCaps);
95e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips            SkASSERT(fViewMatrix);
968acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon            SkASSERT(fShape);
97e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips        }
988acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon#endif
990aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    };
1000aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon
101208236d2b6163b977cc9bc299f8df60158ba8226bsalomon@google.com    /**
102e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com     * Returns true if this path renderer is able to render the path. Returning false allows the
103e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com     * caller to fallback to another path renderer This function is called when searching for a path
104e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com     * renderer capable of rendering a path.
105208236d2b6163b977cc9bc299f8df60158ba8226bsalomon@google.com     *
106208236d2b6163b977cc9bc299f8df60158ba8226bsalomon@google.com     * @return  true if the path can be drawn by this object, false otherwise.
107208236d2b6163b977cc9bc299f8df60158ba8226bsalomon@google.com     */
1080aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    bool canDrawPath(const CanDrawPathArgs& args) const {
109e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips        SkDEBUGCODE(args.validate();)
1100aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon        return this->onCanDrawPath(args);
1110aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    }
1120aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon
113ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com    /**
1140aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     * Args to drawPath()
115ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com     *
1160aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     * fTarget                The target that the path will be rendered to
1170aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     * fResourceProvider      The resource provider for creating gpu resources to render the path
1180aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     * fPipelineBuilder       The pipelineBuilder
119862cff30eaa16206d76d7de7594c9167375ca87ecdalton     * fClip                  The clip
120512e437e1e07159a258dd3c5b907576bd1aefc1ejvanverth     * fColor                 Color to render with
1210aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     * fViewMatrix            The viewMatrix
1228acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon     * fShape                 The shape to draw
1230e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon     * fAAtype                true if anti-aliasing is required.
1240e3c55431b463b5575983c0c875909e08a3562bfbrianosman     * fGammaCorrect          true if gamma-correct rendering is to be used.
125ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com     */
1260aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    struct DrawPathArgs {
127256c37bc9ea2a0420b8ac1084f6d645aaeb919f0Robert Phillips        GrContext*                   fContext;
12882f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        GrPaint&&                    fPaint;
12982f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        const GrUserStencilSettings* fUserStencilSettings;
13082f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        GrRenderTargetContext*       fRenderTargetContext;
13182f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        const GrClip*                fClip;
13282f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        const SkMatrix*              fViewMatrix;
13382f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        const GrShape*               fShape;
13482f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        GrAAType                     fAAType;
13582f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        bool                         fGammaCorrect;
1368acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon#ifdef SK_DEBUG
137e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips        void validate() const {
138256c37bc9ea2a0420b8ac1084f6d645aaeb919f0Robert Phillips            SkASSERT(fContext);
139976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips            SkASSERT(fUserStencilSettings);
1401105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman            SkASSERT(fRenderTargetContext);
141862cff30eaa16206d76d7de7594c9167375ca87ecdalton            SkASSERT(fClip);
142e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips            SkASSERT(fViewMatrix);
1438acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon            SkASSERT(fShape);
144e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips        }
1458acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon#endif
1460aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    };
1470aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon
1480aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    /**
1490aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     * Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then
1500aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     * the subclass must respect the stencil settings of the GrPipelineBuilder.
1510aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     */
1520aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    bool drawPath(const DrawPathArgs& args) {
153e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips        SkDEBUGCODE(args.validate();)
1540aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon#ifdef SK_DEBUG
1550aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon        CanDrawPathArgs canArgs;
156256c37bc9ea2a0420b8ac1084f6d645aaeb919f0Robert Phillips        canArgs.fShaderCaps = args.fContext->caps()->shaderCaps();
1570aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon        canArgs.fViewMatrix = args.fViewMatrix;
1588acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon        canArgs.fShape = args.fShape;
1590e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon        canArgs.fAAType = args.fAAType;
160687378229aecefc0ab7e639181593774ec8a4290robertphillips
161976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips        canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused();
1620e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon        SkASSERT(!(canArgs.fAAType == GrAAType::kMSAA &&
1630e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon                   !args.fRenderTargetContext->isUnifiedMultisampled()));
1640e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon        SkASSERT(!(canArgs.fAAType == GrAAType::kMixedSamples &&
1650e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon                   !args.fRenderTargetContext->isStencilBufferMultisampled()));
1660aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon        SkASSERT(this->canDrawPath(canArgs));
167976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips        if (!args.fUserStencilSettings->isUnused()) {
1688acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon            SkPath path;
1698acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon            args.fShape->asPath(&path);
1708acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon            SkASSERT(args.fShape->style().isSimpleFill());
1718acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon            SkASSERT(kNoRestriction_StencilSupport == this->getStencilSupport(*args.fShape));
172d6f25bf0ef353da39859fb4173d2cf60d52277e4bsalomon        }
1730aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon#endif
1740aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon        return this->onDrawPath(args);
175c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com    }
176ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com
1770aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    /* Args to stencilPath().
1780aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     *
179e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips     * fResourceProvider      The resource provider for creating gpu resources to render the path
1801105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman     * fRenderTargetContext   The target of the draws
1810aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     * fViewMatrix            Matrix applied to the path.
1820aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     * fPath                  The path to draw.
1830e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon     * fAAType                The type of AA, cannot be kCoverage.
1840aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     */
1850aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    struct StencilPathArgs {
186256c37bc9ea2a0420b8ac1084f6d645aaeb919f0Robert Phillips        GrContext*             fContext;
1871105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        GrRenderTargetContext* fRenderTargetContext;
1881105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        const GrClip*          fClip;
1891105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        const SkMatrix*        fViewMatrix;
1900e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon        GrAAType               fAAType;
1911105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        const GrShape*         fShape;
192e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips
1938acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon#ifdef SK_DEBUG
194e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips        void validate() const {
195256c37bc9ea2a0420b8ac1084f6d645aaeb919f0Robert Phillips            SkASSERT(fContext);
1961105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman            SkASSERT(fRenderTargetContext);
197e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips            SkASSERT(fViewMatrix);
1988acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon            SkASSERT(fShape);
199d6562000efca50bc2bfddae8dcb69dce6b8c0950caryclark            SkASSERT(fShape->style().isSimpleFill());
2000e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon            SkASSERT(GrAAType::kCoverage != fAAType);
2018acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon            SkPath path;
2028acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon            fShape->asPath(&path);
2038acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon            SkASSERT(!path.isInverseFillType());
204e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips        }
2058acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon#endif
2060aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    };
2070aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon
208ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com    /**
209e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com     * Draws the path to the stencil buffer. Assume the writable stencil bits are already
210e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com     * initialized to zero. The pixels inside the path will have non-zero stencil values afterwards.
211dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com     */
2120aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    void stencilPath(const StencilPathArgs& args) {
213e7d4b2f5dc3c35f351ba120018c214f739447fb2robertphillips        SkDEBUGCODE(args.validate();)
2148acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon        SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(*args.fShape));
2150aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon        this->onStencilPath(args);
216dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com    }
21706afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
218e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org    // Helper for determining if we can treat a thin stroke as a hairline w/ coverage.
219e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org    // If we can, we draw lots faster (raster device does this same test).
2206663acff010ce752e4bf778da81fa97448c9db31bsalomon    static bool IsStrokeHairlineOrEquivalent(const GrStyle& style, const SkMatrix& matrix,
221e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org                                             SkScalar* outCoverage) {
2226663acff010ce752e4bf778da81fa97448c9db31bsalomon        if (style.pathEffect()) {
2231899651ffc459f5462aa989cd6d08507947b67e4kkinnunen            return false;
2241899651ffc459f5462aa989cd6d08507947b67e4kkinnunen        }
2256663acff010ce752e4bf778da81fa97448c9db31bsalomon        const SkStrokeRec& stroke = style.strokeRec();
226d156d36af871c23ce471a18764f4597f09cfca95kkinnunen        if (stroke.isHairlineStyle()) {
22749f085dddff10473b6ebf832a974288300224e60bsalomon            if (outCoverage) {
228e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org                *outCoverage = SK_Scalar1;
229e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org            }
230e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org            return true;
231e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org        }
232d156d36af871c23ce471a18764f4597f09cfca95kkinnunen        return stroke.getStyle() == SkStrokeRec::kStroke_Style &&
233d156d36af871c23ce471a18764f4597f09cfca95kkinnunen            SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage);
234e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org    }
235e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org
236d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.comprotected:
2370aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    // Helper for getting the device bounds of a path. Inverse filled paths will have bounds set
2380aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    // by devSize. Non-inverse path bounds will not necessarily be clipped to devSize.
2390aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    static void GetPathDevBounds(const SkPath& path,
2400aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon                                 int devW,
2410aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon                                 int devH,
2420aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon                                 const SkMatrix& matrix,
2430aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon                                 SkRect* bounds);
2440aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon
2450aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomonprivate:
246208236d2b6163b977cc9bc299f8df60158ba8226bsalomon@google.com    /**
24745a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     * Subclass overrides if it has any limitations of stenciling support.
24845a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     */
2498acedde5970ce70de6d9791ffeda87a65af4ed07bsalomon    virtual StencilSupport onGetStencilSupport(const GrShape&) const {
25045a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com        return kNoRestriction_StencilSupport;
25145a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com    }
25245a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com
25345a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com    /**
25445a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     * Subclass implementation of drawPath()
255208236d2b6163b977cc9bc299f8df60158ba8226bsalomon@google.com     */
2560aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    virtual bool onDrawPath(const DrawPathArgs& args) = 0;
2570aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon
2580aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    /**
2590aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     * Subclass implementation of canDrawPath()
2600aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon     */
2610aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    virtual bool onCanDrawPath(const CanDrawPathArgs& args) const = 0;
262d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com
26345a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com    /**
26445a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     * Subclass implementation of stencilPath(). Subclass must override iff it ever returns
26545a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     * kStencilOnly in onGetStencilSupport().
26645a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com     */
2670aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon    virtual void onStencilPath(const StencilPathArgs& args) {
26893a379bd4d6b30d86c270b879cf172d80172a72bcdalton        static constexpr GrUserStencilSettings kIncrementStencil(
26993a379bd4d6b30d86c270b879cf172d80172a72bcdalton            GrUserStencilSettings::StaticInit<
27093a379bd4d6b30d86c270b879cf172d80172a72bcdalton                 0xffff,
27193a379bd4d6b30d86c270b879cf172d80172a72bcdalton                 GrUserStencilTest::kAlways,
27293a379bd4d6b30d86c270b879cf172d80172a72bcdalton                 0xffff,
27393a379bd4d6b30d86c270b879cf172d80172a72bcdalton                 GrUserStencilOp::kReplace,
27493a379bd4d6b30d86c270b879cf172d80172a72bcdalton                 GrUserStencilOp::kReplace,
27593a379bd4d6b30d86c270b879cf172d80172a72bcdalton                 0xffff>()
27693a379bd4d6b30d86c270b879cf172d80172a72bcdalton        );
277976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips
278976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips        GrPaint paint;
279976f5f0dc5e907d1ca50685fad117bd15d7fc87brobertphillips
280256c37bc9ea2a0420b8ac1084f6d645aaeb919f0Robert Phillips        DrawPathArgs drawArgs{args.fContext,
28182f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                              std::move(paint),
28282f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                              &kIncrementStencil,
28382f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                              args.fRenderTargetContext,
28482f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                              nullptr,  // clip
28582f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                              args.fViewMatrix,
28682f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                              args.fShape,
28782f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                              args.fAAType,
28882f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                              false};
2890aff2fa82a5fa9f99aa77327dac3e9e803b4ed07bsalomon        this->drawPath(drawArgs);
2901dd9baa6c8faeb4ce837c39d179ce9c9a09719efbsalomon@google.com    }
2911dd9baa6c8faeb4ce837c39d179ce9c9a09719efbsalomon@google.com
292a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    typedef SkRefCnt INHERITED;
293dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com};
294dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com
295dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com#endif
296