• 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 namespace skgpu {
16 class KeyBuilder;
17 }
18 
19 enum class GrStencilTest : uint16_t {
20     kAlways,
21     kNever,
22     kGreater,
23     kGEqual,
24     kLess,
25     kLEqual,
26     kEqual,
27     kNotEqual
28 };
29 static constexpr int kGrStencilTestCount = 1 + (int)GrStencilTest::kNotEqual;
30 
31 enum class GrStencilOp : uint8_t {
32     kKeep,
33     kZero,
34     kReplace, // Replace stencil value with fRef (only the bits enabled in fWriteMask).
35     kInvert,
36     kIncWrap,
37     kDecWrap,
38     // NOTE: clamping occurs before the write mask. So if the MSB is zero and masked out, stencil
39     // values will still wrap when using clamping ops.
40     kIncClamp,
41     kDecClamp
42 };
43 static constexpr int kGrStencilOpCount = 1 + (int)GrStencilOp::kDecClamp;
44 
45 /**
46  * This class defines concrete stencil settings that map directly to the underlying hardware. It
47  * is deduced from user stencil settings, stencil clip status, and the number of bits in the
48  * target stencil buffer.
49  */
50 class GrStencilSettings {
51 public:
GrStencilSettings()52     GrStencilSettings() { this->setDisabled(); }
GrStencilSettings(const GrUserStencilSettings & user,bool hasStencilClip,int numStencilBits)53     GrStencilSettings(const GrUserStencilSettings& user, bool hasStencilClip, int numStencilBits) {
54         this->reset(user, hasStencilClip, numStencilBits);
55     }
GrStencilSettings(const GrStencilSettings & that)56     GrStencilSettings(const GrStencilSettings& that) { this->reset(that); }
57     GrStencilSettings& operator=(const GrStencilSettings& that) { this->reset(that); return *this; }
58 
invalidate()59     void invalidate() { fFlags |= kInvalid_PrivateFlag; }
setDisabled()60     void setDisabled() { fFlags = kAll_StencilFlags; }
61     void reset(const GrUserStencilSettings&, bool hasStencilClip, int numStencilBits);
62     void reset(const GrStencilSettings&);
63 
isValid()64     bool isValid() const { return !(fFlags & kInvalid_PrivateFlag); }
isDisabled()65     bool isDisabled() const { SkASSERT(this->isValid()); return fFlags & kDisabled_StencilFlag; }
doesWrite()66     bool doesWrite() const { SkASSERT(this->isValid());
67                              return !(fFlags & kNoModifyStencil_StencilFlag); }
isTwoSided()68     bool isTwoSided() const { SkASSERT(this->isValid());
69                               return !(fFlags & kSingleSided_StencilFlag); }
usesWrapOp()70     bool usesWrapOp() const { SkASSERT(this->isValid());
71                               return !(fFlags & kNoWrapOps_StencilFlag); }
72 
73     void genKey(skgpu::KeyBuilder* b, bool includeRefsAndMasks) const;
74 
75     bool operator!=(const GrStencilSettings& that) const { return !(*this == that); }
76     bool operator==(const GrStencilSettings&) const;
77 
78     struct Face : public GrTStencilFaceSettings<GrStencilTest, GrStencilOp> {
79         void reset(const GrUserStencilSettings::Face&, bool useStencilClip, int numStencilBits);
80         void setDisabled();
81     };
82 
singleSidedFace()83     const Face& singleSidedFace() const {
84         SkASSERT(!this->isDisabled());
85         SkASSERT(!this->isTwoSided());
86         return fCWFace;
87     }
88     // Returns the stencil settings for triangles that wind clockwise in "post-origin" space.
89     // (i.e., the space that results after a potential y-axis flip on device space for bottom-left
90     // origins.)
postOriginCWFace(GrSurfaceOrigin origin)91     const Face& postOriginCWFace(GrSurfaceOrigin origin) const {
92         SkASSERT(this->isTwoSided());
93         return (kTopLeft_GrSurfaceOrigin == origin) ? fCWFace : fCCWFace;
94     }
95     // Returns the stencil settings for triangles that wind counter-clockwise in "post-origin"
96     // space. (i.e., the space that results after a potential y-axis flip on device space for
97     // bottom-left origins.)
postOriginCCWFace(GrSurfaceOrigin origin)98     const Face& postOriginCCWFace(GrSurfaceOrigin origin) const {
99         SkASSERT(this->isTwoSided());
100         return (kTopLeft_GrSurfaceOrigin == origin) ? fCCWFace : fCWFace;
101     }
102 
103     /** Gets the user stencil settings to directly set the clip bit. */
104     static const GrUserStencilSettings* SetClipBitSettings(bool setToInside);
105 
106 private:
107     // Internal flag for backends to optionally mark their tracked stencil state as invalid.
108     // NOTE: This value is outside the declared range of GrStencilFlags, but since that type is
109     // explicitly backed by 'int', it can still represent this constant. clang 11 complains about
110     // mixing enum types in bit operations, so this works around that.
111     inline static constexpr GrStencilFlags kInvalid_PrivateFlag =
112             static_cast<GrStencilFlags>(kLast_StencilFlag << 1);
113 
114     uint32_t   fFlags;
115     Face       fCWFace;
116     Face       fCCWFace;
117 };
118 
119 #endif
120