• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "include/core/SkMatrix.h"
9 #include "src/gpu/ganesh/gl/GrGLGpu.h"
10 #include "src/gpu/ganesh/gl/GrGLProgramDataManager.h"
11 #include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"
12 
13 #define ASSERT_ARRAY_UPLOAD_IN_BOUNDS(UNI, COUNT) \
14          SkASSERT((COUNT) <= (UNI).fArrayCount || \
15                   (1 == (COUNT) && GrShaderVar::kNonArray == (UNI).fArrayCount))
16 
GrGLProgramDataManager(GrGLGpu * gpu,const UniformInfoArray & uniforms)17 GrGLProgramDataManager::GrGLProgramDataManager(GrGLGpu* gpu, const UniformInfoArray& uniforms)
18         : fGpu(gpu) {
19     fUniforms.push_back_n(uniforms.count());
20     int i = 0;
21     for (const GLUniformInfo& builderUniform : uniforms.items()) {
22         Uniform& uniform = fUniforms[i++];
23         SkASSERT(GrShaderVar::kNonArray == builderUniform.fVariable.getArrayCount() ||
24                  builderUniform.fVariable.getArrayCount() > 0);
25         SkDEBUGCODE(
26             uniform.fArrayCount = builderUniform.fVariable.getArrayCount();
27             uniform.fType = builderUniform.fVariable.getType();
28         )
29         uniform.fLocation = builderUniform.fLocation;
30     }
31 }
32 
setSamplerUniforms(const UniformInfoArray & samplers,int startUnit) const33 void GrGLProgramDataManager::setSamplerUniforms(const UniformInfoArray& samplers,
34                                                 int startUnit) const {
35     int i = 0;
36     for (const GLUniformInfo& sampler : samplers.items()) {
37         SkASSERT(sampler.fVisibility);
38         if (kUnusedUniform != sampler.fLocation) {
39             GR_GL_CALL(fGpu->glInterface(), Uniform1i(sampler.fLocation, i + startUnit));
40         }
41         ++i;
42     }
43 }
44 
set1i(UniformHandle u,int32_t i) const45 void GrGLProgramDataManager::set1i(UniformHandle u, int32_t i) const {
46     const Uniform& uni = fUniforms[u.toIndex()];
47     SkASSERT(uni.fType == SkSLType::kInt || uni.fType == SkSLType::kShort);
48     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
49     if (kUnusedUniform != uni.fLocation) {
50         GR_GL_CALL(fGpu->glInterface(), Uniform1i(uni.fLocation, i));
51     }
52 }
53 
set1iv(UniformHandle u,int arrayCount,const int32_t v[]) const54 void GrGLProgramDataManager::set1iv(UniformHandle u,
55                                     int arrayCount,
56                                     const int32_t v[]) const {
57     const Uniform& uni = fUniforms[u.toIndex()];
58     SkASSERT(uni.fType == SkSLType::kInt || uni.fType == SkSLType::kShort);
59     SkASSERT(arrayCount > 0);
60     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
61     if (kUnusedUniform != uni.fLocation) {
62         GR_GL_CALL(fGpu->glInterface(), Uniform1iv(uni.fLocation, arrayCount, v));
63     }
64 }
65 
set1f(UniformHandle u,float v0) const66 void GrGLProgramDataManager::set1f(UniformHandle u, float v0) const {
67     const Uniform& uni = fUniforms[u.toIndex()];
68     SkASSERT(uni.fType == SkSLType::kFloat || uni.fType == SkSLType::kHalf);
69     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
70     if (kUnusedUniform != uni.fLocation) {
71         GR_GL_CALL(fGpu->glInterface(), Uniform1f(uni.fLocation, v0));
72     }
73 }
74 
set1fv(UniformHandle u,int arrayCount,const float v[]) const75 void GrGLProgramDataManager::set1fv(UniformHandle u,
76                                     int arrayCount,
77                                     const float v[]) const {
78     const Uniform& uni = fUniforms[u.toIndex()];
79     SkASSERT(uni.fType == SkSLType::kFloat || uni.fType == SkSLType::kHalf);
80     SkASSERT(arrayCount > 0);
81     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
82     // This assert fires in some instances of the two-pt gradient for its VSParams.
83     // Once the uniform manager is responsible for inserting the duplicate uniform
84     // arrays in VS and FS driver bug workaround, this can be enabled.
85     // this->printUni(uni);
86     if (kUnusedUniform != uni.fLocation) {
87         GR_GL_CALL(fGpu->glInterface(), Uniform1fv(uni.fLocation, arrayCount, v));
88     }
89 }
90 
set2i(UniformHandle u,int32_t i0,int32_t i1) const91 void GrGLProgramDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
92     const Uniform& uni = fUniforms[u.toIndex()];
93     SkASSERT(uni.fType == SkSLType::kInt2 || uni.fType == SkSLType::kShort2);
94     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
95     if (kUnusedUniform != uni.fLocation) {
96         GR_GL_CALL(fGpu->glInterface(), Uniform2i(uni.fLocation, i0, i1));
97     }
98 }
99 
set2iv(UniformHandle u,int arrayCount,const int32_t v[]) const100 void GrGLProgramDataManager::set2iv(UniformHandle u,
101                                     int arrayCount,
102                                     const int32_t v[]) const {
103     const Uniform& uni = fUniforms[u.toIndex()];
104     SkASSERT(uni.fType == SkSLType::kInt2 || uni.fType == SkSLType::kShort2);
105     SkASSERT(arrayCount > 0);
106     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
107     if (kUnusedUniform != uni.fLocation) {
108         GR_GL_CALL(fGpu->glInterface(), Uniform2iv(uni.fLocation, arrayCount, v));
109     }
110 }
111 
set2f(UniformHandle u,float v0,float v1) const112 void GrGLProgramDataManager::set2f(UniformHandle u, float v0, float v1) const {
113     const Uniform& uni = fUniforms[u.toIndex()];
114     SkASSERT(uni.fType == SkSLType::kFloat2 || uni.fType == SkSLType::kHalf2);
115     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
116     if (kUnusedUniform != uni.fLocation) {
117         GR_GL_CALL(fGpu->glInterface(), Uniform2f(uni.fLocation, v0, v1));
118     }
119 }
120 
set2fv(UniformHandle u,int arrayCount,const float v[]) const121 void GrGLProgramDataManager::set2fv(UniformHandle u,
122                                     int arrayCount,
123                                     const float v[]) const {
124     const Uniform& uni = fUniforms[u.toIndex()];
125     SkASSERT(uni.fType == SkSLType::kFloat2 || uni.fType == SkSLType::kHalf2);
126     SkASSERT(arrayCount > 0);
127     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
128     if (kUnusedUniform != uni.fLocation) {
129         GR_GL_CALL(fGpu->glInterface(), Uniform2fv(uni.fLocation, arrayCount, v));
130     }
131 }
132 
set3i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2) const133 void GrGLProgramDataManager::set3i(UniformHandle u, int32_t i0, int32_t i1, int32_t i2) const {
134     const Uniform& uni = fUniforms[u.toIndex()];
135     SkASSERT(uni.fType == SkSLType::kInt3 || uni.fType == SkSLType::kShort3);
136     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
137     if (kUnusedUniform != uni.fLocation) {
138         GR_GL_CALL(fGpu->glInterface(), Uniform3i(uni.fLocation, i0, i1, i2));
139     }
140 }
141 
set3iv(UniformHandle u,int arrayCount,const int32_t v[]) const142 void GrGLProgramDataManager::set3iv(UniformHandle u,
143                                     int arrayCount,
144                                     const int32_t v[]) const {
145     const Uniform& uni = fUniforms[u.toIndex()];
146     SkASSERT(uni.fType == SkSLType::kInt3 || uni.fType == SkSLType::kShort3);
147     SkASSERT(arrayCount > 0);
148     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
149     if (kUnusedUniform != uni.fLocation) {
150         GR_GL_CALL(fGpu->glInterface(), Uniform3iv(uni.fLocation, arrayCount, v));
151     }
152 }
153 
set3f(UniformHandle u,float v0,float v1,float v2) const154 void GrGLProgramDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
155     const Uniform& uni = fUniforms[u.toIndex()];
156     SkASSERT(uni.fType == SkSLType::kFloat3 || uni.fType == SkSLType::kHalf3);
157     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
158     if (kUnusedUniform != uni.fLocation) {
159         GR_GL_CALL(fGpu->glInterface(), Uniform3f(uni.fLocation, v0, v1, v2));
160     }
161 }
162 
set3fv(UniformHandle u,int arrayCount,const float v[]) const163 void GrGLProgramDataManager::set3fv(UniformHandle u,
164                                     int arrayCount,
165                                     const float v[]) const {
166     const Uniform& uni = fUniforms[u.toIndex()];
167     SkASSERT(uni.fType == SkSLType::kFloat3 || uni.fType == SkSLType::kHalf3);
168     SkASSERT(arrayCount > 0);
169     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
170     if (kUnusedUniform != uni.fLocation) {
171         GR_GL_CALL(fGpu->glInterface(), Uniform3fv(uni.fLocation, arrayCount, v));
172     }
173 }
174 
set4i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2,int32_t i3) const175 void GrGLProgramDataManager::set4i(UniformHandle u,
176                                    int32_t i0,
177                                    int32_t i1,
178                                    int32_t i2,
179                                    int32_t i3) const {
180     const Uniform& uni = fUniforms[u.toIndex()];
181     SkASSERT(uni.fType == SkSLType::kInt4 || uni.fType == SkSLType::kShort4);
182     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
183     if (kUnusedUniform != uni.fLocation) {
184         GR_GL_CALL(fGpu->glInterface(), Uniform4i(uni.fLocation, i0, i1, i2, i3));
185     }
186 }
187 
set4iv(UniformHandle u,int arrayCount,const int32_t v[]) const188 void GrGLProgramDataManager::set4iv(UniformHandle u,
189                                     int arrayCount,
190                                     const int32_t v[]) const {
191     const Uniform& uni = fUniforms[u.toIndex()];
192     SkASSERT(uni.fType == SkSLType::kInt4 || uni.fType == SkSLType::kShort4);
193     SkASSERT(arrayCount > 0);
194     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
195     if (kUnusedUniform != uni.fLocation) {
196         GR_GL_CALL(fGpu->glInterface(), Uniform4iv(uni.fLocation, arrayCount, v));
197     }
198 }
199 
set4f(UniformHandle u,float v0,float v1,float v2,float v3) const200 void GrGLProgramDataManager::set4f(UniformHandle u,
201                                    float v0,
202                                    float v1,
203                                    float v2,
204                                    float v3) const {
205     const Uniform& uni = fUniforms[u.toIndex()];
206     SkASSERT(uni.fType == SkSLType::kFloat4 || uni.fType == SkSLType::kHalf4);
207     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
208     if (kUnusedUniform != uni.fLocation) {
209         GR_GL_CALL(fGpu->glInterface(), Uniform4f(uni.fLocation, v0, v1, v2, v3));
210     }
211 }
212 
set4fv(UniformHandle u,int arrayCount,const float v[]) const213 void GrGLProgramDataManager::set4fv(UniformHandle u,
214                                     int arrayCount,
215                                     const float v[]) const {
216     const Uniform& uni = fUniforms[u.toIndex()];
217     SkASSERT(uni.fType == SkSLType::kFloat4 || uni.fType == SkSLType::kHalf4);
218     SkASSERT(arrayCount > 0);
219     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
220     if (kUnusedUniform != uni.fLocation) {
221         GR_GL_CALL(fGpu->glInterface(), Uniform4fv(uni.fLocation, arrayCount, v));
222     }
223 }
224 
setMatrix2f(UniformHandle u,const float matrix[]) const225 void GrGLProgramDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
226     this->setMatrices<2>(u, 1, matrix);
227 }
228 
setMatrix3f(UniformHandle u,const float matrix[]) const229 void GrGLProgramDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
230     this->setMatrices<3>(u, 1, matrix);
231 }
232 
setMatrix4f(UniformHandle u,const float matrix[]) const233 void GrGLProgramDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
234     this->setMatrices<4>(u, 1, matrix);
235 }
236 
setMatrix2fv(UniformHandle u,int arrayCount,const float m[]) const237 void GrGLProgramDataManager::setMatrix2fv(UniformHandle u, int arrayCount, const float m[]) const {
238     this->setMatrices<2>(u, arrayCount, m);
239 }
240 
setMatrix3fv(UniformHandle u,int arrayCount,const float m[]) const241 void GrGLProgramDataManager::setMatrix3fv(UniformHandle u, int arrayCount, const float m[]) const {
242     this->setMatrices<3>(u, arrayCount, m);
243 }
244 
setMatrix4fv(UniformHandle u,int arrayCount,const float m[]) const245 void GrGLProgramDataManager::setMatrix4fv(UniformHandle u, int arrayCount, const float m[]) const {
246     this->setMatrices<4>(u, arrayCount, m);
247 }
248 
249 template<int N> struct set_uniform_matrix;
250 
setMatrices(UniformHandle u,int arrayCount,const float matrices[]) const251 template<int N> inline void GrGLProgramDataManager::setMatrices(UniformHandle u,
252                                                                 int arrayCount,
253                                                                 const float matrices[]) const {
254     const Uniform& uni = fUniforms[u.toIndex()];
255     SkASSERT(static_cast<int>(uni.fType) == static_cast<int>(SkSLType::kFloat2x2) + (N - 2) ||
256              static_cast<int>(uni.fType) == static_cast<int>(SkSLType::kHalf2x2) + (N - 2));
257     SkASSERT(arrayCount > 0);
258     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
259     if (kUnusedUniform != uni.fLocation) {
260         set_uniform_matrix<N>::set(fGpu->glInterface(), uni.fLocation, arrayCount, matrices);
261     }
262 }
263 
264 template<> struct set_uniform_matrix<2> {
setset_uniform_matrix265     inline static void set(const GrGLInterface* gli, const GrGLint loc, int cnt, const float m[]) {
266         GR_GL_CALL(gli, UniformMatrix2fv(loc, cnt, false, m));
267     }
268 };
269 
270 template<> struct set_uniform_matrix<3> {
setset_uniform_matrix271     inline static void set(const GrGLInterface* gli, const GrGLint loc, int cnt, const float m[]) {
272         GR_GL_CALL(gli, UniformMatrix3fv(loc, cnt, false, m));
273     }
274 };
275 
276 template<> struct set_uniform_matrix<4> {
setset_uniform_matrix277     inline static void set(const GrGLInterface* gli, const GrGLint loc, int cnt, const float m[]) {
278         GR_GL_CALL(gli, UniformMatrix4fv(loc, cnt, false, m));
279     }
280 };
281