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 15namespace gr_instanced { 16 17/** 18 * Per-vertex data. These values get fed into normal vertex attribs. 19 */ 20struct 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 */ 28struct 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 35enum class Attrib : uint8_t { 36 kShapeCoords, 37 kVertexAttrs, 38 kInstanceInfo, 39 kShapeMatrixX, 40 kShapeMatrixY, 41 kColor, 42 kLocalRect 43}; 44constexpr int kNumAttribs = 1 + (int)Attrib::kLocalRect; 45 46enum class ShapeType : uint8_t { 47 kRect, 48 kOval, 49 kSimpleRRect, 50 kNinePatch, 51 kComplexRRect 52}; 53constexpr int kNumShapeTypes = 1 + (int)ShapeType::kComplexRRect; 54 55inline 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 68enum 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 78constexpr 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 */ 83enum InfoBits { 84 kShapeType_InfoBit = 29, 85 kInnerShapeType_InfoBit = 27, 86 kPerspective_InfoBit = 26, 87 kLocalMatrix_InfoBit = 25, 88 kParamsIdx_InfoBit = 0 89}; 90 91enum 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 99GR_STATIC_ASSERT((kNumShapeTypes - 1) <= (uint32_t)kShapeType_InfoMask >> kShapeType_InfoBit); 100GR_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 */ 107struct ParamsTexel { 108 float fX, fY, fZ, fW; 109}; 110 111GR_STATIC_ASSERT(0 == offsetof(ParamsTexel, fX)); 112GR_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 */ 118struct OpInfo { 119 OpInfo() : fData(0) {} 120 explicit OpInfo(uint32_t data) : fData(data) {} 121 122 static bool CanCombine(const OpInfo& a, const OpInfo& b); 123 124 bool isSimpleRects() const { 125 return !((fShapeTypes & ~kRect_ShapeFlag) | fInnerShapeTypes); 126 } 127 128 GrAAType aaType() const { return static_cast<GrAAType>(fAAType); } 129 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 148inline 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 163inline 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. 169GR_STATIC_ASSERT(sizeof(uint32_t) == sizeof(OpInfo)); 170GR_STATIC_ASSERT(kNumShapeTypes <= 8); 171 172struct 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 179 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 189