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 | 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 | |
20 | void* GrUniformDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const { |
21 | fUniformsDirty = true; |
22 | return static_cast<char*>(fUniformData.get())+uni.fOffset; |
23 | } |
24 | |
25 | 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 | |
33 | 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 | |
51 | 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 | |
60 | 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 | |
78 | 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 | |
87 | 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 | |
105 | 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 | |
115 | 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 | |
133 | 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 | |
145 | 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 | |
163 | 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 | |
173 | 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 | |
191 | 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 | |
204 | 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 | |
222 | 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 | |
236 | 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 | |
250 | void GrUniformDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const { |
251 | this->setMatrices<2>(u, 1, matrix); |
252 | } |
253 | |
254 | void GrUniformDataManager::setMatrix2fv(UniformHandle u, |
255 | int arrayCount, |
256 | const float m[]) const { |
257 | this->setMatrices<2>(u, arrayCount, m); |
258 | } |
259 | |
260 | void GrUniformDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const { |
261 | this->setMatrices<3>(u, 1, matrix); |
262 | } |
263 | |
264 | void GrUniformDataManager::setMatrix3fv(UniformHandle u, |
265 | int arrayCount, |
266 | const float m[]) const { |
267 | this->setMatrices<3>(u, arrayCount, m); |
268 | } |
269 | |
270 | void GrUniformDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const { |
271 | this->setMatrices<4>(u, 1, matrix); |
272 | } |
273 | |
274 | 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 | |
282 | 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 { |
299 | 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> { |
313 | 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 | |