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
GetRRectShapeType(const SkRRect & rrect)55 inline static ShapeType GetRRectShapeType(const SkRRect& rrect) {
56 SkASSERT(rrect.getType() >= SkRRect::kRect_Type &&
57 rrect.getType() <= SkRRect::kComplex_Type);
58 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
GetShapeFlag(ShapeType type)78 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 {
OpInfoOpInfo119 OpInfo() : fData(0) {}
OpInfoOpInfo120 explicit OpInfo(uint32_t data) : fData(data) {}
121
122 static bool CanCombine(const OpInfo& a, const OpInfo& b);
123
isSimpleRectsOpInfo124 bool isSimpleRects() const {
125 return !((fShapeTypes & ~kRect_ShapeFlag) | fInnerShapeTypes);
126 }
127
aaTypeOpInfo128 GrAAType aaType() const { return static_cast<GrAAType>(fAAType); }
setAATypeOpInfo129 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
CanCombine(const OpInfo & a,const OpInfo & b)148 inline bool OpInfo::CanCombine(const OpInfo& a, const OpInfo& b) {
149 if (a.fAAType != b.fAAType) {
150 return false;
151 }
152 if (SkToBool(a.fInnerShapeTypes) != SkToBool(b.fInnerShapeTypes)) {
153 // GrInstanceProcessor can't currently combine draws with and without inner shapes.
154 return false;
155 }
156 if (a.fCannotDiscard != b.fCannotDiscard) {
157 // For stencil draws, the use of discard can be a requirement.
158 return false;
159 }
160 return true;
161 }
162
163 inline OpInfo operator|(const OpInfo& a, const OpInfo& b) {
164 SkASSERT(OpInfo::CanCombine(a, b));
165 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 bool operator ==(const IndexRange& that) const {
174 SkASSERT(fStart != that.fStart || fCount == that.fCount);
175 return fStart == that.fStart;
176 }
177 bool operator !=(const IndexRange& that) const { return !(*this == that); }
178
isEmptyIndexRange179 bool isEmpty() const { return fCount <= 0; }
endIndexRange180 int end() { return fStart + fCount; }
181
182 int16_t fStart;
183 int16_t fCount;
184 };
185
186 }
187
188 #endif
189