blob: 8eba7140c9c17bba863cf9b15b8572d9d9ee3916 [file] [log] [blame]
bsalomon@google.com4fa66942011-09-20 19:06:12 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#ifndef GrGLShaderVar_DEFINED
10#define GrGLShaderVar_DEFINED
11
12#include "GrGLInterface.h"
bsalomon@google.comffa11bb2011-10-20 13:43:13 +000013#include "GrStringBuilder.h"
bsalomon@google.com4fa66942011-09-20 19:06:12 +000014
15/**
16 * Represents a variable in a shader
17 */
18class GrGLShaderVar {
19public:
20
21 enum Type {
22 kFloat_Type,
23 kVec2f_Type,
24 kVec3f_Type,
25 kVec4f_Type,
26 kMat33f_Type,
27 kSampler2D_Type,
28 };
29
30 /**
31 * Defaults to a float with no precision specifier
32 */
33 GrGLShaderVar() {
34 fType = kFloat_Type;
35 fCount = kNonArray;
36 fEmitPrecision = false;
37 }
38
39 GrGLShaderVar(const GrGLShaderVar& var)
40 : fType(var.fType)
41 , fName(var.fName)
42 , fCount(var.fCount)
43 , fEmitPrecision(var.fEmitPrecision) {}
44
45 /**
46 * Values for array count that have special meaning. We allow 1-sized arrays.
47 */
48 enum {
49 kNonArray = 0, // not an array
50 kUnsizedArray = -1, // an unsized array (declared with [])
51 };
52
53 /**
54 * Sets as a non-array.
55 */
56 void set(Type type,
57 const GrStringBuilder& name,
58 bool emitPrecision = false) {
59 fType = type;
60 fName = name;
61 fCount = kNonArray;
62 fEmitPrecision = emitPrecision;
63 }
64
65 /**
66 * Sets as a non-array.
67 */
68 void set(Type type,
69 const char* name,
70 bool specifyPrecision = false) {
71 fType = type;
72 fName = name;
73 fCount = kNonArray;
74 fEmitPrecision = specifyPrecision;
75 }
76
77 /**
78 * Set all var options
79 */
80 void set(Type type,
81 const GrStringBuilder& name,
82 int count,
83 bool specifyPrecision = false) {
84 fType = type;
85 fName = name;
86 fCount = count;
87 fEmitPrecision = specifyPrecision;
88 }
89
90 /**
91 * Set all var options
92 */
93 void set(Type type,
94 const char* name,
95 int count,
96 bool specifyPrecision = false) {
97 fType = type;
98 fName = name;
99 fCount = count;
100 fEmitPrecision = specifyPrecision;
101 }
102
103 /**
104 * Is the var an array.
105 */
106 bool isArray() const { return kNonArray != fCount; }
107 /**
108 * Is this an unsized array, (i.e. declared with []).
109 */
110 bool isUnsizedArray() const { return kUnsizedArray == fCount; }
111 /**
112 * Get the array length of the var.
113 */
114 int getArrayCount() const { return fCount; }
115 /**
116 * Set the array length of the var
117 */
118 void setArrayCount(int count) { fCount = count; }
119 /**
120 * Set to be a non-array.
121 */
122 void setNonArray() { fCount = kNonArray; }
123 /**
124 * Set to be an unsized array.
125 */
126 void setUnsizedArray() { fCount = kUnsizedArray; }
127
128 /**
129 * Access the var name as a writable string
130 */
131 GrStringBuilder* accessName() { return &fName; }
132 /**
133 * Set the var name
134 */
135 void setName(const GrStringBuilder& n) { fName = n; }
136 void setName(const char* n) { fName = n; }
137 /**
138 * Get the var name.
139 */
140 const GrStringBuilder& getName() const { return fName; }
141
142 /**
143 * Get the type of the var
144 */
145 Type getType() const { return fType; }
146 /**
147 * Set the type of the var
148 */
149 void setType(Type type) { fType = type; }
150
151 /**
152 * Must the variable declaration emit a precision specifier
153 */
154 bool emitsPrecision() const { return fEmitPrecision; }
155 /**
156 * Specify whether the declaration should specify precision
157 */
158 void setEmitPrecision(bool p) { fEmitPrecision = p; }
159
160 /**
161 * Write a declaration of this variable to out.
162 */
163 void appendDecl(const GrGLInterface* gl, GrStringBuilder* out) const {
164 if (this->emitsPrecision()) {
165 out->append(PrecisionString(gl));
166 out->append(" ");
167 }
168 if (this->isArray()) {
169 if (this->isUnsizedArray()) {
170 out->appendf("%s %s[]",
171 TypeString(this->getType()),
172 this->getName().c_str());
173 } else {
174 GrAssert(this->getArrayCount() > 0);
175 out->appendf("%s %s[%d]",
176 TypeString(this->getType()),
177 this->getName().c_str(),
178 this->getArrayCount());
179 }
180 } else {
181 out->appendf("%s %s",
182 TypeString(this->getType()),
183 this->getName().c_str());
184 }
185 }
186
187 static const char* TypeString(Type t) {
188 switch (t) {
189 case kFloat_Type:
190 return "float";
191 case kVec2f_Type:
192 return "vec2";
193 case kVec3f_Type:
194 return "vec3";
195 case kVec4f_Type:
196 return "vec4";
197 case kMat33f_Type:
198 return "mat3";
199 case kSampler2D_Type:
200 return "sampler2D";
201 default:
202 GrCrash("Unknown shader var type.");
203 return ""; // suppress warning
204 }
205 }
206
207private:
208 static const char* PrecisionString(const GrGLInterface* gl) {
209 return gl->supportsDesktop() ? "" : "mediump";
210 }
211
212 Type fType;
213 GrStringBuilder fName;
214 int fCount;
215 bool fEmitPrecision;
216};
217
218#endif