• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 Google LLC
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 "src/gpu/GrUniformDataManager.h"
9 
10 #include "src/gpu/GrShaderVar.h"
11 
12 // ensure that these types are the sizes the uniform data is expecting
13 static_assert(sizeof(int32_t) == 4);
14 static_assert(sizeof(float) == 4);
15 
GrUniformDataManager(uint32_t uniformCount,uint32_t uniformSize)16 GrUniformDataManager::GrUniformDataManager(uint32_t uniformCount, uint32_t uniformSize)
17     : fUniformSize(uniformSize)
18     , fUniformsDirty(false) {
19     fUniformData.reset(uniformSize);
20     fUniforms.push_back_n(uniformCount);
21     // subclasses fill in the uniforms in their constructor
22 }
23 
getBufferPtrAndMarkDirty(const Uniform & uni) const24 void* GrUniformDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
25     fUniformsDirty = true;
26     return static_cast<char*>(fUniformData.get())+uni.fOffset;
27 }
28 
set1i(UniformHandle u,int32_t i) const29 void GrUniformDataManager::set1i(UniformHandle u, int32_t i) const {
30     const Uniform& uni = fUniforms[u.toIndex()];
31     SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
32     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
33     void* buffer = this->getBufferPtrAndMarkDirty(uni);
34     memcpy(buffer, &i, sizeof(int32_t));
35 }
36 
set1iv(UniformHandle u,int arrayCount,const int32_t v[]) const37 void GrUniformDataManager::set1iv(UniformHandle u,
38                                           int arrayCount,
39                                           const int32_t v[]) const {
40     const Uniform& uni = fUniforms[u.toIndex()];
41     SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
42     SkASSERT(arrayCount > 0);
43     SkASSERT(arrayCount <= uni.fArrayCount ||
44              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
45 
46     void* buffer = this->getBufferPtrAndMarkDirty(uni);
47     for (int i = 0; i < arrayCount; ++i) {
48         const int32_t* curVec = &v[i];
49         memcpy(buffer, curVec, sizeof(int32_t));
50         buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
51     }
52 }
53 
set1f(UniformHandle u,float v0) const54 void GrUniformDataManager::set1f(UniformHandle u, float v0) const {
55     const Uniform& uni = fUniforms[u.toIndex()];
56     SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
57     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
58     void* buffer = this->getBufferPtrAndMarkDirty(uni);
59     memcpy(buffer, &v0, sizeof(float));
60 }
61 
set1fv(UniformHandle u,int arrayCount,const float v[]) const62 void GrUniformDataManager::set1fv(UniformHandle u,
63                                           int arrayCount,
64                                           const float v[]) const {
65     const Uniform& uni = fUniforms[u.toIndex()];
66     SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
67     SkASSERT(arrayCount > 0);
68     SkASSERT(arrayCount <= uni.fArrayCount ||
69              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
70 
71     void* buffer = this->getBufferPtrAndMarkDirty(uni);
72     for (int i = 0; i < arrayCount; ++i) {
73         const float* curVec = &v[i];
74         memcpy(buffer, curVec, sizeof(float));
75         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
76     }
77 }
78 
set2i(UniformHandle u,int32_t i0,int32_t i1) const79 void GrUniformDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
80     const Uniform& uni = fUniforms[u.toIndex()];
81     SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
82     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
83     void* buffer = this->getBufferPtrAndMarkDirty(uni);
84     int32_t v[2] = { i0, i1 };
85     memcpy(buffer, v, 2 * sizeof(int32_t));
86 }
87 
set2iv(UniformHandle u,int arrayCount,const int32_t v[]) const88 void GrUniformDataManager::set2iv(UniformHandle u,
89                                           int arrayCount,
90                                           const int32_t v[]) const {
91     const Uniform& uni = fUniforms[u.toIndex()];
92     SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
93     SkASSERT(arrayCount > 0);
94     SkASSERT(arrayCount <= uni.fArrayCount ||
95              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
96 
97     void* buffer = this->getBufferPtrAndMarkDirty(uni);
98     for (int i = 0; i < arrayCount; ++i) {
99         const int32_t* curVec = &v[2 * i];
100         memcpy(buffer, curVec, 2 * sizeof(int32_t));
101         buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
102     }
103 }
104 
set2f(UniformHandle u,float v0,float v1) const105 void GrUniformDataManager::set2f(UniformHandle u, float v0, float v1) const {
106     const Uniform& uni = fUniforms[u.toIndex()];
107     SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
108     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
109     void* buffer = this->getBufferPtrAndMarkDirty(uni);
110     float v[2] = { v0, v1 };
111     memcpy(buffer, v, 2 * sizeof(float));
112 }
113 
set2fv(UniformHandle u,int arrayCount,const float v[]) const114 void GrUniformDataManager::set2fv(UniformHandle u,
115                                           int arrayCount,
116                                           const float v[]) const {
117     const Uniform& uni = fUniforms[u.toIndex()];
118     SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
119     SkASSERT(arrayCount > 0);
120     SkASSERT(arrayCount <= uni.fArrayCount ||
121              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
122 
123     void* buffer = this->getBufferPtrAndMarkDirty(uni);
124     for (int i = 0; i < arrayCount; ++i) {
125         const float* curVec = &v[2 * i];
126         memcpy(buffer, curVec, 2 * sizeof(float));
127         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
128     }
129 }
130 
set3i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2) const131 void GrUniformDataManager::set3i(UniformHandle u,
132                                          int32_t i0,
133                                          int32_t i1,
134                                          int32_t i2) const {
135     const Uniform& uni = fUniforms[u.toIndex()];
136     SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
137     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
138     void* buffer = this->getBufferPtrAndMarkDirty(uni);
139     int32_t v[3] = { i0, i1, i2 };
140     memcpy(buffer, v, 3 * sizeof(int32_t));
141 }
142 
set3iv(UniformHandle u,int arrayCount,const int32_t v[]) const143 void GrUniformDataManager::set3iv(UniformHandle u,
144                                           int arrayCount,
145                                           const int32_t v[]) const {
146     const Uniform& uni = fUniforms[u.toIndex()];
147     SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
148     SkASSERT(arrayCount > 0);
149     SkASSERT(arrayCount <= uni.fArrayCount ||
150              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
151 
152     void* buffer = this->getBufferPtrAndMarkDirty(uni);
153     for (int i = 0; i < arrayCount; ++i) {
154         const int32_t* curVec = &v[3 * i];
155         memcpy(buffer, curVec, 3 * sizeof(int32_t));
156         buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
157     }
158 }
159 
set3f(UniformHandle u,float v0,float v1,float v2) const160 void GrUniformDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
161     const Uniform& uni = fUniforms[u.toIndex()];
162     SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
163     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
164     void* buffer = this->getBufferPtrAndMarkDirty(uni);
165     float v[3] = { v0, v1, v2 };
166     memcpy(buffer, v, 3 * sizeof(float));
167 }
168 
set3fv(UniformHandle u,int arrayCount,const float v[]) const169 void GrUniformDataManager::set3fv(UniformHandle u,
170                                           int arrayCount,
171                                           const float v[]) const {
172     const Uniform& uni = fUniforms[u.toIndex()];
173     SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
174     SkASSERT(arrayCount > 0);
175     SkASSERT(arrayCount <= uni.fArrayCount ||
176              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
177 
178     void* buffer = this->getBufferPtrAndMarkDirty(uni);
179     for (int i = 0; i < arrayCount; ++i) {
180         const float* curVec = &v[3 * i];
181         memcpy(buffer, curVec, 3 * sizeof(float));
182         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
183     }
184 }
185 
set4i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2,int32_t i3) const186 void GrUniformDataManager::set4i(UniformHandle u,
187                                          int32_t i0,
188                                          int32_t i1,
189                                          int32_t i2,
190                                          int32_t i3) const {
191     const Uniform& uni = fUniforms[u.toIndex()];
192     SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
193     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
194     void* buffer = this->getBufferPtrAndMarkDirty(uni);
195     int32_t v[4] = { i0, i1, i2, i3 };
196     memcpy(buffer, v, 4 * sizeof(int32_t));
197 }
198 
set4iv(UniformHandle u,int arrayCount,const int32_t v[]) const199 void GrUniformDataManager::set4iv(UniformHandle u,
200                                           int arrayCount,
201                                           const int32_t v[]) const {
202     const Uniform& uni = fUniforms[u.toIndex()];
203     SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
204     SkASSERT(arrayCount > 0);
205     SkASSERT(arrayCount <= uni.fArrayCount ||
206              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
207 
208     void* buffer = this->getBufferPtrAndMarkDirty(uni);
209     memcpy(buffer, v, arrayCount * 4 * sizeof(int32_t));
210 }
211 
set4f(UniformHandle u,float v0,float v1,float v2,float v3) const212 void GrUniformDataManager::set4f(UniformHandle u,
213                                          float v0,
214                                          float v1,
215                                          float v2,
216                                          float v3) const {
217     const Uniform& uni = fUniforms[u.toIndex()];
218     SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
219     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
220     void* buffer = this->getBufferPtrAndMarkDirty(uni);
221     float v[4] = { v0, v1, v2, v3 };
222     memcpy(buffer, v, 4 * sizeof(float));
223 }
224 
set4fv(UniformHandle u,int arrayCount,const float v[]) const225 void GrUniformDataManager::set4fv(UniformHandle u,
226                                           int arrayCount,
227                                           const float v[]) const {
228     const Uniform& uni = fUniforms[u.toIndex()];
229     SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
230     SkASSERT(arrayCount > 0);
231     SkASSERT(arrayCount <= uni.fArrayCount ||
232              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
233 
234     void* buffer = this->getBufferPtrAndMarkDirty(uni);
235     memcpy(buffer, v, arrayCount * 4 * sizeof(float));
236 }
237 
setMatrix2f(UniformHandle u,const float matrix[]) const238 void GrUniformDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
239     this->setMatrices<2>(u, 1, matrix);
240 }
241 
setMatrix2fv(UniformHandle u,int arrayCount,const float m[]) const242 void GrUniformDataManager::setMatrix2fv(UniformHandle u, int arrayCount, const float m[]) const {
243     this->setMatrices<2>(u, arrayCount, m);
244 }
245 
setMatrix3f(UniformHandle u,const float matrix[]) const246 void GrUniformDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
247     this->setMatrices<3>(u, 1, matrix);
248 }
249 
setMatrix3fv(UniformHandle u,int arrayCount,const float m[]) const250 void GrUniformDataManager::setMatrix3fv(UniformHandle u, int arrayCount, const float m[]) const {
251     this->setMatrices<3>(u, arrayCount, m);
252 }
253 
setMatrix4f(UniformHandle u,const float matrix[]) const254 void GrUniformDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
255     this->setMatrices<4>(u, 1, matrix);
256 }
257 
setMatrix4fv(UniformHandle u,int arrayCount,const float m[]) const258 void GrUniformDataManager::setMatrix4fv(UniformHandle u, int arrayCount, const float m[]) const {
259     this->setMatrices<4>(u, arrayCount, m);
260 }
261 
262 template<int N> struct set_uniform_matrix;
263 
setMatrices(UniformHandle u,int arrayCount,const float matrices[]) const264 template<int N> inline void GrUniformDataManager::setMatrices(UniformHandle u,
265                                                               int arrayCount,
266                                                               const float matrices[]) const {
267     const Uniform& uni = fUniforms[u.toIndex()];
268     SkASSERT(uni.fType == kFloat2x2_GrSLType + (N - 2) ||
269              uni.fType == kHalf2x2_GrSLType + (N - 2));
270     SkASSERT(arrayCount > 0);
271     SkASSERT(arrayCount <= uni.fArrayCount ||
272              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
273 
274     void* buffer = fUniformData.get();
275     fUniformsDirty = true;
276 
277     set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices);
278 }
279 
280 template<int N> struct set_uniform_matrix {
setset_uniform_matrix281     inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
282         buffer = static_cast<char*>(buffer) + uniformOffset;
283         for (int i = 0; i < count; ++i) {
284             const float* matrix = &matrices[N * N * i];
285             for (int j = 0; j < N; ++j) {
286                 memcpy(buffer, &matrix[j * N], N * sizeof(float));
287                 buffer = static_cast<char*>(buffer) + 4 * sizeof(float);
288             }
289         }
290     }
291 };
292 
293 template<> struct set_uniform_matrix<4> {
setset_uniform_matrix294     inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
295         buffer = static_cast<char*>(buffer) + uniformOffset;
296         memcpy(buffer, matrices, count * 16 * sizeof(float));
297     }
298 };
299 
300