• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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