LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu - GrUserStencilSettings.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 5 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 3 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 GrUserStencilSettings_DEFINED
      10             : #define GrUserStencilSettings_DEFINED
      11             : 
      12             : #include "GrTypes.h"
      13             : 
      14             : /**
      15             :  * Gr uses the stencil buffer to implement complex clipping inside the
      16             :  * GrOpList class. The GrOpList makes a subset of the stencil buffer
      17             :  * bits available for other uses by external code (user bits). Client code can
      18             :  * modify these bits. GrOpList will ignore ref, mask, and writemask bits
      19             :  * provided by clients that fall outside the user range.
      20             :  *
      21             :  * When code outside the GrOpList class uses the stencil buffer the contract
      22             :  * is as follows:
      23             :  *
      24             :  * > Normal stencil funcs allow the client to pass / fail regardless of the
      25             :  *   reserved clip bits.
      26             :  * > Additional functions allow a test against the clip along with a limited
      27             :  *   set of tests against the user bits.
      28             :  * > Client can assume all user bits are zero initially.
      29             :  * > Client must ensure that after all its passes are finished it has only
      30             :  *   written to the color buffer in the region inside the clip. Furthermore, it
      31             :  *   must zero all user bits that were modifed (both inside and outside the
      32             :  *   clip).
      33             :  */
      34             : 
      35             : enum GrStencilFlags {
      36             :     kDisabled_StencilFlag         = 0x1,
      37             :     kNoModifyStencil_StencilFlag  = 0x2,
      38             :     kNoWrapOps_StencilFlag        = 0x4,
      39             :     kSingleSided_StencilFlag      = 0x8,
      40             : 
      41             :     kLast_StencilFlag = kSingleSided_StencilFlag,
      42             :     kAll_StencilFlags = kLast_StencilFlag | (kLast_StencilFlag - 1)
      43             : };
      44             : 
      45             : template<typename TTest, typename TOp> struct GrTStencilFaceSettings {
      46             :     uint16_t   fRef;        // Reference value for stencil test and ops.
      47             :     TTest      fTest;       // Stencil test function, where fRef is on the left side.
      48             :     uint16_t   fTestMask;   // Bitwise "and" to perform on fRef and stencil values before testing.
      49             :                             // (e.g. (fRef & fTestMask) < (stencil & fTestMask))
      50             :     TOp        fPassOp;     // Op to perform when the test passes.
      51             :     TOp        fFailOp;     // Op to perform when the test fails.
      52             :     uint16_t   fWriteMask;  // Indicates which bits in the stencil buffer should be updated.
      53             :                             // (e.g. stencil = (newValue & fWriteMask) | (stencil & ~fWriteMask))
      54             : };
      55             : 
      56             : enum class GrUserStencilTest : uint16_t {
      57             :     // Tests that respect the clip bit. If a stencil clip is not in effect, the "IfInClip" is
      58             :     // ignored and these only act on user bits.
      59             :     kAlwaysIfInClip,
      60             :     kEqualIfInClip,
      61             :     kLessIfInClip,
      62             :     kLEqualIfInClip,
      63             : 
      64             :     // Tests that ignore the clip bit. The client is responsible to ensure no color write occurs
      65             :     // outside the clip if it is in use.
      66             :     kAlways,
      67             :     kNever,
      68             :     kGreater,
      69             :     kGEqual,
      70             :     kLess,
      71             :     kLEqual,
      72             :     kEqual,
      73             :     kNotEqual
      74             : };
      75             : constexpr static GrUserStencilTest kLastClippedStencilTest = GrUserStencilTest::kLEqualIfInClip;
      76             : constexpr static int kGrUserStencilTestCount = 1 + (int)GrUserStencilTest::kNotEqual;
      77             : 
      78             : enum class GrUserStencilOp : uint8_t {
      79             :     kKeep,
      80             : 
      81             :     // Ops that only modify user bits. These must not be paired with ops that modify the clip bit.
      82             :     kZero,
      83             :     kReplace, // Replace stencil value with fRef (only the bits enabled in fWriteMask).
      84             :     kInvert,
      85             :     kIncWrap,
      86             :     kDecWrap,
      87             :     // These two should only be used if wrap ops are not supported, or if the math is guaranteed
      88             :     // to not overflow. The user bits may or may not clamp, depending on the state of non-user bits.
      89             :     kIncMaybeClamp,
      90             :     kDecMaybeClamp,
      91             : 
      92             :     // Ops that only modify the clip bit. These must not be paired with ops that modify user bits.
      93             :     kZeroClipBit,
      94             :     kSetClipBit,
      95             :     kInvertClipBit,
      96             : 
      97             :     // Ops that modify both clip and user bits. These can only be paired with kKeep or each other.
      98             :     kSetClipAndReplaceUserBits,
      99             :     kZeroClipAndUserBits
     100             : };
     101             : constexpr static GrUserStencilOp kLastUserOnlyStencilOp = GrUserStencilOp::kDecMaybeClamp;
     102             : constexpr static GrUserStencilOp kLastClipOnlyStencilOp = GrUserStencilOp::kInvertClipBit;
     103             : constexpr static int kGrUserStencilOpCount = 1 + (int)GrUserStencilOp::kZeroClipAndUserBits;
     104             : 
     105             : /**
     106             :  * This struct is a compile-time constant representation of user stencil settings. It describes in
     107             :  * abstract terms how a draw will use the stencil buffer. It gets ODR-used at runtime to define a
     108             :  * draw's stencil settings, and is later translated into concrete settings when the pipeline is
     109             :  * finalized.
     110             :  */
     111             : struct GrUserStencilSettings {
     112             :     typedef GrTStencilFaceSettings<GrUserStencilTest, GrUserStencilOp> Face;
     113             : 
     114             :     template<GrUserStencilTest, GrUserStencilOp PassOp, GrUserStencilOp FailOp> struct Attrs;
     115             : 
     116             :     // Unfortunately, this is the only way to pass template arguments to a constructor.
     117             :     template<uint16_t Ref, GrUserStencilTest Test, uint16_t TestMask,
     118             :              GrUserStencilOp PassOp, GrUserStencilOp FailOp, uint16_t WriteMask> struct Init {};
     119             : 
     120             :     template<uint16_t FtRef,            uint16_t BkRef,
     121             :              GrUserStencilTest FtTest,  GrUserStencilTest BkTest,
     122             :              uint16_t FtTestMask,       uint16_t BkTestMask,
     123             :              GrUserStencilOp FtPassOp,  GrUserStencilOp BkPassOp,
     124             :              GrUserStencilOp FtFailOp,  GrUserStencilOp BkFailOp,
     125             :              uint16_t FtWriteMask,      uint16_t BkWriteMask> struct InitSeparate {};
     126             : 
     127             :     template<uint16_t Ref, GrUserStencilTest Test, uint16_t TestMask,
     128             :              GrUserStencilOp PassOp, GrUserStencilOp FailOp, uint16_t WriteMask>
     129             :     constexpr static Init<Ref, Test, TestMask, PassOp, FailOp, WriteMask> StaticInit() {
     130             :         return Init<Ref, Test, TestMask, PassOp, FailOp, WriteMask>();
     131             :     }
     132             : 
     133             :     template<uint16_t FtRef,            uint16_t BkRef,
     134             :              GrUserStencilTest FtTest,  GrUserStencilTest BkTest,
     135             :              uint16_t FtTestMask,       uint16_t BkTestMask,
     136             :              GrUserStencilOp FtPassOp,  GrUserStencilOp BkPassOp,
     137             :              GrUserStencilOp FtFailOp,  GrUserStencilOp BkFailOp,
     138             :              uint16_t FtWriteMask,      uint16_t BkWriteMask>
     139             :     constexpr static InitSeparate<FtRef, BkRef, FtTest, BkTest, FtTestMask, BkTestMask,
     140             :                                   FtPassOp, BkPassOp, FtFailOp, BkFailOp, FtWriteMask,
     141             :                                   BkWriteMask> StaticInitSeparate() {
     142             :         return InitSeparate<FtRef, BkRef, FtTest, BkTest, FtTestMask, BkTestMask,
     143             :                             FtPassOp, BkPassOp, FtFailOp, BkFailOp, FtWriteMask, BkWriteMask>();
     144             :     }
     145             : 
     146             :     // We construct with template arguments in order to enforce that the struct be compile-time
     147             :     // constant and to make use of static asserts.
     148             :     template<uint16_t Ref, GrUserStencilTest Test, uint16_t TestMask,
     149             :              GrUserStencilOp PassOp, GrUserStencilOp FailOp, uint16_t WriteMask,
     150             :              typename Attrs = Attrs<Test, PassOp, FailOp> >
     151             :     constexpr explicit GrUserStencilSettings(
     152             :             const Init<Ref, Test, TestMask, PassOp, FailOp, WriteMask>&)
     153             :         : fFrontFlags{(uint16_t)(Attrs::Flags(false) | kSingleSided_StencilFlag),
     154             :                       (uint16_t)(Attrs::Flags(true) | kSingleSided_StencilFlag)}
     155             :         , fFront{Ref, Test, Attrs::EffectiveTestMask(TestMask), PassOp, FailOp,
     156             :                  Attrs::EffectiveWriteMask(WriteMask)}
     157             :         , fBackFlags{(uint16_t)(Attrs::Flags(false) | kSingleSided_StencilFlag),
     158             :                      (uint16_t)(Attrs::Flags(true) | kSingleSided_StencilFlag)}
     159             :         , fBack{Ref, Test, Attrs::EffectiveTestMask(TestMask), PassOp, FailOp,
     160             :                 Attrs::EffectiveWriteMask(WriteMask)} {
     161             :     }
     162             : 
     163             :     template<uint16_t FtRef,            uint16_t BkRef,
     164             :              GrUserStencilTest FtTest,  GrUserStencilTest BkTest,
     165             :              uint16_t FtTestMask,       uint16_t BkTestMask,
     166             :              GrUserStencilOp FtPassOp,  GrUserStencilOp BkPassOp,
     167             :              GrUserStencilOp FtFailOp,  GrUserStencilOp BkFailOp,
     168             :              uint16_t FtWriteMask,      uint16_t BkWriteMask,
     169             :              typename FtAttrs = Attrs<FtTest, FtPassOp, FtFailOp>,
     170             :              typename BkAttrs = Attrs<BkTest, BkPassOp, BkFailOp> >
     171             :     constexpr explicit GrUserStencilSettings(
     172             :             const InitSeparate<FtRef, BkRef, FtTest, BkTest, FtTestMask, BkTestMask,
     173             :                                FtPassOp, BkPassOp, FtFailOp, BkFailOp, FtWriteMask, BkWriteMask>&)
     174             :         : fFrontFlags{FtAttrs::Flags(false), FtAttrs::Flags(true)}
     175             :         , fFront{FtRef, FtTest, FtAttrs::EffectiveTestMask(FtTestMask), FtPassOp, FtFailOp,
     176             :                  FtAttrs::EffectiveWriteMask(FtWriteMask)}
     177             :         , fBackFlags{BkAttrs::Flags(false), BkAttrs::Flags(true)}
     178             :         , fBack{BkRef, BkTest, BkAttrs::EffectiveTestMask(BkTestMask), BkPassOp, BkFailOp,
     179             :                 BkAttrs::EffectiveWriteMask(BkWriteMask)} {}
     180             : 
     181             :     // This struct can only be constructed with static initializers.
     182             :     GrUserStencilSettings() = delete;
     183             :     GrUserStencilSettings(const GrUserStencilSettings&) = delete;
     184             : 
     185           0 :     uint16_t flags(bool hasStencilClip) const {
     186           0 :         return fFrontFlags[hasStencilClip] & fBackFlags[hasStencilClip];
     187             :     }
     188           0 :     bool isDisabled(bool hasStencilClip) const {
     189           0 :         return this->flags(hasStencilClip) & kDisabled_StencilFlag;
     190             :     }
     191             :     bool isTwoSided(bool hasStencilClip) const {
     192             :         return !(this->flags(hasStencilClip) & kSingleSided_StencilFlag);
     193             :     }
     194             :     bool usesWrapOp(bool hasStencilClip) const {
     195             :         return !(this->flags(hasStencilClip) & kNoWrapOps_StencilFlag);
     196             :     }
     197             : 
     198             :     const uint16_t   fFrontFlags[2]; // frontFlagsForDraw = fFrontFlags[hasStencilClip].
     199             :     const Face       fFront;
     200             :     const uint16_t   fBackFlags[2]; // backFlagsForDraw = fBackFlags[hasStencilClip].
     201             :     const Face       fBack;
     202             : 
     203             :     static const GrUserStencilSettings& kUnused;
     204             : 
     205           0 :     bool isUnused() const { return this == &kUnused; }
     206             : };
     207             : 
     208             : template<GrUserStencilTest Test, GrUserStencilOp PassOp, GrUserStencilOp FailOp>
     209             : struct GrUserStencilSettings::Attrs {
     210             :     // Ensure an op that only modifies user bits isn't paired with one that modifies clip bits.
     211             :     GR_STATIC_ASSERT(GrUserStencilOp::kKeep == PassOp || GrUserStencilOp::kKeep == FailOp ||
     212             :                      (PassOp <= kLastUserOnlyStencilOp) == (FailOp <= kLastUserOnlyStencilOp));
     213             :     // Ensure an op that only modifies clip bits isn't paired with one that modifies clip and user.
     214             :     GR_STATIC_ASSERT(GrUserStencilOp::kKeep == PassOp || GrUserStencilOp::kKeep == FailOp ||
     215             :                      (PassOp <= kLastClipOnlyStencilOp) == (FailOp <= kLastClipOnlyStencilOp));
     216             : 
     217             :     constexpr static bool TestAlwaysPasses(bool hasStencilClip) {
     218             :         return (!hasStencilClip && GrUserStencilTest::kAlwaysIfInClip == Test) ||
     219             :                 GrUserStencilTest::kAlways == Test;
     220             :     }
     221             :     constexpr static bool DoesNotModifyStencil(bool hasStencilClip) {
     222             :         return (GrUserStencilTest::kNever == Test || GrUserStencilOp::kKeep == PassOp) &&
     223             :                 (TestAlwaysPasses(hasStencilClip) || GrUserStencilOp::kKeep == FailOp);
     224             :     }
     225             :     constexpr static bool IsDisabled(bool hasStencilClip) {
     226             :         return TestAlwaysPasses(hasStencilClip) && DoesNotModifyStencil(hasStencilClip);
     227             :     }
     228             :     constexpr static bool UsesWrapOps() {
     229             :         return GrUserStencilOp::kIncWrap == PassOp || GrUserStencilOp::kDecWrap == PassOp ||
     230             :                GrUserStencilOp::kIncWrap == FailOp || GrUserStencilOp::kDecWrap == FailOp;
     231             :     }
     232             :     constexpr static bool TestIgnoresRef() {
     233             :         return (GrUserStencilTest::kAlwaysIfInClip == Test || GrUserStencilTest::kAlways == Test ||
     234             :                 GrUserStencilTest::kNever == Test);
     235             :     }
     236             :     constexpr static uint16_t Flags(bool hasStencilClip) {
     237             :         return (IsDisabled(hasStencilClip) ? kDisabled_StencilFlag : 0) |
     238             :                (DoesNotModifyStencil(hasStencilClip) ? kNoModifyStencil_StencilFlag : 0) |
     239             :                (UsesWrapOps() ? 0 : kNoWrapOps_StencilFlag);
     240             :     }
     241             :     constexpr static uint16_t EffectiveTestMask(uint16_t testMask) {
     242             :         return TestIgnoresRef() ? 0 : testMask;
     243             :     }
     244             :     constexpr static uint16_t EffectiveWriteMask(uint16_t writeMask) {
     245             :         // We don't modify the mask differently when hasStencilClip=false because either the entire
     246             :         // face gets disabled in that case (e.g. Test=kAlwaysIfInClip, PassOp=kKeep), or else the
     247             :         // effective mask stays the same either way.
     248             :         return DoesNotModifyStencil(true) ? 0 : writeMask;
     249             :     }
     250             : };
     251             : 
     252             : #endif

Generated by: LCOV version 1.13