GrStencilSettings.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. #include "include/core/SkRegion.h"
  10. #include "src/gpu/GrUserStencilSettings.h"
  11. class GrProcessorKeyBuilder;
  12. enum class GrStencilTest : uint16_t {
  13. kAlways,
  14. kNever,
  15. kGreater,
  16. kGEqual,
  17. kLess,
  18. kLEqual,
  19. kEqual,
  20. kNotEqual
  21. };
  22. static constexpr int kGrStencilTestCount = 1 + (int)GrStencilTest::kNotEqual;
  23. enum class GrStencilOp : uint8_t {
  24. kKeep,
  25. kZero,
  26. kReplace, // Replace stencil value with fRef (only the bits enabled in fWriteMask).
  27. kInvert,
  28. kIncWrap,
  29. kDecWrap,
  30. // NOTE: clamping occurs before the write mask. So if the MSB is zero and masked out, stencil
  31. // values will still wrap when using clamping ops.
  32. kIncClamp,
  33. kDecClamp
  34. };
  35. static constexpr int kGrStencilOpCount = 1 + (int)GrStencilOp::kDecClamp;
  36. /**
  37. * This class defines concrete stencil settings that map directly to the underlying hardware. It
  38. * is deduced from user stencil settings, stencil clip status, and the number of bits in the
  39. * target stencil buffer.
  40. */
  41. class GrStencilSettings {
  42. public:
  43. GrStencilSettings() { this->setDisabled(); }
  44. GrStencilSettings(const GrUserStencilSettings& user, bool hasStencilClip, int numStencilBits) {
  45. this->reset(user, hasStencilClip, numStencilBits);
  46. }
  47. GrStencilSettings(const GrStencilSettings& that) { this->reset(that); }
  48. GrStencilSettings& operator=(const GrStencilSettings& that) { this->reset(that); return *this; }
  49. void invalidate() { fFlags |= kInvalid_PrivateFlag; }
  50. void setDisabled() { fFlags = kAll_StencilFlags; }
  51. void reset(const GrUserStencilSettings&, bool hasStencilClip, int numStencilBits);
  52. void reset(const GrStencilSettings&);
  53. bool isValid() const { return !(fFlags & kInvalid_PrivateFlag); }
  54. bool isDisabled() const { SkASSERT(this->isValid()); return fFlags & kDisabled_StencilFlag; }
  55. bool doesWrite() const { SkASSERT(this->isValid());
  56. return !(fFlags & kNoModifyStencil_StencilFlag); }
  57. bool isTwoSided() const { SkASSERT(this->isValid());
  58. return !(fFlags & kSingleSided_StencilFlag); }
  59. bool usesWrapOp() const { SkASSERT(this->isValid());
  60. return !(fFlags & kNoWrapOps_StencilFlag); }
  61. void genKey(GrProcessorKeyBuilder* b) const;
  62. bool operator!=(const GrStencilSettings& that) const { return !(*this == that); }
  63. bool operator==(const GrStencilSettings&) const;
  64. struct Face : public GrTStencilFaceSettings<GrStencilTest, GrStencilOp> {
  65. void reset(const GrUserStencilSettings::Face&, bool useStencilClip, int numStencilBits);
  66. void setDisabled();
  67. };
  68. const Face& frontAndBack() const {
  69. SkASSERT(!this->isDisabled());
  70. SkASSERT(!this->isTwoSided());
  71. return fFront;
  72. }
  73. const Face& front(GrSurfaceOrigin origin) const {
  74. SkASSERT(this->isTwoSided());
  75. return (kTopLeft_GrSurfaceOrigin == origin) ? fFront : fBack;
  76. }
  77. const Face& back(GrSurfaceOrigin origin) const {
  78. SkASSERT(this->isTwoSided());
  79. return (kTopLeft_GrSurfaceOrigin == origin) ? fBack : fFront;
  80. }
  81. /**
  82. * Given a thing to draw into the stencil clip, a fill type, and a set op
  83. * this function determines:
  84. * 1. Whether the thing can be draw directly to the stencil clip or
  85. * needs to be drawn to the client portion of the stencil first.
  86. * 2. How many passes are needed.
  87. * 3. What those passes are.
  88. *
  89. * @param op the set op to combine this element with the existing clip
  90. * @param canBeDirect can the caller draw this element directly (without using stencil)?
  91. * @param invertedFill is this path inverted
  92. * @param drawDirectToClip out: true if caller should draw the element directly, false if it
  93. * should draw it into the user stencil bits first.
  94. *
  95. * @return a null-terminated array of settings for stencil passes.
  96. *
  97. * If drawDirectToClip is false, the caller must first draw the element into the user
  98. * stencil bits, and then cover the clip area with multiple passes using the returned
  99. * stencil settings.
  100. *
  101. * If drawDirectToClip is true, the returned array will only have one pass and the
  102. * caller should use those stencil settings while drawing the element directly.
  103. */
  104. static GrUserStencilSettings const* const* GetClipPasses(SkRegion::Op op,
  105. bool canBeDirect,
  106. bool invertedFill,
  107. bool* drawDirectToClip);
  108. /** Gets the user stencil settings to directly set the clip bit. */
  109. static const GrUserStencilSettings* SetClipBitSettings(bool setToInside);
  110. private:
  111. // Internal flag for backends to optionally mark their tracked stencil state as invalid.
  112. enum { kInvalid_PrivateFlag = (kLast_StencilFlag << 1) };
  113. uint32_t fFlags;
  114. Face fFront;
  115. Face fBack;
  116. };
  117. #endif