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 : #ifndef gr_instanced_InstancedRenderingTypes_DEFINED
9 : #define gr_instanced_InstancedRenderingTypes_DEFINED
10 :
11 : #include "GrTypes.h"
12 : #include "GrTypesPriv.h"
13 : #include "SkRRect.h"
14 :
15 : namespace gr_instanced {
16 :
17 : /**
18 : * Per-vertex data. These values get fed into normal vertex attribs.
19 : */
20 : struct ShapeVertex {
21 : float fX, fY; //!< Shape coordinates.
22 : int32_t fAttrs; //!< Shape-specific vertex attributes, if needed.
23 : };
24 :
25 : /**
26 : * Per-instance data. These values get fed into instanced vertex attribs.
27 : */
28 : struct Instance {
29 : uint32_t fInfo; //!< Packed info about the instance. See InfoBits.
30 : float fShapeMatrix2x3[6]; //!< Maps canonical shape coords -> device space coords.
31 : uint32_t fColor; //!< Color to be written out by the primitive processor.
32 : float fLocalRect[4]; //!< Local coords rect that spans [-1, +1] in shape coords.
33 : };
34 :
35 : enum class Attrib : uint8_t {
36 : kShapeCoords,
37 : kVertexAttrs,
38 : kInstanceInfo,
39 : kShapeMatrixX,
40 : kShapeMatrixY,
41 : kColor,
42 : kLocalRect
43 : };
44 : constexpr int kNumAttribs = 1 + (int)Attrib::kLocalRect;
45 :
46 : enum class ShapeType : uint8_t {
47 : kRect,
48 : kOval,
49 : kSimpleRRect,
50 : kNinePatch,
51 : kComplexRRect
52 : };
53 : constexpr int kNumShapeTypes = 1 + (int)ShapeType::kComplexRRect;
54 :
55 0 : inline static ShapeType GetRRectShapeType(const SkRRect& rrect) {
56 0 : SkASSERT(rrect.getType() >= SkRRect::kRect_Type &&
57 : rrect.getType() <= SkRRect::kComplex_Type);
58 0 : return static_cast<ShapeType>(rrect.getType() - 1);
59 :
60 : GR_STATIC_ASSERT((int)ShapeType::kRect == SkRRect::kRect_Type - 1);
61 : GR_STATIC_ASSERT((int)ShapeType::kOval == SkRRect::kOval_Type - 1);
62 : GR_STATIC_ASSERT((int)ShapeType::kSimpleRRect == SkRRect::kSimple_Type - 1);
63 : GR_STATIC_ASSERT((int)ShapeType::kNinePatch == SkRRect::kNinePatch_Type - 1);
64 : GR_STATIC_ASSERT((int)ShapeType::kComplexRRect == SkRRect::kComplex_Type - 1);
65 : GR_STATIC_ASSERT(kNumShapeTypes == SkRRect::kComplex_Type);
66 : }
67 :
68 : enum ShapeFlag {
69 : kRect_ShapeFlag = (1 << (int)ShapeType::kRect),
70 : kOval_ShapeFlag = (1 << (int)ShapeType::kOval),
71 : kSimpleRRect_ShapeFlag = (1 << (int)ShapeType::kSimpleRRect),
72 : kNinePatch_ShapeFlag = (1 << (int)ShapeType::kNinePatch),
73 : kComplexRRect_ShapeFlag = (1 << (int)ShapeType::kComplexRRect),
74 :
75 : kRRect_ShapesMask = kSimpleRRect_ShapeFlag | kNinePatch_ShapeFlag | kComplexRRect_ShapeFlag
76 : };
77 :
78 0 : constexpr uint8_t GetShapeFlag(ShapeType type) { return 1 << (int)type; }
79 :
80 : /**
81 : * Defines what data is stored at which bits in the fInfo field of the instanced data.
82 : */
83 : enum InfoBits {
84 : kShapeType_InfoBit = 29,
85 : kInnerShapeType_InfoBit = 27,
86 : kPerspective_InfoBit = 26,
87 : kLocalMatrix_InfoBit = 25,
88 : kParamsIdx_InfoBit = 0
89 : };
90 :
91 : enum InfoMasks {
92 : kShapeType_InfoMask = 0u - (1 << kShapeType_InfoBit),
93 : kInnerShapeType_InfoMask = (1 << kShapeType_InfoBit) - (1 << kInnerShapeType_InfoBit),
94 : kPerspective_InfoFlag = (1 << kPerspective_InfoBit),
95 : kLocalMatrix_InfoFlag = (1 << kLocalMatrix_InfoBit),
96 : kParamsIdx_InfoMask = (1 << kLocalMatrix_InfoBit) - 1
97 : };
98 :
99 : GR_STATIC_ASSERT((kNumShapeTypes - 1) <= (uint32_t)kShapeType_InfoMask >> kShapeType_InfoBit);
100 : GR_STATIC_ASSERT((int)ShapeType::kSimpleRRect <=
101 : kInnerShapeType_InfoMask >> kInnerShapeType_InfoBit);
102 :
103 : /**
104 : * Additional parameters required by some instances (e.g. round rect radii, perspective column,
105 : * local matrix). These are accessed via texel buffer.
106 : */
107 : struct ParamsTexel {
108 : float fX, fY, fZ, fW;
109 : };
110 :
111 : GR_STATIC_ASSERT(0 == offsetof(ParamsTexel, fX));
112 : GR_STATIC_ASSERT(4 * 4 == sizeof(ParamsTexel));
113 :
114 : /**
115 : * Tracks all information needed in order to draw a op of instances. This struct also serves
116 : * as an all-in-one shader key for the op.
117 : */
118 : struct OpInfo {
119 0 : OpInfo() : fData(0) {}
120 0 : explicit OpInfo(uint32_t data) : fData(data) {}
121 :
122 : static bool CanCombine(const OpInfo& a, const OpInfo& b);
123 :
124 0 : bool isSimpleRects() const {
125 0 : return !((fShapeTypes & ~kRect_ShapeFlag) | fInnerShapeTypes);
126 : }
127 :
128 0 : GrAAType aaType() const { return static_cast<GrAAType>(fAAType); }
129 0 : void setAAType(GrAAType aaType) { fAAType = static_cast<uint8_t>(aaType); }
130 :
131 : union {
132 : struct {
133 : uint8_t fAAType; // GrAAType
134 : uint8_t fShapeTypes;
135 : uint8_t fInnerShapeTypes;
136 : bool fHasPerspective : 1;
137 : bool fHasLocalMatrix : 1;
138 : bool fHasParams : 1;
139 : bool fNonSquare : 1;
140 : bool fUsesLocalCoords : 1;
141 : bool fCannotTweakAlphaForCoverage : 1;
142 : bool fCannotDiscard : 1;
143 : };
144 : uint32_t fData;
145 : };
146 : };
147 :
148 0 : inline bool OpInfo::CanCombine(const OpInfo& a, const OpInfo& b) {
149 0 : if (a.fAAType != b.fAAType) {
150 0 : return false;
151 : }
152 0 : if (SkToBool(a.fInnerShapeTypes) != SkToBool(b.fInnerShapeTypes)) {
153 : // GrInstanceProcessor can't currently combine draws with and without inner shapes.
154 0 : return false;
155 : }
156 0 : if (a.fCannotDiscard != b.fCannotDiscard) {
157 : // For stencil draws, the use of discard can be a requirement.
158 0 : return false;
159 : }
160 0 : return true;
161 : }
162 :
163 0 : inline OpInfo operator|(const OpInfo& a, const OpInfo& b) {
164 0 : SkASSERT(OpInfo::CanCombine(a, b));
165 0 : return OpInfo(a.fData | b.fData);
166 : }
167 :
168 : // This is required since all the data must fit into 32 bits of a shader key.
169 : GR_STATIC_ASSERT(sizeof(uint32_t) == sizeof(OpInfo));
170 : GR_STATIC_ASSERT(kNumShapeTypes <= 8);
171 :
172 : struct IndexRange {
173 0 : bool operator ==(const IndexRange& that) const {
174 0 : SkASSERT(fStart != that.fStart || fCount == that.fCount);
175 0 : return fStart == that.fStart;
176 : }
177 0 : bool operator !=(const IndexRange& that) const { return !(*this == that); }
178 :
179 0 : bool isEmpty() const { return fCount <= 0; }
180 : int end() { return fStart + fCount; }
181 :
182 : int16_t fStart;
183 : int16_t fCount;
184 : };
185 :
186 : }
187 :
188 : #endif
|