• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 
9 #ifndef GrStencilSettings_DEFINED
10 #define GrStencilSettings_DEFINED
11 
12 #include "include/core/SkRegion.h"
13 #include "src/gpu/GrUserStencilSettings.h"
14 
15 class GrProcessorKeyBuilder;
16 
17 enum class GrStencilTest : uint16_t {
18     kAlways,
19     kNever,
20     kGreater,
21     kGEqual,
22     kLess,
23     kLEqual,
24     kEqual,
25     kNotEqual
26 };
27 static constexpr int kGrStencilTestCount = 1 + (int)GrStencilTest::kNotEqual;
28 
29 enum class GrStencilOp : uint8_t {
30     kKeep,
31     kZero,
32     kReplace, // Replace stencil value with fRef (only the bits enabled in fWriteMask).
33     kInvert,
34     kIncWrap,
35     kDecWrap,
36     // NOTE: clamping occurs before the write mask. So if the MSB is zero and masked out, stencil
37     // values will still wrap when using clamping ops.
38     kIncClamp,
39     kDecClamp
40 };
41 static constexpr int kGrStencilOpCount = 1 + (int)GrStencilOp::kDecClamp;
42 
43 /**
44  * This class defines concrete stencil settings that map directly to the underlying hardware. It
45  * is deduced from user stencil settings, stencil clip status, and the number of bits in the
46  * target stencil buffer.
47  */
48 class GrStencilSettings {
49 public:
GrStencilSettings()50     GrStencilSettings() { this->setDisabled(); }
GrStencilSettings(const GrUserStencilSettings & user,bool hasStencilClip,int numStencilBits)51     GrStencilSettings(const GrUserStencilSettings& user, bool hasStencilClip, int numStencilBits) {
52         this->reset(user, hasStencilClip, numStencilBits);
53     }
GrStencilSettings(const GrStencilSettings & that)54     GrStencilSettings(const GrStencilSettings& that) { this->reset(that); }
55     GrStencilSettings& operator=(const GrStencilSettings& that) { this->reset(that); return *this; }
56 
invalidate()57     void invalidate() { fFlags |= kInvalid_PrivateFlag; }
setDisabled()58     void setDisabled() { fFlags = kAll_StencilFlags; }
59     void reset(const GrUserStencilSettings&, bool hasStencilClip, int numStencilBits);
60     void reset(const GrStencilSettings&);
61 
isValid()62     bool isValid() const { return !(fFlags & kInvalid_PrivateFlag); }
isDisabled()63     bool isDisabled() const { SkASSERT(this->isValid()); return fFlags & kDisabled_StencilFlag; }
doesWrite()64     bool doesWrite() const { SkASSERT(this->isValid());
65                              return !(fFlags & kNoModifyStencil_StencilFlag); }
isTwoSided()66     bool isTwoSided() const { SkASSERT(this->isValid());
67                               return !(fFlags & kSingleSided_StencilFlag); }
usesWrapOp()68     bool usesWrapOp() const { SkASSERT(this->isValid());
69                               return !(fFlags & kNoWrapOps_StencilFlag); }
70 
71     void genKey(GrProcessorKeyBuilder* b) const;
72 
73     bool operator!=(const GrStencilSettings& that) const { return !(*this == that); }
74     bool operator==(const GrStencilSettings&) const;
75 
76     struct Face : public GrTStencilFaceSettings<GrStencilTest, GrStencilOp> {
77         void reset(const GrUserStencilSettings::Face&, bool useStencilClip, int numStencilBits);
78         void setDisabled();
79     };
80 
frontAndBack()81     const Face& frontAndBack() const {
82         SkASSERT(!this->isDisabled());
83         SkASSERT(!this->isTwoSided());
84         return fFront;
85     }
front(GrSurfaceOrigin origin)86     const Face& front(GrSurfaceOrigin origin) const {
87         SkASSERT(this->isTwoSided());
88         return (kTopLeft_GrSurfaceOrigin == origin) ? fFront : fBack;
89     }
back(GrSurfaceOrigin origin)90     const Face& back(GrSurfaceOrigin origin) const {
91         SkASSERT(this->isTwoSided());
92         return (kTopLeft_GrSurfaceOrigin == origin) ? fBack : fFront;
93     }
94 
95     /**
96      * Given a thing to draw into the stencil clip, a fill type, and a set op
97      * this function determines:
98      *      1. Whether the thing can be draw directly to the stencil clip or
99      *      needs to be drawn to the client portion of the stencil first.
100      *      2. How many passes are needed.
101      *      3. What those passes are.
102      *
103      * @param op                the set op to combine this element with the existing clip
104      * @param canBeDirect       can the caller draw this element directly (without using stencil)?
105      * @param invertedFill      is this path inverted
106      * @param drawDirectToClip  out: true if caller should draw the element directly, false if it
107      *                          should draw it into the user stencil bits first.
108      *
109      * @return a null-terminated array of settings for stencil passes.
110      *
111      *         If drawDirectToClip is false, the caller must first draw the element into the user
112      *         stencil bits, and then cover the clip area with multiple passes using the returned
113      *         stencil settings.
114      *
115      *         If drawDirectToClip is true, the returned array will only have one pass and the
116      *         caller should use those stencil settings while drawing the element directly.
117      */
118     static GrUserStencilSettings const* const* GetClipPasses(SkRegion::Op op,
119                                                              bool canBeDirect,
120                                                              bool invertedFill,
121                                                              bool* drawDirectToClip);
122 
123     /** Gets the user stencil settings to directly set the clip bit. */
124     static const GrUserStencilSettings* SetClipBitSettings(bool setToInside);
125 
126 private:
127     // Internal flag for backends to optionally mark their tracked stencil state as invalid.
128     enum { kInvalid_PrivateFlag = (kLast_StencilFlag << 1) };
129 
130     uint32_t   fFlags;
131     Face       fFront;
132     Face       fBack;
133 };
134 
135 #endif
136