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