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 
GrUniformDataManager(uint32_t uniformCount,uint32_t uniformSize)12 GrUniformDataManager::GrUniformDataManager(uint32_t uniformCount, uint32_t uniformSize)
13     : fUniformSize(uniformSize)
14     , fUniformsDirty(false) {
15     fUniformData.reset(uniformSize);
16     fUniforms.push_back_n(uniformCount);
17     // subclasses fill in the uniforms in their constructor
18 }
19 
getBufferPtrAndMarkDirty(const Uniform & uni) const20 void* GrUniformDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
21     fUniformsDirty = true;
22     return static_cast<char*>(fUniformData.get())+uni.fOffset;
23 }
24 
set1i(UniformHandle u,int32_t i) const25 void GrUniformDataManager::set1i(UniformHandle u, int32_t i) const {
26     const Uniform& uni = fUniforms[u.toIndex()];
27     SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
28     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
29     void* buffer = this->getBufferPtrAndMarkDirty(uni);
30     memcpy(buffer, &i, sizeof(int32_t));
31 }
32 
set1iv(UniformHandle u,int arrayCount,const int32_t v[]) const33 void GrUniformDataManager::set1iv(UniformHandle u,
34                                           int arrayCount,
35                                           const int32_t v[]) const {
36     const Uniform& uni = fUniforms[u.toIndex()];
37     SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
38     SkASSERT(arrayCount > 0);
39     SkASSERT(arrayCount <= uni.fArrayCount ||
40              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
41 
42     void* buffer = this->getBufferPtrAndMarkDirty(uni);
43     SkASSERT(sizeof(int32_t) == 4);
44     for (int i = 0; i < arrayCount; ++i) {
45         const int32_t* curVec = &v[i];
46         memcpy(buffer, curVec, sizeof(int32_t));
47         buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
48     }
49 }
50 
set1f(UniformHandle u,float v0) const51 void GrUniformDataManager::set1f(UniformHandle u, float v0) const {
52     const Uniform& uni = fUniforms[u.toIndex()];
53     SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
54     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
55     void* buffer = this->getBufferPtrAndMarkDirty(uni);
56     SkASSERT(sizeof(float) == 4);
57     memcpy(buffer, &v0, sizeof(float));
58 }
59 
set1fv(UniformHandle u,int arrayCount,const float v[]) const60 void GrUniformDataManager::set1fv(UniformHandle u,
61                                           int arrayCount,
62                                           const float v[]) const {
63     const Uniform& uni = fUniforms[u.toIndex()];
64     SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
65     SkASSERT(arrayCount > 0);
66     SkASSERT(arrayCount <= uni.fArrayCount ||
67              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
68 
69     void* buffer = this->getBufferPtrAndMarkDirty(uni);
70     SkASSERT(sizeof(float) == 4);
71     for (int i = 0; i < arrayCount; ++i) {
72         const float* curVec = &v[i];
73         memcpy(buffer, curVec, sizeof(float));
74         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
75     }
76 }
77 
set2i(UniformHandle u,int32_t i0,int32_t i1) const78 void GrUniformDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
79     const Uniform& uni = fUniforms[u.toIndex()];
80     SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
81     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
82     void* buffer = this->getBufferPtrAndMarkDirty(uni);
83     int32_t v[2] = { i0, i1 };
84     memcpy(buffer, v, 2 * sizeof(int32_t));
85 }
86 
set2iv(UniformHandle u,int arrayCount,const int32_t v[]) const87 void GrUniformDataManager::set2iv(UniformHandle u,
88                                           int arrayCount,
89                                           const int32_t v[]) const {
90     const Uniform& uni = fUniforms[u.toIndex()];
91     SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
92     SkASSERT(arrayCount > 0);
93     SkASSERT(arrayCount <= uni.fArrayCount ||
94              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
95 
96     void* buffer = this->getBufferPtrAndMarkDirty(uni);
97     SkASSERT(sizeof(int32_t) == 4);
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     SkASSERT(sizeof(float) == 4);
111     float v[2] = { v0, v1 };
112     memcpy(buffer, v, 2 * sizeof(float));
113 }
114 
set2fv(UniformHandle u,int arrayCount,const float v[]) const115 void GrUniformDataManager::set2fv(UniformHandle u,
116                                           int arrayCount,
117                                           const float v[]) const {
118     const Uniform& uni = fUniforms[u.toIndex()];
119     SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
120     SkASSERT(arrayCount > 0);
121     SkASSERT(arrayCount <= uni.fArrayCount ||
122              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
123 
124     void* buffer = this->getBufferPtrAndMarkDirty(uni);
125     SkASSERT(sizeof(float) == 4);
126     for (int i = 0; i < arrayCount; ++i) {
127         const float* curVec = &v[2 * i];
128         memcpy(buffer, curVec, 2 * sizeof(float));
129         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
130     }
131 }
132 
set3i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2) const133 void GrUniformDataManager::set3i(UniformHandle u,
134                                          int32_t i0,
135                                          int32_t i1,
136                                          int32_t i2) const {
137     const Uniform& uni = fUniforms[u.toIndex()];
138     SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
139     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
140     void* buffer = this->getBufferPtrAndMarkDirty(uni);
141     int32_t v[3] = { i0, i1, i2 };
142     memcpy(buffer, v, 3 * sizeof(int32_t));
143 }
144 
set3iv(UniformHandle u,int arrayCount,const int32_t v[]) const145 void GrUniformDataManager::set3iv(UniformHandle u,
146                                           int arrayCount,
147                                           const int32_t v[]) const {
148     const Uniform& uni = fUniforms[u.toIndex()];
149     SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
150     SkASSERT(arrayCount > 0);
151     SkASSERT(arrayCount <= uni.fArrayCount ||
152              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
153 
154     void* buffer = this->getBufferPtrAndMarkDirty(uni);
155     SkASSERT(sizeof(int32_t) == 4);
156     for (int i = 0; i < arrayCount; ++i) {
157         const int32_t* curVec = &v[3 * i];
158         memcpy(buffer, curVec, 3 * sizeof(int32_t));
159         buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
160     }
161 }
162 
set3f(UniformHandle u,float v0,float v1,float v2) const163 void GrUniformDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
164     const Uniform& uni = fUniforms[u.toIndex()];
165     SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
166     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
167     void* buffer = this->getBufferPtrAndMarkDirty(uni);
168     SkASSERT(sizeof(float) == 4);
169     float v[3] = { v0, v1, v2 };
170     memcpy(buffer, v, 3 * sizeof(float));
171 }
172 
set3fv(UniformHandle u,int arrayCount,const float v[]) const173 void GrUniformDataManager::set3fv(UniformHandle u,
174                                           int arrayCount,
175                                           const float v[]) const {
176     const Uniform& uni = fUniforms[u.toIndex()];
177     SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
178     SkASSERT(arrayCount > 0);
179     SkASSERT(arrayCount <= uni.fArrayCount ||
180              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
181 
182     void* buffer = this->getBufferPtrAndMarkDirty(uni);
183     SkASSERT(sizeof(float) == 4);
184     for (int i = 0; i < arrayCount; ++i) {
185         const float* curVec = &v[3 * i];
186         memcpy(buffer, curVec, 3 * sizeof(float));
187         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
188     }
189 }
190 
set4i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2,int32_t i3) const191 void GrUniformDataManager::set4i(UniformHandle u,
192                                          int32_t i0,
193                                          int32_t i1,
194                                          int32_t i2,
195                                          int32_t i3) const {
196     const Uniform& uni = fUniforms[u.toIndex()];
197     SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
198     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
199     void* buffer = this->getBufferPtrAndMarkDirty(uni);
200     int32_t v[4] = { i0, i1, i2, i3 };
201     memcpy(buffer, v, 4 * sizeof(int32_t));
202 }
203 
set4iv(UniformHandle u,int arrayCount,const int32_t v[]) const204 void GrUniformDataManager::set4iv(UniformHandle u,
205                                           int arrayCount,
206                                           const int32_t v[]) const {
207     const Uniform& uni = fUniforms[u.toIndex()];
208     SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
209     SkASSERT(arrayCount > 0);
210     SkASSERT(arrayCount <= uni.fArrayCount ||
211              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
212 
213     void* buffer = this->getBufferPtrAndMarkDirty(uni);
214     SkASSERT(sizeof(int32_t) == 4);
215     for (int i = 0; i < arrayCount; ++i) {
216         const int32_t* curVec = &v[4 * i];
217         memcpy(buffer, curVec, 4 * sizeof(int32_t));
218         buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
219     }
220 }
221 
set4f(UniformHandle u,float v0,float v1,float v2,float v3) const222 void GrUniformDataManager::set4f(UniformHandle u,
223                                          float v0,
224                                          float v1,
225                                          float v2,
226                                          float v3) const {
227     const Uniform& uni = fUniforms[u.toIndex()];
228     SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
229     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
230     void* buffer = this->getBufferPtrAndMarkDirty(uni);
231     SkASSERT(sizeof(float) == 4);
232     float v[4] = { v0, v1, v2, v3 };
233     memcpy(buffer, v, 4 * sizeof(float));
234 }
235 
set4fv(UniformHandle u,int arrayCount,const float v[]) const236 void GrUniformDataManager::set4fv(UniformHandle u,
237                                           int arrayCount,
238                                           const float v[]) const {
239     const Uniform& uni = fUniforms[u.toIndex()];
240     SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
241     SkASSERT(arrayCount > 0);
242     SkASSERT(arrayCount <= uni.fArrayCount ||
243              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
244 
245     void* buffer = this->getBufferPtrAndMarkDirty(uni);
246     SkASSERT(sizeof(float) == 4);
247     memcpy(buffer, v, arrayCount * 4 * sizeof(float));
248 }
249 
setMatrix2f(UniformHandle u,const float matrix[]) const250 void GrUniformDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
251     this->setMatrices<2>(u, 1, matrix);
252 }
253 
setMatrix2fv(UniformHandle u,int arrayCount,const float m[]) const254 void GrUniformDataManager::setMatrix2fv(UniformHandle u,
255                                                 int arrayCount,
256                                                 const float m[]) const {
257     this->setMatrices<2>(u, arrayCount, m);
258 }
259 
setMatrix3f(UniformHandle u,const float matrix[]) const260 void GrUniformDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
261     this->setMatrices<3>(u, 1, matrix);
262 }
263 
setMatrix3fv(UniformHandle u,int arrayCount,const float m[]) const264 void GrUniformDataManager::setMatrix3fv(UniformHandle u,
265                                                 int arrayCount,
266                                                 const float m[]) const {
267     this->setMatrices<3>(u, arrayCount, m);
268 }
269 
setMatrix4f(UniformHandle u,const float matrix[]) const270 void GrUniformDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
271     this->setMatrices<4>(u, 1, matrix);
272 }
273 
setMatrix4fv(UniformHandle u,int arrayCount,const float m[]) const274 void GrUniformDataManager::setMatrix4fv(UniformHandle u,
275                                                 int arrayCount,
276                                                 const float m[]) const {
277     this->setMatrices<4>(u, arrayCount, m);
278 }
279 
280 template<int N> struct set_uniform_matrix;
281 
setMatrices(UniformHandle u,int arrayCount,const float matrices[]) const282 template<int N> inline void GrUniformDataManager::setMatrices(UniformHandle u,
283                                                                       int arrayCount,
284                                                                      const float matrices[]) const {
285     const Uniform& uni = fUniforms[u.toIndex()];
286     SkASSERT(uni.fType == kFloat2x2_GrSLType + (N - 2) ||
287              uni.fType == kHalf2x2_GrSLType + (N - 2));
288     SkASSERT(arrayCount > 0);
289     SkASSERT(arrayCount <= uni.fArrayCount ||
290              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
291 
292     void* buffer = fUniformData.get();
293     fUniformsDirty = true;
294 
295     set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices);
296 }
297 
298 template<int N> struct set_uniform_matrix {
setset_uniform_matrix299     inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
300         static_assert(sizeof(float) == 4);
301         buffer = static_cast<char*>(buffer) + uniformOffset;
302         for (int i = 0; i < count; ++i) {
303             const float* matrix = &matrices[N * N * i];
304             for (int j = 0; j < N; ++j) {
305                 memcpy(buffer, &matrix[j * N], N * sizeof(float));
306                 buffer = static_cast<char*>(buffer) + 4 * sizeof(float);
307             }
308         }
309     }
310 };
311 
312 template<> struct set_uniform_matrix<4> {
setset_uniform_matrix313     inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
314         static_assert(sizeof(float) == 4);
315         buffer = static_cast<char*>(buffer) + uniformOffset;
316         memcpy(buffer, matrices, count * 16 * sizeof(float));
317     }
318 };
319 
320