OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2012 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 #include "gl/GrGLShaderBuilder.h" | |
9 #include "gl/GrGLProgram.h" | |
10 #include "gl/GrGLUniformHandle.h" | |
11 #include "SkMatrix.h" | |
12 | |
13 #define ASSERT_ARRAY_UPLOAD_IN_BOUNDS(UNI, OFFSET, COUNT) \ | |
14 GrAssert(offset + arrayCount <= uni.fArrayCount || \ | |
15 (0 == offset && 1 == arrayCount && GrGLShaderVar::kNonArray ==
uni.fArrayCount)) | |
16 | |
17 GrGLUniformManager::UniformHandle GrGLUniformManager::appendUniform(GrSLType typ
e, int arrayCount) { | |
18 int idx = fUniforms.count(); | |
19 Uniform& uni = fUniforms.push_back(); | |
20 GrAssert(GrGLShaderVar::kNonArray == arrayCount || arrayCount > 0); | |
21 uni.fArrayCount = arrayCount; | |
22 uni.fType = type; | |
23 uni.fVSLocation = kUnusedUniform; | |
24 uni.fFSLocation = kUnusedUniform; | |
25 return index_to_handle(idx); | |
26 } | |
27 | |
28 void GrGLUniformManager::setSampler(UniformHandle u, GrGLint texUnit) const { | |
29 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
30 GrAssert(uni.fType == kSampler2D_GrSLType); | |
31 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); | |
32 // FIXME: We still insert a single sampler uniform for every stage. If the s
hader does not | |
33 // reference the sampler then the compiler may have optimized it out. Uncomm
ent this assert | |
34 // once stages insert their own samplers. | |
35 // GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLo
cation); | |
36 if (kUnusedUniform != uni.fFSLocation) { | |
37 GR_GL_CALL(fContext.interface(), Uniform1i(uni.fFSLocation, texUnit)); | |
38 } | |
39 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
40 GR_GL_CALL(fContext.interface(), Uniform1i(uni.fVSLocation, texUnit)); | |
41 } | |
42 } | |
43 | |
44 void GrGLUniformManager::set1f(UniformHandle u, GrGLfloat v0) const { | |
45 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
46 GrAssert(uni.fType == kFloat_GrSLType); | |
47 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); | |
48 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocat
ion); | |
49 if (kUnusedUniform != uni.fFSLocation) { | |
50 GR_GL_CALL(fContext.interface(), Uniform1f(uni.fFSLocation, v0)); | |
51 } | |
52 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
53 GR_GL_CALL(fContext.interface(), Uniform1f(uni.fVSLocation, v0)); | |
54 } | |
55 } | |
56 | |
57 void GrGLUniformManager::set1fv(UniformHandle u, | |
58 int offset, | |
59 int arrayCount, | |
60 const GrGLfloat v[]) const { | |
61 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
62 GrAssert(uni.fType == kFloat_GrSLType); | |
63 GrAssert(arrayCount > 0); | |
64 ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount); | |
65 // This assert fires in some instances of the two-pt gradient for its VSPara
ms. | |
66 // Once the uniform manager is responsible for inserting the duplicate unifo
rm | |
67 // arrays in VS and FS driver bug workaround, this can be enabled. | |
68 //GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLoc
ation); | |
69 if (kUnusedUniform != uni.fFSLocation) { | |
70 GR_GL_CALL(fContext.interface(), Uniform1fv(uni.fFSLocation + offset, ar
rayCount, v)); | |
71 } | |
72 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
73 GR_GL_CALL(fContext.interface(), Uniform1fv(uni.fVSLocation + offset, ar
rayCount, v)); | |
74 } | |
75 } | |
76 | |
77 void GrGLUniformManager::set2f(UniformHandle u, GrGLfloat v0, GrGLfloat v1) cons
t { | |
78 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
79 GrAssert(uni.fType == kVec2f_GrSLType); | |
80 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); | |
81 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocat
ion); | |
82 if (kUnusedUniform != uni.fFSLocation) { | |
83 GR_GL_CALL(fContext.interface(), Uniform2f(uni.fFSLocation, v0, v1)); | |
84 } | |
85 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
86 GR_GL_CALL(fContext.interface(), Uniform2f(uni.fVSLocation, v0, v1)); | |
87 } | |
88 } | |
89 | |
90 void GrGLUniformManager::set2fv(UniformHandle u, | |
91 int offset, | |
92 int arrayCount, | |
93 const GrGLfloat v[]) const { | |
94 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
95 GrAssert(uni.fType == kVec2f_GrSLType); | |
96 GrAssert(arrayCount > 0); | |
97 ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount); | |
98 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocat
ion); | |
99 if (kUnusedUniform != uni.fFSLocation) { | |
100 GR_GL_CALL(fContext.interface(), Uniform2fv(uni.fFSLocation + offset, ar
rayCount, v)); | |
101 } | |
102 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
103 GR_GL_CALL(fContext.interface(), Uniform2fv(uni.fVSLocation + offset, ar
rayCount, v)); | |
104 } | |
105 } | |
106 | |
107 void GrGLUniformManager::set3f(UniformHandle u, GrGLfloat v0, GrGLfloat v1, GrGL
float v2) const { | |
108 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
109 GrAssert(uni.fType == kVec3f_GrSLType); | |
110 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); | |
111 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocat
ion); | |
112 if (kUnusedUniform != uni.fFSLocation) { | |
113 GR_GL_CALL(fContext.interface(), Uniform3f(uni.fFSLocation, v0, v1, v2))
; | |
114 } | |
115 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
116 GR_GL_CALL(fContext.interface(), Uniform3f(uni.fVSLocation, v0, v1, v2))
; | |
117 } | |
118 } | |
119 | |
120 void GrGLUniformManager::set3fv(UniformHandle u, | |
121 int offset, | |
122 int arrayCount, | |
123 const GrGLfloat v[]) const { | |
124 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
125 GrAssert(uni.fType == kVec3f_GrSLType); | |
126 GrAssert(arrayCount > 0); | |
127 ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount); | |
128 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocat
ion); | |
129 if (kUnusedUniform != uni.fFSLocation) { | |
130 GR_GL_CALL(fContext.interface(), Uniform3fv(uni.fFSLocation + offset, ar
rayCount, v)); | |
131 } | |
132 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
133 GR_GL_CALL(fContext.interface(), Uniform3fv(uni.fVSLocation + offset, ar
rayCount, v)); | |
134 } | |
135 } | |
136 | |
137 void GrGLUniformManager::set4f(UniformHandle u, | |
138 GrGLfloat v0, | |
139 GrGLfloat v1, | |
140 GrGLfloat v2, | |
141 GrGLfloat v3) const { | |
142 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
143 GrAssert(uni.fType == kVec4f_GrSLType); | |
144 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); | |
145 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocat
ion); | |
146 if (kUnusedUniform != uni.fFSLocation) { | |
147 GR_GL_CALL(fContext.interface(), Uniform4f(uni.fFSLocation, v0, v1, v2,
v3)); | |
148 } | |
149 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
150 GR_GL_CALL(fContext.interface(), Uniform4f(uni.fVSLocation, v0, v1, v2,
v3)); | |
151 } | |
152 } | |
153 | |
154 void GrGLUniformManager::set4fv(UniformHandle u, | |
155 int offset, | |
156 int arrayCount, | |
157 const GrGLfloat v[]) const { | |
158 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
159 GrAssert(uni.fType == kVec4f_GrSLType); | |
160 GrAssert(arrayCount > 0); | |
161 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocat
ion); | |
162 if (kUnusedUniform != uni.fFSLocation) { | |
163 GR_GL_CALL(fContext.interface(), Uniform4fv(uni.fFSLocation + offset, ar
rayCount, v)); | |
164 } | |
165 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
166 GR_GL_CALL(fContext.interface(), Uniform4fv(uni.fVSLocation + offset, ar
rayCount, v)); | |
167 } | |
168 } | |
169 | |
170 void GrGLUniformManager::setMatrix3f(UniformHandle u, const GrGLfloat matrix[])
const { | |
171 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
172 GrAssert(uni.fType == kMat33f_GrSLType); | |
173 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); | |
174 // TODO: Re-enable this assert once texture matrices aren't forced on all ef
fects | |
175 // GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLo
cation); | |
176 if (kUnusedUniform != uni.fFSLocation) { | |
177 GR_GL_CALL(fContext.interface(), UniformMatrix3fv(uni.fFSLocation, 1, fa
lse, matrix)); | |
178 } | |
179 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
180 GR_GL_CALL(fContext.interface(), UniformMatrix3fv(uni.fVSLocation, 1, fa
lse, matrix)); | |
181 } | |
182 } | |
183 | |
184 void GrGLUniformManager::setMatrix4f(UniformHandle u, const GrGLfloat matrix[])
const { | |
185 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
186 GrAssert(uni.fType == kMat44f_GrSLType); | |
187 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount); | |
188 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocat
ion); | |
189 if (kUnusedUniform != uni.fFSLocation) { | |
190 GR_GL_CALL(fContext.interface(), UniformMatrix4fv(uni.fFSLocation, 1, fa
lse, matrix)); | |
191 } | |
192 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
193 GR_GL_CALL(fContext.interface(), UniformMatrix4fv(uni.fVSLocation, 1, fa
lse, matrix)); | |
194 } | |
195 } | |
196 | |
197 void GrGLUniformManager::setMatrix3fv(UniformHandle u, | |
198 int offset, | |
199 int arrayCount, | |
200 const GrGLfloat matrices[]) const { | |
201 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
202 GrAssert(uni.fType == kMat33f_GrSLType); | |
203 GrAssert(arrayCount > 0); | |
204 ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount); | |
205 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocat
ion); | |
206 if (kUnusedUniform != uni.fFSLocation) { | |
207 GR_GL_CALL(fContext.interface(), | |
208 UniformMatrix3fv(uni.fFSLocation + offset, arrayCount, false,
matrices)); | |
209 } | |
210 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
211 GR_GL_CALL(fContext.interface(), | |
212 UniformMatrix3fv(uni.fVSLocation + offset, arrayCount, false,
matrices)); | |
213 } | |
214 } | |
215 | |
216 void GrGLUniformManager::setMatrix4fv(UniformHandle u, | |
217 int offset, | |
218 int arrayCount, | |
219 const GrGLfloat matrices[]) const { | |
220 const Uniform& uni = fUniforms[handle_to_index(u)]; | |
221 GrAssert(uni.fType == kMat44f_GrSLType); | |
222 GrAssert(arrayCount > 0); | |
223 ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount); | |
224 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocat
ion); | |
225 if (kUnusedUniform != uni.fFSLocation) { | |
226 GR_GL_CALL(fContext.interface(), | |
227 UniformMatrix4fv(uni.fFSLocation + offset, arrayCount, false,
matrices)); | |
228 } | |
229 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation)
{ | |
230 GR_GL_CALL(fContext.interface(), | |
231 UniformMatrix4fv(uni.fVSLocation + offset, arrayCount, false,
matrices)); | |
232 } | |
233 } | |
234 | |
235 void GrGLUniformManager::setSkMatrix(UniformHandle u, const SkMatrix& matrix) co
nst { | |
236 // GR_STATIC_ASSERT(SK_SCALAR_IS_FLOAT); | |
237 GrGLfloat mt[] = { | |
238 matrix.get(SkMatrix::kMScaleX), | |
239 matrix.get(SkMatrix::kMSkewY), | |
240 matrix.get(SkMatrix::kMPersp0), | |
241 matrix.get(SkMatrix::kMSkewX), | |
242 matrix.get(SkMatrix::kMScaleY), | |
243 matrix.get(SkMatrix::kMPersp1), | |
244 matrix.get(SkMatrix::kMTransX), | |
245 matrix.get(SkMatrix::kMTransY), | |
246 matrix.get(SkMatrix::kMPersp2), | |
247 }; | |
248 this->setMatrix3f(u, mt); | |
249 } | |
250 | |
251 | |
252 void GrGLUniformManager::getUniformLocations(GrGLuint programID, const BuilderUn
iformArray& uniforms) { | |
253 GrAssert(uniforms.count() == fUniforms.count()); | |
254 int count = fUniforms.count(); | |
255 for (int i = 0; i < count; ++i) { | |
256 GrAssert(uniforms[i].fVariable.getType() == fUniforms[i].fType); | |
257 GrAssert(uniforms[i].fVariable.getArrayCount() == fUniforms[i].fArrayCou
nt); | |
258 GrGLint location; | |
259 // TODO: Move the Xoom uniform array in both FS and VS bug workaround he
re. | |
260 GR_GL_CALL_RET(fContext.interface(), location, | |
261 GetUniformLocation(programID, uniforms[i].fVariable.c_str
())); | |
262 if (GrGLShaderBuilder::kVertex_ShaderType & uniforms[i].fVisibility) { | |
263 fUniforms[i].fVSLocation = location; | |
264 } | |
265 if (GrGLShaderBuilder::kFragment_ShaderType & uniforms[i].fVisibility) { | |
266 fUniforms[i].fFSLocation = location; | |
267 } | |
268 } | |
269 } | |
OLD | NEW |