1/*
2 * Copyright 2014 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 GrShaderVar_DEFINED
9#define GrShaderVar_DEFINED
10
11#include "GrTypesPriv.h"
12#include "SkString.h"
13
14class GrShaderVar {
15public:
16    /**
17     * Early versions of GLSL have Varying and Attribute; those are later
18     * deprecated, but we still need to know whether a Varying variable
19     * should be treated as In or Out.
20     *
21     * TODO This really shouldn't live here, but until we have c++11, there is really no good way
22     * to write extensible enums.  In reality, only none, out, in, inout, and uniform really
23     * make sense on this base class
24     */
25    enum TypeModifier {
26        kNone_TypeModifier,
27        kOut_TypeModifier,
28        kIn_TypeModifier,
29        kInOut_TypeModifier,
30        kUniform_TypeModifier,
31        // GL Specific types below
32        kAttribute_TypeModifier,
33        kVaryingIn_TypeModifier,
34        kVaryingOut_TypeModifier
35    };
36
37    enum Precision {
38        kLow_Precision,         // lowp
39        kMedium_Precision,      // mediump
40        kHigh_Precision,        // highp
41        kDefault_Precision,     // Default for the current context. We make
42                                // fragment shaders default to mediump on ES2
43                                // because highp support is not guaranteed (and
44                                // we haven't been motivated to test for it).
45                                // Otherwise, highp.
46    };
47
48    /**
49     * Defaults to a float with no precision specifier
50     */
51    GrShaderVar()
52        : fType(kFloat_GrSLType)
53        , fTypeModifier(kNone_TypeModifier)
54        , fCount(kNonArray)
55        , fPrecision(kDefault_Precision) {
56    }
57
58    GrShaderVar(const SkString& name, GrSLType type, int arrayCount = kNonArray,
59                Precision precision = kDefault_Precision)
60        : fType(type)
61        , fTypeModifier(kNone_TypeModifier)
62        , fName(name)
63        , fCount(arrayCount)
64        , fPrecision(precision) {
65        SkASSERT(kVoid_GrSLType != type);
66    }
67
68    GrShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray,
69                  Precision precision = kDefault_Precision)
70        : fType(type)
71        , fTypeModifier(kNone_TypeModifier)
72        , fName(name)
73        , fCount(arrayCount)
74        , fPrecision(precision) {
75        SkASSERT(kVoid_GrSLType != type);
76    }
77
78    GrShaderVar(const char* name, GrSLType type, TypeModifier typeModifier,
79                  int arrayCount = kNonArray, Precision precision = kDefault_Precision)
80        : fType(type)
81        , fTypeModifier(typeModifier)
82        , fName(name)
83        , fCount(arrayCount)
84        , fPrecision(precision) {
85        SkASSERT(kVoid_GrSLType != type);
86    }
87
88    /**
89     * Values for array count that have special meaning. We allow 1-sized arrays.
90     */
91    enum {
92        kNonArray     =  0, // not an array
93        kUnsizedArray = -1, // an unsized array (declared with [])
94    };
95
96    /**
97     * Sets as a non-array.
98     */
99    void set(GrSLType type,
100             TypeModifier typeModifier,
101             const SkString& name,
102             Precision precision = kDefault_Precision) {
103        SkASSERT(kVoid_GrSLType != type);
104        fType = type;
105        fTypeModifier = typeModifier;
106        fName = name;
107        fCount = kNonArray;
108        fPrecision = precision;
109    }
110
111    /**
112     * Sets as a non-array.
113     */
114    void set(GrSLType type,
115             TypeModifier typeModifier,
116             const char* name,
117             Precision precision = kDefault_Precision) {
118        SkASSERT(kVoid_GrSLType != type);
119        fType = type;
120        fTypeModifier = typeModifier;
121        fName = name;
122        fCount = kNonArray;
123        fPrecision = precision;
124    }
125
126    /**
127     * Set all var options
128     */
129    void set(GrSLType type,
130             TypeModifier typeModifier,
131             const SkString& name,
132             int count,
133             Precision precision = kDefault_Precision) {
134        SkASSERT(kVoid_GrSLType != type);
135        fType = type;
136        fTypeModifier = typeModifier;
137        fName = name;
138        fCount = count;
139        fPrecision = precision;
140    }
141
142    /**
143     * Set all var options
144     */
145    void set(GrSLType type,
146             TypeModifier typeModifier,
147             const char* name,
148             int count,
149             Precision precision = kDefault_Precision) {
150        SkASSERT(kVoid_GrSLType != type);
151        fType = type;
152        fTypeModifier = typeModifier;
153        fName = name;
154        fCount = count;
155        fPrecision = precision;
156    }
157
158    /**
159     * Is the var an array.
160     */
161    bool isArray() const { return kNonArray != fCount; }
162    /**
163     * Is this an unsized array, (i.e. declared with []).
164     */
165    bool isUnsizedArray() const { return kUnsizedArray == fCount; }
166    /**
167     * Get the array length of the var.
168     */
169    int getArrayCount() const { return fCount; }
170    /**
171     * Set the array length of the var
172     */
173    void setArrayCount(int count) { fCount = count; }
174    /**
175     * Set to be a non-array.
176     */
177    void setNonArray() { fCount = kNonArray; }
178    /**
179     * Set to be an unsized array.
180     */
181    void setUnsizedArray() { fCount = kUnsizedArray; }
182
183    /**
184     * Access the var name as a writable string
185     */
186    SkString* accessName() { return &fName; }
187    /**
188     * Set the var name
189     */
190    void setName(const SkString& n) { fName = n; }
191    void setName(const char* n) { fName = n; }
192
193    /**
194     * Get the var name.
195     */
196    const SkString& getName() const { return fName; }
197
198    /**
199     * Shortcut for this->getName().c_str();
200     */
201    const char* c_str() const { return this->getName().c_str(); }
202
203    /**
204     * Get the type of the var
205     */
206    GrSLType getType() const { return fType; }
207    /**
208     * Set the type of the var
209     */
210    void setType(GrSLType type) { fType = type; }
211
212    TypeModifier getTypeModifier() const { return fTypeModifier; }
213    void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
214
215    /**
216     * Get the precision of the var
217     */
218    Precision getPrecision() const { return fPrecision; }
219
220    /**
221     * Set the precision of the var
222     */
223    void setPrecision(Precision p) { fPrecision = p; }
224
225protected:
226    GrSLType        fType;
227    TypeModifier    fTypeModifier;
228    SkString        fName;
229    int             fCount;
230    Precision       fPrecision;
231};
232
233#endif
234