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, bool includeRefsAndMasks) 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 singleSidedFace()81 const Face& singleSidedFace() const { 82 SkASSERT(!this->isDisabled()); 83 SkASSERT(!this->isTwoSided()); 84 return fCWFace; 85 } 86 // Returns the stencil settings for triangles that wind clockwise in "post-origin" space. 87 // (i.e., the space that results after a potential y-axis flip on device space for bottom-left 88 // origins.) postOriginCWFace(GrSurfaceOrigin origin)89 const Face& postOriginCWFace(GrSurfaceOrigin origin) const { 90 SkASSERT(this->isTwoSided()); 91 return (kTopLeft_GrSurfaceOrigin == origin) ? fCWFace : fCCWFace; 92 } 93 // Returns the stencil settings for triangles that wind counter-clockwise in "post-origin" 94 // space. (i.e., the space that results after a potential y-axis flip on device space for 95 // bottom-left origins.) postOriginCCWFace(GrSurfaceOrigin origin)96 const Face& postOriginCCWFace(GrSurfaceOrigin origin) const { 97 SkASSERT(this->isTwoSided()); 98 return (kTopLeft_GrSurfaceOrigin == origin) ? fCCWFace : fCWFace; 99 } 100 101 /** Gets the user stencil settings to directly set the clip bit. */ 102 static const GrUserStencilSettings* SetClipBitSettings(bool setToInside); 103 104 private: 105 // Internal flag for backends to optionally mark their tracked stencil state as invalid. 106 // NOTE: This value is outside the declared range of GrStencilFlags, but since that type is 107 // explicitly backed by 'int', it can still represent this constant. clang 11 complains about 108 // mixing enum types in bit operations, so this works around that. 109 inline static constexpr GrStencilFlags kInvalid_PrivateFlag = 110 static_cast<GrStencilFlags>(kLast_StencilFlag << 1); 111 112 uint32_t fFlags; 113 Face fCWFace; 114 Face fCCWFace; 115 }; 116 117 #endif 118