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 GrStencilSettings_DEFINED
10 : #define GrStencilSettings_DEFINED
11 :
12 : #include "GrUserStencilSettings.h"
13 : #include "SkRegion.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:
50 0 : GrStencilSettings() { this->setDisabled(); }
51 0 : GrStencilSettings(const GrUserStencilSettings& user, bool hasStencilClip, int numStencilBits) {
52 0 : this->reset(user, hasStencilClip, numStencilBits);
53 0 : }
54 : GrStencilSettings(const GrStencilSettings& that) { this->reset(that); }
55 0 : GrStencilSettings& operator=(const GrStencilSettings& that) { this->reset(that); return *this; }
56 :
57 0 : void invalidate() { fFlags |= kInvalid_PrivateFlag; }
58 0 : void setDisabled() { fFlags = kAll_StencilFlags; }
59 : void reset(const GrUserStencilSettings&, bool hasStencilClip, int numStencilBits);
60 : void reset(const GrStencilSettings&);
61 :
62 0 : bool isValid() const { return !(fFlags & kInvalid_PrivateFlag); }
63 0 : bool isDisabled() const { SkASSERT(this->isValid()); return fFlags & kDisabled_StencilFlag; }
64 : bool doesWrite() const { SkASSERT(this->isValid());
65 : return !(fFlags & kNoModifyStencil_StencilFlag); }
66 0 : bool isTwoSided() const { SkASSERT(this->isValid());
67 0 : return !(fFlags & kSingleSided_StencilFlag); }
68 : bool usesWrapOp() const { SkASSERT(this->isValid());
69 : return !(fFlags & kNoWrapOps_StencilFlag); }
70 :
71 : void genKey(GrProcessorKeyBuilder* b) const;
72 :
73 0 : 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 :
81 0 : const Face& front() const { SkASSERT(!this->isDisabled()); return fFront; }
82 0 : const Face& back() const { SkASSERT(this->isTwoSided()); return fBack; }
83 :
84 : /**
85 : * Given a thing to draw into the stencil clip, a fill type, and a set op
86 : * this function determines:
87 : * 1. Whether the thing can be draw directly to the stencil clip or
88 : * needs to be drawn to the client portion of the stencil first.
89 : * 2. How many passes are needed.
90 : * 3. What those passes are.
91 : *
92 : * @param op the set op to combine this element with the existing clip
93 : * @param canBeDirect can the caller draw this element directly (without using stencil)?
94 : * @param invertedFill is this path inverted
95 : * @param drawDirectToClip out: true if caller should draw the element directly, false if it
96 : * should draw it into the user stencil bits first.
97 : *
98 : * @return a null-terminated array of settings for stencil passes.
99 : *
100 : * If drawDirectToClip is false, the caller must first draw the element into the user
101 : * stencil bits, and then cover the clip area with multiple passes using the returned
102 : * stencil settings.
103 : *
104 : * If drawDirectToClip is true, the returned array will only have one pass and the
105 : * caller should use those stencil settings while drawing the element directly.
106 : */
107 : static GrUserStencilSettings const* const* GetClipPasses(SkRegion::Op op,
108 : bool canBeDirect,
109 : bool invertedFill,
110 : bool* drawDirectToClip);
111 :
112 : private:
113 : // Internal flag for backends to optionally mark their tracked stencil state as invalid.
114 : enum { kInvalid_PrivateFlag = (kLast_StencilFlag << 1) };
115 :
116 : uint32_t fFlags;
117 : Face fFront;
118 : Face fBack;
119 : };
120 :
121 : #endif
|