xref: /aosp_15_r20/external/skia/src/gpu/ganesh/gl/GrGLProgramDataManager.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 #include "src/gpu/ganesh/gl/GrGLProgramDataManager.h"
8 
9 #include "include/gpu/ganesh/gl/GrGLFunctions.h"
10 #include "include/gpu/ganesh/gl/GrGLInterface.h"
11 #include "include/private/base/SkAssert.h"
12 #include "src/core/SkSLTypeShared.h"
13 #include "src/gpu/ganesh/gl/GrGLGpu.h"
14 #include "src/gpu/ganesh/gl/GrGLUtil.h"
15 
16 #define ASSERT_ARRAY_UPLOAD_IN_BOUNDS(UNI, COUNT) \
17          SkASSERT((COUNT) <= (UNI).fArrayCount || \
18                   (1 == (COUNT) && GrShaderVar::kNonArray == (UNI).fArrayCount))
19 
20 static constexpr GrGLint kUnusedUniform = -1;
21 
GrGLProgramDataManager(GrGLGpu * gpu,const UniformInfoArray & uniforms)22 GrGLProgramDataManager::GrGLProgramDataManager(GrGLGpu* gpu, const UniformInfoArray& uniforms)
23         : fGpu(gpu) {
24     fUniforms.push_back_n(uniforms.count());
25     int i = 0;
26     for (const GLUniformInfo& builderUniform : uniforms.items()) {
27         Uniform& uniform = fUniforms[i++];
28         SkASSERT(GrShaderVar::kNonArray == builderUniform.fVariable.getArrayCount() ||
29                  builderUniform.fVariable.getArrayCount() > 0);
30         SkDEBUGCODE(
31             uniform.fArrayCount = builderUniform.fVariable.getArrayCount();
32             uniform.fType = builderUniform.fVariable.getType();
33         )
34         uniform.fLocation = builderUniform.fLocation;
35     }
36 }
37 
setSamplerUniforms(const UniformInfoArray & samplers,int startUnit) const38 void GrGLProgramDataManager::setSamplerUniforms(const UniformInfoArray& samplers,
39                                                 int startUnit) const {
40     int i = 0;
41     for (const GLUniformInfo& sampler : samplers.items()) {
42         SkASSERT(sampler.fVisibility);
43         if (kUnusedUniform != sampler.fLocation) {
44             GR_GL_CALL(fGpu->glInterface(), Uniform1i(sampler.fLocation, i + startUnit));
45         }
46         ++i;
47     }
48 }
49 
set1i(UniformHandle u,int32_t i) const50 void GrGLProgramDataManager::set1i(UniformHandle u, int32_t i) const {
51     const Uniform& uni = fUniforms[u.toIndex()];
52     SkASSERT(uni.fType == SkSLType::kInt || uni.fType == SkSLType::kShort);
53     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
54     if (kUnusedUniform != uni.fLocation) {
55         GR_GL_CALL(fGpu->glInterface(), Uniform1i(uni.fLocation, i));
56     }
57 }
58 
set1iv(UniformHandle u,int arrayCount,const int32_t v[]) const59 void GrGLProgramDataManager::set1iv(UniformHandle u,
60                                     int arrayCount,
61                                     const int32_t v[]) const {
62     const Uniform& uni = fUniforms[u.toIndex()];
63     SkASSERT(uni.fType == SkSLType::kInt || uni.fType == SkSLType::kShort);
64     SkASSERT(arrayCount > 0);
65     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
66     if (kUnusedUniform != uni.fLocation) {
67         GR_GL_CALL(fGpu->glInterface(), Uniform1iv(uni.fLocation, arrayCount, v));
68     }
69 }
70 
set1f(UniformHandle u,float v0) const71 void GrGLProgramDataManager::set1f(UniformHandle u, float v0) const {
72     const Uniform& uni = fUniforms[u.toIndex()];
73     SkASSERT(uni.fType == SkSLType::kFloat || uni.fType == SkSLType::kHalf);
74     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
75     if (kUnusedUniform != uni.fLocation) {
76         GR_GL_CALL(fGpu->glInterface(), Uniform1f(uni.fLocation, v0));
77     }
78 }
79 
set1fv(UniformHandle u,int arrayCount,const float v[]) const80 void GrGLProgramDataManager::set1fv(UniformHandle u,
81                                     int arrayCount,
82                                     const float v[]) const {
83     const Uniform& uni = fUniforms[u.toIndex()];
84     SkASSERT(uni.fType == SkSLType::kFloat || uni.fType == SkSLType::kHalf);
85     SkASSERT(arrayCount > 0);
86     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
87     // This assert fires in some instances of the two-pt gradient for its VSParams.
88     // Once the uniform manager is responsible for inserting the duplicate uniform
89     // arrays in VS and FS driver bug workaround, this can be enabled.
90     // this->printUni(uni);
91     if (kUnusedUniform != uni.fLocation) {
92         GR_GL_CALL(fGpu->glInterface(), Uniform1fv(uni.fLocation, arrayCount, v));
93     }
94 }
95 
set2i(UniformHandle u,int32_t i0,int32_t i1) const96 void GrGLProgramDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
97     const Uniform& uni = fUniforms[u.toIndex()];
98     SkASSERT(uni.fType == SkSLType::kInt2 || uni.fType == SkSLType::kShort2);
99     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
100     if (kUnusedUniform != uni.fLocation) {
101         GR_GL_CALL(fGpu->glInterface(), Uniform2i(uni.fLocation, i0, i1));
102     }
103 }
104 
set2iv(UniformHandle u,int arrayCount,const int32_t v[]) const105 void GrGLProgramDataManager::set2iv(UniformHandle u,
106                                     int arrayCount,
107                                     const int32_t v[]) const {
108     const Uniform& uni = fUniforms[u.toIndex()];
109     SkASSERT(uni.fType == SkSLType::kInt2 || uni.fType == SkSLType::kShort2);
110     SkASSERT(arrayCount > 0);
111     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
112     if (kUnusedUniform != uni.fLocation) {
113         GR_GL_CALL(fGpu->glInterface(), Uniform2iv(uni.fLocation, arrayCount, v));
114     }
115 }
116 
set2f(UniformHandle u,float v0,float v1) const117 void GrGLProgramDataManager::set2f(UniformHandle u, float v0, float v1) const {
118     const Uniform& uni = fUniforms[u.toIndex()];
119     SkASSERT(uni.fType == SkSLType::kFloat2 || uni.fType == SkSLType::kHalf2);
120     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
121     if (kUnusedUniform != uni.fLocation) {
122         GR_GL_CALL(fGpu->glInterface(), Uniform2f(uni.fLocation, v0, v1));
123     }
124 }
125 
set2fv(UniformHandle u,int arrayCount,const float v[]) const126 void GrGLProgramDataManager::set2fv(UniformHandle u,
127                                     int arrayCount,
128                                     const float v[]) const {
129     const Uniform& uni = fUniforms[u.toIndex()];
130     SkASSERT(uni.fType == SkSLType::kFloat2 || uni.fType == SkSLType::kHalf2);
131     SkASSERT(arrayCount > 0);
132     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
133     if (kUnusedUniform != uni.fLocation) {
134         GR_GL_CALL(fGpu->glInterface(), Uniform2fv(uni.fLocation, arrayCount, v));
135     }
136 }
137 
set3i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2) const138 void GrGLProgramDataManager::set3i(UniformHandle u, int32_t i0, int32_t i1, int32_t i2) const {
139     const Uniform& uni = fUniforms[u.toIndex()];
140     SkASSERT(uni.fType == SkSLType::kInt3 || uni.fType == SkSLType::kShort3);
141     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
142     if (kUnusedUniform != uni.fLocation) {
143         GR_GL_CALL(fGpu->glInterface(), Uniform3i(uni.fLocation, i0, i1, i2));
144     }
145 }
146 
set3iv(UniformHandle u,int arrayCount,const int32_t v[]) const147 void GrGLProgramDataManager::set3iv(UniformHandle u,
148                                     int arrayCount,
149                                     const int32_t v[]) const {
150     const Uniform& uni = fUniforms[u.toIndex()];
151     SkASSERT(uni.fType == SkSLType::kInt3 || uni.fType == SkSLType::kShort3);
152     SkASSERT(arrayCount > 0);
153     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
154     if (kUnusedUniform != uni.fLocation) {
155         GR_GL_CALL(fGpu->glInterface(), Uniform3iv(uni.fLocation, arrayCount, v));
156     }
157 }
158 
set3f(UniformHandle u,float v0,float v1,float v2) const159 void GrGLProgramDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
160     const Uniform& uni = fUniforms[u.toIndex()];
161     SkASSERT(uni.fType == SkSLType::kFloat3 || uni.fType == SkSLType::kHalf3);
162     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
163     if (kUnusedUniform != uni.fLocation) {
164         GR_GL_CALL(fGpu->glInterface(), Uniform3f(uni.fLocation, v0, v1, v2));
165     }
166 }
167 
set3fv(UniformHandle u,int arrayCount,const float v[]) const168 void GrGLProgramDataManager::set3fv(UniformHandle u,
169                                     int arrayCount,
170                                     const float v[]) const {
171     const Uniform& uni = fUniforms[u.toIndex()];
172     SkASSERT(uni.fType == SkSLType::kFloat3 || uni.fType == SkSLType::kHalf3);
173     SkASSERT(arrayCount > 0);
174     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
175     if (kUnusedUniform != uni.fLocation) {
176         GR_GL_CALL(fGpu->glInterface(), Uniform3fv(uni.fLocation, arrayCount, v));
177     }
178 }
179 
set4i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2,int32_t i3) const180 void GrGLProgramDataManager::set4i(UniformHandle u,
181                                    int32_t i0,
182                                    int32_t i1,
183                                    int32_t i2,
184                                    int32_t i3) const {
185     const Uniform& uni = fUniforms[u.toIndex()];
186     SkASSERT(uni.fType == SkSLType::kInt4 || uni.fType == SkSLType::kShort4);
187     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
188     if (kUnusedUniform != uni.fLocation) {
189         GR_GL_CALL(fGpu->glInterface(), Uniform4i(uni.fLocation, i0, i1, i2, i3));
190     }
191 }
192 
set4iv(UniformHandle u,int arrayCount,const int32_t v[]) const193 void GrGLProgramDataManager::set4iv(UniformHandle u,
194                                     int arrayCount,
195                                     const int32_t v[]) const {
196     const Uniform& uni = fUniforms[u.toIndex()];
197     SkASSERT(uni.fType == SkSLType::kInt4 || uni.fType == SkSLType::kShort4);
198     SkASSERT(arrayCount > 0);
199     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
200     if (kUnusedUniform != uni.fLocation) {
201         GR_GL_CALL(fGpu->glInterface(), Uniform4iv(uni.fLocation, arrayCount, v));
202     }
203 }
204 
set4f(UniformHandle u,float v0,float v1,float v2,float v3) const205 void GrGLProgramDataManager::set4f(UniformHandle u,
206                                    float v0,
207                                    float v1,
208                                    float v2,
209                                    float v3) const {
210     const Uniform& uni = fUniforms[u.toIndex()];
211     SkASSERT(uni.fType == SkSLType::kFloat4 || uni.fType == SkSLType::kHalf4);
212     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
213     if (kUnusedUniform != uni.fLocation) {
214         GR_GL_CALL(fGpu->glInterface(), Uniform4f(uni.fLocation, v0, v1, v2, v3));
215     }
216 }
217 
set4fv(UniformHandle u,int arrayCount,const float v[]) const218 void GrGLProgramDataManager::set4fv(UniformHandle u,
219                                     int arrayCount,
220                                     const float v[]) const {
221     const Uniform& uni = fUniforms[u.toIndex()];
222     SkASSERT(uni.fType == SkSLType::kFloat4 || uni.fType == SkSLType::kHalf4);
223     SkASSERT(arrayCount > 0);
224     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
225     if (kUnusedUniform != uni.fLocation) {
226         GR_GL_CALL(fGpu->glInterface(), Uniform4fv(uni.fLocation, arrayCount, v));
227     }
228 }
229 
setMatrix2f(UniformHandle u,const float matrix[]) const230 void GrGLProgramDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
231     this->setMatrices<2>(u, 1, matrix);
232 }
233 
setMatrix3f(UniformHandle u,const float matrix[]) const234 void GrGLProgramDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
235     this->setMatrices<3>(u, 1, matrix);
236 }
237 
setMatrix4f(UniformHandle u,const float matrix[]) const238 void GrGLProgramDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
239     this->setMatrices<4>(u, 1, matrix);
240 }
241 
setMatrix2fv(UniformHandle u,int arrayCount,const float m[]) const242 void GrGLProgramDataManager::setMatrix2fv(UniformHandle u, int arrayCount, const float m[]) const {
243     this->setMatrices<2>(u, arrayCount, m);
244 }
245 
setMatrix3fv(UniformHandle u,int arrayCount,const float m[]) const246 void GrGLProgramDataManager::setMatrix3fv(UniformHandle u, int arrayCount, const float m[]) const {
247     this->setMatrices<3>(u, arrayCount, m);
248 }
249 
setMatrix4fv(UniformHandle u,int arrayCount,const float m[]) const250 void GrGLProgramDataManager::setMatrix4fv(UniformHandle u, int arrayCount, const float m[]) const {
251     this->setMatrices<4>(u, arrayCount, m);
252 }
253 
254 template<int N> struct set_uniform_matrix;
255 
setMatrices(UniformHandle u,int arrayCount,const float matrices[]) const256 template<int N> inline void GrGLProgramDataManager::setMatrices(UniformHandle u,
257                                                                 int arrayCount,
258                                                                 const float matrices[]) const {
259     const Uniform& uni = fUniforms[u.toIndex()];
260     SkASSERT(static_cast<int>(uni.fType) == static_cast<int>(SkSLType::kFloat2x2) + (N - 2) ||
261              static_cast<int>(uni.fType) == static_cast<int>(SkSLType::kHalf2x2) + (N - 2));
262     SkASSERT(arrayCount > 0);
263     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
264     if (kUnusedUniform != uni.fLocation) {
265         set_uniform_matrix<N>::set(fGpu->glInterface(), uni.fLocation, arrayCount, matrices);
266     }
267 }
268 
269 template<> struct set_uniform_matrix<2> {
setset_uniform_matrix270     inline static void set(const GrGLInterface* gli, const GrGLint loc, int cnt, const float m[]) {
271         GR_GL_CALL(gli, UniformMatrix2fv(loc, cnt, false, m));
272     }
273 };
274 
275 template<> struct set_uniform_matrix<3> {
setset_uniform_matrix276     inline static void set(const GrGLInterface* gli, const GrGLint loc, int cnt, const float m[]) {
277         GR_GL_CALL(gli, UniformMatrix3fv(loc, cnt, false, m));
278     }
279 };
280 
281 template<> struct set_uniform_matrix<4> {
setset_uniform_matrix282     inline static void set(const GrGLInterface* gli, const GrGLint loc, int cnt, const float m[]) {
283         GR_GL_CALL(gli, UniformMatrix4fv(loc, cnt, false, m));
284     }
285 };
286