• 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                   Precision precision = kDefault_Precision)
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, Precision precision = kDefault_Precision)
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              Precision precision = kDefault_Precision,
87              Origin origin = kDefault_Origin,
88              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
89         SkASSERT(kVoid_GrSLType != type);
90         INHERITED::set(type, typeModifier, name, precision);
91         fOrigin = origin;
92         fUseUniformFloatArrays = useUniformFloatArrays;
93     }
94 
95     /**
96      * Sets as a non-array.
97      */
98     void set(GrSLType type,
99              TypeModifier typeModifier,
100              const char* name,
101              Precision precision = kDefault_Precision,
102              Origin origin = kDefault_Origin,
103              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
104         SkASSERT(kVoid_GrSLType != type);
105         INHERITED::set(type, typeModifier, name, precision);
106         fOrigin = origin;
107         fUseUniformFloatArrays = useUniformFloatArrays;
108     }
109 
110     /**
111      * Set all var options
112      */
113     void set(GrSLType type,
114              TypeModifier typeModifier,
115              const SkString& name,
116              int count,
117              Precision precision = kDefault_Precision,
118              Origin origin = kDefault_Origin,
119              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
120         SkASSERT(kVoid_GrSLType != type);
121         INHERITED::set(type, typeModifier, name, count, precision);
122         fOrigin = origin;
123         fUseUniformFloatArrays = useUniformFloatArrays;
124     }
125 
126     /**
127      * Set all var options
128      */
129     void set(GrSLType type,
130              TypeModifier typeModifier,
131              const char* name,
132              int count,
133              Precision precision = kDefault_Precision,
134              Origin origin = kDefault_Origin,
135              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
136         SkASSERT(kVoid_GrSLType != type);
137         INHERITED::set(type, typeModifier, name, count, precision);
138         fOrigin = origin;
139         fUseUniformFloatArrays = useUniformFloatArrays;
140     }
141 
142     /**
143      * Get the origin of the var
144      */
getOrigin()145     Origin getOrigin() const { return fOrigin; }
146 
147     /**
148      * Set the origin of the var
149      */
setOrigin(Origin origin)150     void setOrigin(Origin origin) { fOrigin = origin; }
151 
152     /**
153      * Write a declaration of this variable to out.
154      */
appendDecl(const GrGLContextInfo & ctxInfo,SkString * out)155     void appendDecl(const GrGLContextInfo& ctxInfo, SkString* out) const {
156         if (kUpperLeft_Origin == fOrigin) {
157             // this is the only place where we specify a layout modifier. If we use other layout
158             // modifiers in the future then they should be placed in a list.
159             out->append("layout(origin_upper_left) ");
160         }
161         if (this->getTypeModifier() != kNone_TypeModifier) {
162            out->append(TypeModifierString(this->getTypeModifier(),
163                                           ctxInfo.glslGeneration()));
164            out->append(" ");
165         }
166         out->append(PrecisionString(fPrecision, ctxInfo.standard()));
167         GrSLType effectiveType = this->getType();
168         if (this->isArray()) {
169             if (this->isUnsizedArray()) {
170                 out->appendf("%s %s[]",
171                              GrGLSLTypeString(effectiveType),
172                              this->getName().c_str());
173             } else {
174                 SkASSERT(this->getArrayCount() > 0);
175                 out->appendf("%s %s[%d]",
176                              GrGLSLTypeString(effectiveType),
177                              this->getName().c_str(),
178                              this->getArrayCount());
179             }
180         } else {
181             out->appendf("%s %s",
182                          GrGLSLTypeString(effectiveType),
183                          this->getName().c_str());
184         }
185     }
186 
appendArrayAccess(int index,SkString * out)187     void appendArrayAccess(int index, SkString* out) const {
188         out->appendf("%s[%d]%s",
189                      this->getName().c_str(),
190                      index,
191                      fUseUniformFloatArrays ? "" : ".x");
192     }
193 
appendArrayAccess(const char * indexName,SkString * out)194     void appendArrayAccess(const char* indexName, SkString* out) const {
195         out->appendf("%s[%s]%s",
196                      this->getName().c_str(),
197                      indexName,
198                      fUseUniformFloatArrays ? "" : ".x");
199     }
200 
PrecisionString(Precision p,GrGLStandard standard)201     static const char* PrecisionString(Precision p, GrGLStandard standard) {
202         // Desktop GLSL has added precision qualifiers but they don't do anything.
203         if (kGLES_GrGLStandard == standard) {
204             switch (p) {
205                 case kLow_Precision:
206                     return "lowp ";
207                 case kMedium_Precision:
208                     return "mediump ";
209                 case kHigh_Precision:
210                     return "highp ";
211                 case kDefault_Precision:
212                     return "";
213                 default:
214                     SkFAIL("Unexpected precision type.");
215             }
216         }
217         return "";
218     }
219 
220 private:
TypeModifierString(TypeModifier t,GrGLSLGeneration gen)221     static const char* TypeModifierString(TypeModifier t, GrGLSLGeneration gen) {
222         switch (t) {
223             case kNone_TypeModifier:
224                 return "";
225             case kIn_TypeModifier:
226                 return "in";
227             case kInOut_TypeModifier:
228                 return "inout";
229             case kOut_TypeModifier:
230                 return "out";
231             case kUniform_TypeModifier:
232                 return "uniform";
233             case kAttribute_TypeModifier:
234                 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
235             case kVaryingIn_TypeModifier:
236                 return k110_GrGLSLGeneration == gen ? "varying" : "in";
237             case kVaryingOut_TypeModifier:
238                 return k110_GrGLSLGeneration == gen ? "varying" : "out";
239             default:
240                 SkFAIL("Unknown shader variable type modifier.");
241                 return ""; // suppress warning
242         }
243     }
244 
245     Origin          fOrigin;
246     /// Work around driver bugs on some hardware that don't correctly
247     /// support uniform float []
248     bool            fUseUniformFloatArrays;
249 
250     typedef GrShaderVar INHERITED;
251 };
252 
253 #endif
254