• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2011 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 GrGLShaderVar_DEFINED
9 #define GrGLShaderVar_DEFINED
10 
11 #include "GrGLContext.h"
12 #include "GrGLSL.h"
13 #include "GrShaderVar.h"
14 
15 #define USE_UNIFORM_FLOAT_ARRAYS true
16 
17 /**
18  * Represents a variable in a shader
19  */
20 class GrGLShaderVar : public GrShaderVar {
21 public:
22     /**
23      * See GL_ARB_fragment_coord_conventions.
24      */
25     enum Origin {
26         kDefault_Origin,        // when set to kDefault the origin field is ignored.
27         kUpperLeft_Origin,      // only used to declare vec4 in gl_FragCoord.
28     };
29 
30     /**
31      * Defaults to a float with no precision specifier
32      */
GrGLShaderVar()33     GrGLShaderVar()
34         : GrShaderVar()
35         , fOrigin(kDefault_Origin)
36         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
37     }
38 
39     GrGLShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray,
40                   GrSLPrecision precision = kDefault_GrSLPrecision)
GrShaderVar(name,type,arrayCount,precision)41         : GrShaderVar(name, type, arrayCount, precision)
42         , fOrigin(kDefault_Origin)
43         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
44         SkASSERT(kVoid_GrSLType != type);
45         fOrigin = kDefault_Origin;
46         fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
47     }
48 
49     GrGLShaderVar(const char* name, GrSLType type, TypeModifier typeModifier,
50                   int arrayCount = kNonArray, GrSLPrecision precision = kDefault_GrSLPrecision)
GrShaderVar(name,type,typeModifier,arrayCount,precision)51         : GrShaderVar(name, type, typeModifier, arrayCount, precision)
52         , fOrigin(kDefault_Origin)
53         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
54         SkASSERT(kVoid_GrSLType != type);
55     }
56 
GrGLShaderVar(const GrShaderVar & var)57     GrGLShaderVar(const GrShaderVar& var)
58         : GrShaderVar(var)
59         , fOrigin(kDefault_Origin)
60         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
61         SkASSERT(kVoid_GrSLType != var.getType());
62     }
63 
GrGLShaderVar(const GrGLShaderVar & var)64     GrGLShaderVar(const GrGLShaderVar& var)
65         : GrShaderVar(var.c_str(), var.getType(), var.getTypeModifier(),
66                       var.getArrayCount(), var.getPrecision())
67         , fOrigin(var.fOrigin)
68         , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {
69         SkASSERT(kVoid_GrSLType != var.getType());
70     }
71 
72     /**
73      * Values for array count that have special meaning. We allow 1-sized arrays.
74      */
75     enum {
76         kNonArray     =  0, // not an array
77         kUnsizedArray = -1, // an unsized array (declared with [])
78     };
79 
80     /**
81      * Sets as a non-array.
82      */
83     void set(GrSLType type,
84              TypeModifier typeModifier,
85              const SkString& name,
86              GrSLPrecision precision = kDefault_GrSLPrecision,
87              Origin origin = kDefault_Origin,
88              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
89         SkASSERT(kVoid_GrSLType != type);
90         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsFloatType(type));
91         INHERITED::set(type, name, typeModifier, precision);
92         fOrigin = origin;
93         fUseUniformFloatArrays = useUniformFloatArrays;
94     }
95 
96     /**
97      * Sets as a non-array.
98      */
99     void set(GrSLType type,
100              TypeModifier typeModifier,
101              const char* name,
102              GrSLPrecision precision = kDefault_GrSLPrecision,
103              Origin origin = kDefault_Origin,
104              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
105         SkASSERT(kVoid_GrSLType != type);
106         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsFloatType(type));
107         INHERITED::set(type, name, typeModifier, precision);
108         fOrigin = origin;
109         fUseUniformFloatArrays = useUniformFloatArrays;
110     }
111 
112     /**
113      * Set all var options
114      */
115     void set(GrSLType type,
116              TypeModifier typeModifier,
117              const SkString& name,
118              int count,
119              GrSLPrecision precision = kDefault_GrSLPrecision,
120              Origin origin = kDefault_Origin,
121              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
122         SkASSERT(kVoid_GrSLType != type);
123         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsFloatType(type));
124         INHERITED::set(type, name, typeModifier, precision, count);
125         fOrigin = origin;
126         fUseUniformFloatArrays = useUniformFloatArrays;
127     }
128 
129     /**
130      * Set all var options
131      */
132     void set(GrSLType type,
133              TypeModifier typeModifier,
134              const char* name,
135              int count,
136              GrSLPrecision precision = kDefault_GrSLPrecision,
137              Origin origin = kDefault_Origin,
138              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
139         SkASSERT(kVoid_GrSLType != type);
140         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsFloatType(type));
141         INHERITED::set(type, name, typeModifier, precision, count);
142         fOrigin = origin;
143         fUseUniformFloatArrays = useUniformFloatArrays;
144     }
145 
146     /**
147      * Get the origin of the var
148      */
getOrigin()149     Origin getOrigin() const { return fOrigin; }
150 
151     /**
152      * Set the origin of the var
153      */
setOrigin(Origin origin)154     void setOrigin(Origin origin) { fOrigin = origin; }
155 
156     /**
157      * Write a declaration of this variable to out.
158      */
appendDecl(const GrGLContextInfo & ctxInfo,SkString * out)159     void appendDecl(const GrGLContextInfo& ctxInfo, SkString* out) const {
160         SkASSERT(kDefault_GrSLPrecision == fPrecision || GrSLTypeIsFloatType(fType));
161         if (kUpperLeft_Origin == fOrigin) {
162             // this is the only place where we specify a layout modifier. If we use other layout
163             // modifiers in the future then they should be placed in a list.
164             out->append("layout(origin_upper_left) ");
165         }
166         if (this->getTypeModifier() != kNone_TypeModifier) {
167            out->append(TypeModifierString(this->getTypeModifier(), ctxInfo.glslGeneration()));
168            out->append(" ");
169         }
170         out->append(PrecisionString(fPrecision, ctxInfo.standard()));
171         GrSLType effectiveType = this->getType();
172         if (this->isArray()) {
173             if (this->isUnsizedArray()) {
174                 out->appendf("%s %s[]",
175                              GrGLSLTypeString(effectiveType),
176                              this->getName().c_str());
177             } else {
178                 SkASSERT(this->getArrayCount() > 0);
179                 out->appendf("%s %s[%d]",
180                              GrGLSLTypeString(effectiveType),
181                              this->getName().c_str(),
182                              this->getArrayCount());
183             }
184         } else {
185             out->appendf("%s %s",
186                          GrGLSLTypeString(effectiveType),
187                          this->getName().c_str());
188         }
189     }
190 
appendArrayAccess(int index,SkString * out)191     void appendArrayAccess(int index, SkString* out) const {
192         out->appendf("%s[%d]%s",
193                      this->getName().c_str(),
194                      index,
195                      fUseUniformFloatArrays ? "" : ".x");
196     }
197 
appendArrayAccess(const char * indexName,SkString * out)198     void appendArrayAccess(const char* indexName, SkString* out) const {
199         out->appendf("%s[%s]%s",
200                      this->getName().c_str(),
201                      indexName,
202                      fUseUniformFloatArrays ? "" : ".x");
203     }
204 
PrecisionString(GrSLPrecision p,GrGLStandard standard)205     static const char* PrecisionString(GrSLPrecision p, GrGLStandard standard) {
206         // Desktop GLSL has added precision qualifiers but they don't do anything.
207         if (kGLES_GrGLStandard == standard) {
208             switch (p) {
209                 case kLow_GrSLPrecision:
210                     return "lowp ";
211                 case kMedium_GrSLPrecision:
212                     return "mediump ";
213                 case kHigh_GrSLPrecision:
214                     return "highp ";
215                 default:
216                     SkFAIL("Unexpected precision type.");
217             }
218         }
219         return "";
220     }
221 
222 private:
TypeModifierString(TypeModifier t,GrGLSLGeneration gen)223     static const char* TypeModifierString(TypeModifier t, GrGLSLGeneration gen) {
224         switch (t) {
225             case kNone_TypeModifier:
226                 return "";
227             case kIn_TypeModifier:
228                 return "in";
229             case kInOut_TypeModifier:
230                 return "inout";
231             case kOut_TypeModifier:
232                 return "out";
233             case kUniform_TypeModifier:
234                 return "uniform";
235             case kAttribute_TypeModifier:
236                 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
237             case kVaryingIn_TypeModifier:
238                 return k110_GrGLSLGeneration == gen ? "varying" : "in";
239             case kVaryingOut_TypeModifier:
240                 return k110_GrGLSLGeneration == gen ? "varying" : "out";
241             default:
242                 SkFAIL("Unknown shader variable type modifier.");
243                 return ""; // suppress warning
244         }
245     }
246 
247     Origin          fOrigin;
248     /// Work around driver bugs on some hardware that don't correctly
249     /// support uniform float []
250     bool            fUseUniformFloatArrays;
251 
252     typedef GrShaderVar INHERITED;
253 };
254 
255 #endif
256