Chromium Code Reviews| Index: src/gpu/instanced/InstancedRenderingTypes.h |
| diff --git a/src/gpu/instanced/InstancedRenderingTypes.h b/src/gpu/instanced/InstancedRenderingTypes.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ec50e909b963a35d7c21dfc436a61c5460b3bdf6 |
| --- /dev/null |
| +++ b/src/gpu/instanced/InstancedRenderingTypes.h |
| @@ -0,0 +1,192 @@ |
| +/* |
| + * Copyright 2016 Google Inc. |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| +#ifndef gr_instanced_InstancedRenderingTypes_DEFINED |
| +#define gr_instanced_InstancedRenderingTypes_DEFINED |
| + |
| +#include "GrTypes.h" |
| +#include "SkRRect.h" |
| + |
| +namespace gr_instanced { |
| + |
| +enum class AntialiasMode : uint8_t { |
| + kNone, |
| + kCoverage, |
| + kMSAA, |
| + kMixedSamples |
| +}; |
| +constexpr int kNumAntialiasModes = 1 + (int)AntialiasMode::kMixedSamples; |
| + |
| +enum class ShapeType : uint8_t { |
| + kRect, |
| + kOval, |
| + kSimpleRRect, |
| + kNinePatch, |
| + kComplexRRect |
| +}; |
| +constexpr int kNumShapeTypes = 1 + (int)ShapeType::kComplexRRect; |
| + |
| +inline static ShapeType GetRRectShapeType(const SkRRect& rrect) { |
| + SkASSERT(rrect.getType() >= SkRRect::kRect_Type && |
| + rrect.getType() <= SkRRect::kComplex_Type); |
| + return static_cast<ShapeType>(rrect.getType() - 1); |
| + |
| + GR_STATIC_ASSERT((int)ShapeType::kRect == SkRRect::kRect_Type - 1); |
| + GR_STATIC_ASSERT((int)ShapeType::kOval == SkRRect::kOval_Type - 1); |
| + GR_STATIC_ASSERT((int)ShapeType::kSimpleRRect == SkRRect::kSimple_Type - 1); |
| + GR_STATIC_ASSERT((int)ShapeType::kNinePatch == SkRRect::kNinePatch_Type - 1); |
| + GR_STATIC_ASSERT((int)ShapeType::kComplexRRect == SkRRect::kComplex_Type - 1); |
| + GR_STATIC_ASSERT(kNumShapeTypes == SkRRect::kComplex_Type); |
| +} |
| + |
| +/** |
| + * Per-vertex data. These values get fed into normal vertex attribs. |
| + */ |
| +struct ShapeVertex { |
| + float fX, fY; //!< Shape coordinates. |
| + int32_t fAttrs; //!< Shape-specific vertex attributes, if needed. |
| +}; |
| + |
| +template<typename T> struct TRange { |
| + bool operator ==(const TRange& that) const { |
| + return fStart == that.fStart && fCount == that.fCount; |
| + } |
| + bool operator !=(const TRange& that) const { return !(*this == that); } |
| + |
| + bool isEmpty() const { return fCount <= 0; } |
| + T end() { return fStart + fCount; } |
| + |
| + T fStart; |
| + T fCount; |
| +}; |
| + |
| +typedef TRange<int16_t> IndexRange; |
| +typedef TRange<int> InstanceRange; |
| + |
| +/** |
| + * Per-instance data. These values get fed into instanced vertex attribs. |
| + */ |
| +struct Instance { |
| + uint32_t fInfo; //!< Packed info about the instance. See InfoBits. |
| + float fShapeMatrix2x3[6]; //!< Maps canonical shape coords -> device space coords. |
| + uint32_t fColor; //!< Color to be written out by the primitive processor. |
| + float fLocalRect[4]; //!< Local coords rect that spans [-1, +1] in shape coords. |
| +}; |
| + |
| +/** |
| + * Additional parameters required by some instances (e.g. round rect radii, perspective column, |
| + * local matrix). These are accessed via texel buffer. |
| + */ |
| +struct ParamsTexel { |
| + float fX, fY, fZ, fW; |
| +}; |
| + |
| +GR_STATIC_ASSERT(0 == offsetof(ParamsTexel, fX)); |
| +GR_STATIC_ASSERT(4 * 4 == sizeof(ParamsTexel)); |
| + |
| +enum AttribIdx { |
|
bsalomon
2016/06/20 14:49:54
You could make these enum classes if you wanted. I
csmartdalton
2016/06/20 15:33:47
Yeah AttribIdx should be made into an enum class w
|
| + kShapeCoords_AttribIdx, |
| + kVertexAttrs_AttribIdx, |
| + kInstanceInfo_AttribIdx, |
| + kShapeMatrixX_AttribIdx, |
| + kShapeMatrixY_AttribIdx, |
| + kColor_AttribIdx, |
| + kLocalRect_AttribIdx, |
| + |
| + kNumVertexAttribs |
| +}; |
| + |
| +enum ShapeFlag { |
| + kRect_ShapeFlag = (1 << (int)ShapeType::kRect), |
| + kOval_ShapeFlag = (1 << (int)ShapeType::kOval), |
| + kSimpleRRect_ShapeFlag = (1 << (int)ShapeType::kSimpleRRect), |
| + kNinePatch_ShapeFlag = (1 << (int)ShapeType::kNinePatch), |
| + kComplexRRect_ShapeFlag = (1 << (int)ShapeType::kComplexRRect), |
| + |
| + kRRect_ShapesMask = kSimpleRRect_ShapeFlag | kNinePatch_ShapeFlag | kComplexRRect_ShapeFlag |
| +}; |
| + |
| +constexpr uint8_t GetShapeFlag(ShapeType type) { return 1 << (int)type; } |
| + |
| +/** |
| + * Defines what data is stored at which bits in the fInfo field of the instanced data. |
| + */ |
| +enum InfoBits { |
| + kShapeType_InfoBit = 29, |
| + kInnerShapeType_InfoBit = 27, |
| + kPerspective_InfoBit = 26, |
| + kLocalMatrix_InfoBit = 25, |
| + kParamsIdx_InfoBit = 0 |
| +}; |
| + |
| +enum InfoMasks { |
| + kShapeType_InfoMask = 0u - (1 << kShapeType_InfoBit), |
| + kInnerShapeType_InfoMask = (1 << kShapeType_InfoBit) - (1 << kInnerShapeType_InfoBit), |
| + kPerspective_InfoFlag = (1 << kPerspective_InfoBit), |
| + kLocalMatrix_InfoFlag = (1 << kLocalMatrix_InfoBit), |
| + kParamsIdx_InfoMask = (1 << kLocalMatrix_InfoBit) - 1 |
| +}; |
| + |
| +GR_STATIC_ASSERT((kNumShapeTypes - 1) <= (uint32_t)kShapeType_InfoMask >> kShapeType_InfoBit); |
| +GR_STATIC_ASSERT((int)ShapeType::kSimpleRRect <= |
| + kInnerShapeType_InfoMask >> kInnerShapeType_InfoBit); |
| + |
| +/** |
| + * Tracks all information needed in order to draw a batch of instances. This struct also serves |
| + * as an all-in-one shader key for the batch. |
| + */ |
| +struct BatchInfo { |
| + BatchInfo() : fData(0) {} |
| + |
| + bool isSimpleRects() const { |
| + return !((fShapeTypes & ~kRect_ShapeFlag) | fInnerShapeTypes); |
| + } |
| + |
| + bool canJoin(BatchInfo that) const { |
| + if (fAntialiasMode != that.fAntialiasMode) { |
| + return false; |
| + } |
| + if (SkToBool(fInnerShapeTypes) != SkToBool(that.fInnerShapeTypes)) { |
| + // GrInstanceProcessor can't currently combine draws with and without inner shapes. |
| + return false; |
| + } |
| + if (fCannotDiscard != that.fCannotDiscard) { |
| + // For stencil draws, the use of discard can be a requirement. |
| + return false; |
| + } |
| + return true; |
| + } |
| + |
| + void join(BatchInfo that) { |
| + SkASSERT(this->canJoin(that)); |
| + fData |= that.fData; |
| + } |
| + |
| + union { |
| + struct { |
| + AntialiasMode fAntialiasMode; |
| + uint8_t fShapeTypes; |
| + uint8_t fInnerShapeTypes; |
| + bool fHasPerspective : 1; |
| + bool fHasLocalMatrix : 1; |
| + bool fHasParams : 1; |
| + bool fNonSquare : 1; |
| + bool fUsesLocalCoords : 1; |
| + bool fCannotTweakAlphaForCoverage : 1; |
| + bool fCannotDiscard : 1; |
| + }; |
| + uint32_t fData; |
| + }; |
| +}; |
| + |
| +// This is required since all the data must fit into 32 bits of a shader key. |
| +GR_STATIC_ASSERT(sizeof(uint32_t) == sizeof(BatchInfo)); |
| +GR_STATIC_ASSERT(kNumShapeTypes <= 8); |
| + |
| +} |
| + |
| +#endif |