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