1/*
2 * Copyright 2013 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 GrTypesPriv_DEFINED
9#define GrTypesPriv_DEFINED
10
11#include "GrTypes.h"
12#include "SkTArray.h"
13
14/**
15 * Types of shader-language-specific boxed variables we can create. (Currently only GrGLShaderVars,
16 * but should be applicable to other shader languages.)
17 */
18enum GrSLType {
19    kVoid_GrSLType,
20    kFloat_GrSLType,
21    kVec2f_GrSLType,
22    kVec3f_GrSLType,
23    kVec4f_GrSLType,
24    kMat33f_GrSLType,
25    kMat44f_GrSLType,
26    kSampler2D_GrSLType,
27
28    kLast_GrSLType = kSampler2D_GrSLType
29};
30static const int kGrSLTypeCount = kLast_GrSLType + 1;
31
32/**
33 * Gets the vector size of the SLType. Returns -1 for void, matrices, and samplers.
34 */
35static inline int GrSLTypeVectorCount(GrSLType type) {
36    SkASSERT(type >= 0 && type < static_cast<GrSLType>(kGrSLTypeCount));
37    static const int kCounts[] = { -1, 1, 2, 3, 4, -1, -1, -1 };
38    return kCounts[type];
39
40    GR_STATIC_ASSERT(0 == kVoid_GrSLType);
41    GR_STATIC_ASSERT(1 == kFloat_GrSLType);
42    GR_STATIC_ASSERT(2 == kVec2f_GrSLType);
43    GR_STATIC_ASSERT(3 == kVec3f_GrSLType);
44    GR_STATIC_ASSERT(4 == kVec4f_GrSLType);
45    GR_STATIC_ASSERT(5 == kMat33f_GrSLType);
46    GR_STATIC_ASSERT(6 == kMat44f_GrSLType);
47    GR_STATIC_ASSERT(7 == kSampler2D_GrSLType);
48    GR_STATIC_ASSERT(SK_ARRAY_COUNT(kCounts) == kGrSLTypeCount);
49}
50
51/** Return the type enum for a vector of floats of length n (1..4),
52 e.g. 1 -> kFloat_GrSLType, 2 -> kVec2_GrSLType, ... */
53static inline GrSLType GrSLFloatVectorType(int count) {
54    SkASSERT(count > 0 && count <= 4);
55    return (GrSLType)(count);
56
57    GR_STATIC_ASSERT(kFloat_GrSLType == 1);
58    GR_STATIC_ASSERT(kVec2f_GrSLType == 2);
59    GR_STATIC_ASSERT(kVec3f_GrSLType == 3);
60    GR_STATIC_ASSERT(kVec4f_GrSLType == 4);
61}
62
63//////////////////////////////////////////////////////////////////////////////
64
65/**
66 * Types used to describe format of vertices in arrays.
67  */
68enum GrVertexAttribType {
69    kFloat_GrVertexAttribType = 0,
70    kVec2f_GrVertexAttribType,
71    kVec3f_GrVertexAttribType,
72    kVec4f_GrVertexAttribType,
73    kVec4ub_GrVertexAttribType,   // vector of 4 unsigned bytes, e.g. colors
74
75    kLast_GrVertexAttribType = kVec4ub_GrVertexAttribType
76};
77static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
78
79/**
80 * Returns the vector size of the type.
81 */
82static inline int GrVertexAttribTypeVectorCount(GrVertexAttribType type) {
83    SkASSERT(type >= 0 && type < kGrVertexAttribTypeCount);
84    static const int kCounts[] = { 1, 2, 3, 4, 4 };
85    return kCounts[type];
86
87    GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
88    GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
89    GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
90    GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
91    GR_STATIC_ASSERT(4 == kVec4ub_GrVertexAttribType);
92    GR_STATIC_ASSERT(SK_ARRAY_COUNT(kCounts) == kGrVertexAttribTypeCount);
93}
94
95/**
96 * Returns the size of the attrib type in bytes.
97 */
98static inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
99    SkASSERT(type >= 0 && type < kGrVertexAttribTypeCount);
100    static const size_t kSizes[] = {
101        sizeof(float),          // kFloat_GrVertexAttribType
102        2*sizeof(float),        // kVec2f_GrVertexAttribType
103        3*sizeof(float),        // kVec3f_GrVertexAttribType
104        4*sizeof(float),        // kVec4f_GrVertexAttribType
105        4*sizeof(char)          // kVec4ub_GrVertexAttribType
106    };
107    return kSizes[type];
108
109    GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
110    GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
111    GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
112    GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
113    GR_STATIC_ASSERT(4 == kVec4ub_GrVertexAttribType);
114    GR_STATIC_ASSERT(SK_ARRAY_COUNT(kSizes) == kGrVertexAttribTypeCount);
115}
116
117/**
118 * Semantic bindings for vertex attributes. kEffect means that the attribute is input to a GrEffect.
119 * Each binding other than kEffect may not appear more than once in the current set of attributes.
120 * kPosition must be appear for exactly one attribute.
121 */
122enum GrVertexAttribBinding {
123    kPosition_GrVertexAttribBinding,    // required, must have vector count of 2
124    kLocalCoord_GrVertexAttribBinding,  // must have vector count of 2
125    kColor_GrVertexAttribBinding,       // must have vector count of 4
126    kCoverage_GrVertexAttribBinding,    // must have vector count of 4
127
128    kLastFixedFunction_GrVertexAttribBinding = kCoverage_GrVertexAttribBinding,
129
130    kEffect_GrVertexAttribBinding,      // vector length must agree with
131                                        // GrEffect::vertexAttribType() for each effect input to
132                                        // which the attribute is mapped by GrDrawState::setEffect()
133    kLast_GrVertexAttribBinding = kEffect_GrVertexAttribBinding
134};
135
136static const int kGrVertexAttribBindingCnt = kLast_GrVertexAttribBinding + 1;
137static const int kGrFixedFunctionVertexAttribBindingCnt =
138    kLastFixedFunction_GrVertexAttribBinding + 1;
139
140static inline int GrFixedFunctionVertexAttribVectorCount(GrVertexAttribBinding binding) {
141    SkASSERT(binding >= 0 && binding < kGrFixedFunctionVertexAttribBindingCnt);
142    static const int kVecCounts[] = { 2, 2, 4, 4 };
143
144    return kVecCounts[binding];
145
146    GR_STATIC_ASSERT(0 == kPosition_GrVertexAttribBinding);
147    GR_STATIC_ASSERT(1 == kLocalCoord_GrVertexAttribBinding);
148    GR_STATIC_ASSERT(2 == kColor_GrVertexAttribBinding);
149    GR_STATIC_ASSERT(3 == kCoverage_GrVertexAttribBinding);
150    GR_STATIC_ASSERT(kGrFixedFunctionVertexAttribBindingCnt == SK_ARRAY_COUNT(kVecCounts));
151}
152
153struct GrVertexAttrib {
154    inline void set(GrVertexAttribType type, size_t offset, GrVertexAttribBinding binding) {
155        fType = type;
156        fOffset = offset;
157        fBinding = binding;
158    }
159    bool operator==(const GrVertexAttrib& other) const {
160        return fType == other.fType && fOffset == other.fOffset && fBinding == other.fBinding;
161    };
162    bool operator!=(const GrVertexAttrib& other) const { return !(*this == other); }
163
164    GrVertexAttribType      fType;
165    size_t                  fOffset;
166    GrVertexAttribBinding   fBinding;
167};
168
169template <int N> class GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
170
171//////////////////////////////////////////////////////////////////////////////
172
173/**
174* We have coverage effects that clip rendering to the edge of some geometric primitive.
175* This enum specifies how that clipping is performed. Not all factories that take a
176* GrEffectEdgeType will succeed with all values and it is up to the caller to check for
177* a NULL return.
178*/
179enum GrEffectEdgeType {
180    kFillBW_GrEffectEdgeType,
181    kFillAA_GrEffectEdgeType,
182    kInverseFillBW_GrEffectEdgeType,
183    kInverseFillAA_GrEffectEdgeType,
184    kHairlineAA_GrEffectEdgeType,
185
186    kLast_GrEffectEdgeType = kHairlineAA_GrEffectEdgeType
187};
188
189static const int kGrEffectEdgeTypeCnt = kLast_GrEffectEdgeType + 1;
190
191static inline bool GrEffectEdgeTypeIsFill(const GrEffectEdgeType edgeType) {
192    return (kFillAA_GrEffectEdgeType == edgeType || kFillBW_GrEffectEdgeType == edgeType);
193}
194
195static inline bool GrEffectEdgeTypeIsInverseFill(const GrEffectEdgeType edgeType) {
196    return (kInverseFillAA_GrEffectEdgeType == edgeType ||
197            kInverseFillBW_GrEffectEdgeType == edgeType);
198}
199
200static inline bool GrEffectEdgeTypeIsAA(const GrEffectEdgeType edgeType) {
201    return (kFillBW_GrEffectEdgeType != edgeType && kInverseFillBW_GrEffectEdgeType != edgeType);
202}
203
204static inline GrEffectEdgeType GrInvertEffectEdgeType(const GrEffectEdgeType edgeType) {
205    switch (edgeType) {
206        case kFillBW_GrEffectEdgeType:
207            return kInverseFillBW_GrEffectEdgeType;
208        case kFillAA_GrEffectEdgeType:
209            return kInverseFillAA_GrEffectEdgeType;
210        case kInverseFillBW_GrEffectEdgeType:
211            return kFillBW_GrEffectEdgeType;
212        case kInverseFillAA_GrEffectEdgeType:
213            return kFillAA_GrEffectEdgeType;
214        case kHairlineAA_GrEffectEdgeType:
215            SkFAIL("Hairline fill isn't invertible.");
216    }
217    return kFillAA_GrEffectEdgeType; // suppress warning.
218}
219
220#endif
221