xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrUniformDataManager.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2020 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrUniformDataManager.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkHalf.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkSLTypeShared.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrShaderVar.h"
15*c8dee2aaSAndroid Build Coastguard Worker 
16*c8dee2aaSAndroid Build Coastguard Worker #include <cstring>
17*c8dee2aaSAndroid Build Coastguard Worker 
18*c8dee2aaSAndroid Build Coastguard Worker // ensure that these types are the sizes the uniform data is expecting
19*c8dee2aaSAndroid Build Coastguard Worker static_assert(sizeof(int32_t) == 4);
20*c8dee2aaSAndroid Build Coastguard Worker static_assert(sizeof(float) == 4);
21*c8dee2aaSAndroid Build Coastguard Worker static_assert(sizeof(short) == 2);
22*c8dee2aaSAndroid Build Coastguard Worker static_assert(sizeof(SkHalf) == 2);
23*c8dee2aaSAndroid Build Coastguard Worker 
GrUniformDataManager(uint32_t uniformCount,uint32_t uniformSize)24*c8dee2aaSAndroid Build Coastguard Worker GrUniformDataManager::GrUniformDataManager(uint32_t uniformCount, uint32_t uniformSize)
25*c8dee2aaSAndroid Build Coastguard Worker     : fUniformSize(uniformSize)
26*c8dee2aaSAndroid Build Coastguard Worker     , fUniformsDirty(false) {
27*c8dee2aaSAndroid Build Coastguard Worker     fUniformData.reset(uniformSize);
28*c8dee2aaSAndroid Build Coastguard Worker     fUniforms.push_back_n(uniformCount);
29*c8dee2aaSAndroid Build Coastguard Worker     // subclasses fill in the uniforms in their constructor
30*c8dee2aaSAndroid Build Coastguard Worker }
31*c8dee2aaSAndroid Build Coastguard Worker 
getBufferPtrAndMarkDirty(const Uniform & uni) const32*c8dee2aaSAndroid Build Coastguard Worker void* GrUniformDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
33*c8dee2aaSAndroid Build Coastguard Worker     fUniformsDirty = true;
34*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<char*>(fUniformData.get()) + uni.fOffset;
35*c8dee2aaSAndroid Build Coastguard Worker }
36*c8dee2aaSAndroid Build Coastguard Worker 
copyUniforms(void * dest,const void * src,int numUniforms,SkSLType uniformType) const37*c8dee2aaSAndroid Build Coastguard Worker int GrUniformDataManager::copyUniforms(void* dest,
38*c8dee2aaSAndroid Build Coastguard Worker                                        const void* src,
39*c8dee2aaSAndroid Build Coastguard Worker                                        int numUniforms,
40*c8dee2aaSAndroid Build Coastguard Worker                                        SkSLType uniformType) const {
41*c8dee2aaSAndroid Build Coastguard Worker     if (fWrite16BitUniforms) {
42*c8dee2aaSAndroid Build Coastguard Worker         switch (uniformType) {
43*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kHalf:
44*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kHalf2:
45*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kHalf3:
46*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kHalf4:
47*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kHalf2x2:
48*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kHalf3x3:
49*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kHalf4x4: {
50*c8dee2aaSAndroid Build Coastguard Worker                 const float* floatBits = static_cast<const float*>(src);
51*c8dee2aaSAndroid Build Coastguard Worker                 SkHalf* halfBits = static_cast<SkHalf*>(dest);
52*c8dee2aaSAndroid Build Coastguard Worker                 while (numUniforms-- > 0) {
53*c8dee2aaSAndroid Build Coastguard Worker                     *halfBits++ = SkFloatToHalf(*floatBits++);
54*c8dee2aaSAndroid Build Coastguard Worker                 }
55*c8dee2aaSAndroid Build Coastguard Worker                 return 2;
56*c8dee2aaSAndroid Build Coastguard Worker             }
57*c8dee2aaSAndroid Build Coastguard Worker 
58*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kShort:
59*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kShort2:
60*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kShort3:
61*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kShort4:
62*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kUShort:
63*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kUShort2:
64*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kUShort3:
65*c8dee2aaSAndroid Build Coastguard Worker             case SkSLType::kUShort4: {
66*c8dee2aaSAndroid Build Coastguard Worker                 const int32_t* intBits = static_cast<const int32_t*>(src);
67*c8dee2aaSAndroid Build Coastguard Worker                 short* shortBits = static_cast<short*>(dest);
68*c8dee2aaSAndroid Build Coastguard Worker                 while (numUniforms-- > 0) {
69*c8dee2aaSAndroid Build Coastguard Worker                     *shortBits++ = (short)(*intBits++);
70*c8dee2aaSAndroid Build Coastguard Worker                 }
71*c8dee2aaSAndroid Build Coastguard Worker                 return 2;
72*c8dee2aaSAndroid Build Coastguard Worker             }
73*c8dee2aaSAndroid Build Coastguard Worker 
74*c8dee2aaSAndroid Build Coastguard Worker             default:
75*c8dee2aaSAndroid Build Coastguard Worker                 // Fall through to memcpy below.
76*c8dee2aaSAndroid Build Coastguard Worker                 break;
77*c8dee2aaSAndroid Build Coastguard Worker         }
78*c8dee2aaSAndroid Build Coastguard Worker     }
79*c8dee2aaSAndroid Build Coastguard Worker 
80*c8dee2aaSAndroid Build Coastguard Worker     memcpy(dest, src, numUniforms * 4);
81*c8dee2aaSAndroid Build Coastguard Worker     return 4;
82*c8dee2aaSAndroid Build Coastguard Worker }
83*c8dee2aaSAndroid Build Coastguard Worker 
84*c8dee2aaSAndroid Build Coastguard Worker template <int N, SkSLType FullType, SkSLType HalfType>
set(UniformHandle u,const void * v) const85*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set(UniformHandle u, const void* v) const {
86*c8dee2aaSAndroid Build Coastguard Worker     const Uniform& uni = fUniforms[u.toIndex()];
87*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(uni.fType == FullType || uni.fType == HalfType);
88*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
89*c8dee2aaSAndroid Build Coastguard Worker     void* buffer = this->getBufferPtrAndMarkDirty(uni);
90*c8dee2aaSAndroid Build Coastguard Worker     this->copyUniforms(buffer, v, N, uni.fType);
91*c8dee2aaSAndroid Build Coastguard Worker }
92*c8dee2aaSAndroid Build Coastguard Worker 
93*c8dee2aaSAndroid Build Coastguard Worker template <int N, SkSLType FullType, SkSLType HalfType>
setv(UniformHandle u,int arrayCount,const void * v) const94*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::setv(UniformHandle u, int arrayCount, const void* v) const {
95*c8dee2aaSAndroid Build Coastguard Worker     const Uniform& uni = fUniforms[u.toIndex()];
96*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(uni.fType == FullType || uni.fType == HalfType);
97*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(arrayCount > 0);
98*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(arrayCount <= uni.fArrayCount ||
99*c8dee2aaSAndroid Build Coastguard Worker              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
100*c8dee2aaSAndroid Build Coastguard Worker 
101*c8dee2aaSAndroid Build Coastguard Worker     void* buffer = this->getBufferPtrAndMarkDirty(uni);
102*c8dee2aaSAndroid Build Coastguard Worker     if constexpr (N == 4) {
103*c8dee2aaSAndroid Build Coastguard Worker         this->copyUniforms(buffer, v, arrayCount * 4, uni.fType);
104*c8dee2aaSAndroid Build Coastguard Worker     } else {
105*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < arrayCount; ++i) {
106*c8dee2aaSAndroid Build Coastguard Worker             int uniformSize = this->copyUniforms(buffer, v, N, uni.fType);
107*c8dee2aaSAndroid Build Coastguard Worker             buffer = SkTAddOffset<void>(buffer, /*numUniforms*/4 * uniformSize);
108*c8dee2aaSAndroid Build Coastguard Worker             v = static_cast<const char*>(v) + N * 4;
109*c8dee2aaSAndroid Build Coastguard Worker         }
110*c8dee2aaSAndroid Build Coastguard Worker     }
111*c8dee2aaSAndroid Build Coastguard Worker }
112*c8dee2aaSAndroid Build Coastguard Worker 
set1i(UniformHandle u,int32_t i0) const113*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set1i(UniformHandle u, int32_t i0) const {
114*c8dee2aaSAndroid Build Coastguard Worker     this->set<1, SkSLType::kInt, SkSLType::kShort>(u, &i0);
115*c8dee2aaSAndroid Build Coastguard Worker }
116*c8dee2aaSAndroid Build Coastguard Worker 
set1iv(UniformHandle u,int arrayCount,const int32_t v[]) const117*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set1iv(UniformHandle u,
118*c8dee2aaSAndroid Build Coastguard Worker                                   int arrayCount,
119*c8dee2aaSAndroid Build Coastguard Worker                                   const int32_t v[]) const {
120*c8dee2aaSAndroid Build Coastguard Worker     this->setv<1, SkSLType::kInt, SkSLType::kShort>(u, arrayCount, v);
121*c8dee2aaSAndroid Build Coastguard Worker }
122*c8dee2aaSAndroid Build Coastguard Worker 
set1f(UniformHandle u,float v0) const123*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set1f(UniformHandle u, float v0) const {
124*c8dee2aaSAndroid Build Coastguard Worker     this->set<1, SkSLType::kFloat, SkSLType::kHalf>(u, &v0);
125*c8dee2aaSAndroid Build Coastguard Worker }
126*c8dee2aaSAndroid Build Coastguard Worker 
set1fv(UniformHandle u,int arrayCount,const float v[]) const127*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set1fv(UniformHandle u,
128*c8dee2aaSAndroid Build Coastguard Worker                                   int arrayCount,
129*c8dee2aaSAndroid Build Coastguard Worker                                   const float v[]) const {
130*c8dee2aaSAndroid Build Coastguard Worker     this->setv<1, SkSLType::kFloat, SkSLType::kHalf>(u, arrayCount, v);
131*c8dee2aaSAndroid Build Coastguard Worker }
132*c8dee2aaSAndroid Build Coastguard Worker 
set2i(UniformHandle u,int32_t i0,int32_t i1) const133*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
134*c8dee2aaSAndroid Build Coastguard Worker     int32_t v[2] = { i0, i1 };
135*c8dee2aaSAndroid Build Coastguard Worker     this->set<2, SkSLType::kInt2, SkSLType::kShort2>(u, v);
136*c8dee2aaSAndroid Build Coastguard Worker }
137*c8dee2aaSAndroid Build Coastguard Worker 
set2iv(UniformHandle u,int arrayCount,const int32_t v[]) const138*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set2iv(UniformHandle u,
139*c8dee2aaSAndroid Build Coastguard Worker                                   int arrayCount,
140*c8dee2aaSAndroid Build Coastguard Worker                                   const int32_t v[]) const {
141*c8dee2aaSAndroid Build Coastguard Worker     this->setv<2, SkSLType::kInt2, SkSLType::kShort2>(u, arrayCount, v);
142*c8dee2aaSAndroid Build Coastguard Worker }
143*c8dee2aaSAndroid Build Coastguard Worker 
set2f(UniformHandle u,float v0,float v1) const144*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set2f(UniformHandle u, float v0, float v1) const {
145*c8dee2aaSAndroid Build Coastguard Worker     float v[2] = { v0, v1 };
146*c8dee2aaSAndroid Build Coastguard Worker     this->set<2, SkSLType::kFloat2, SkSLType::kHalf2>(u, v);
147*c8dee2aaSAndroid Build Coastguard Worker }
148*c8dee2aaSAndroid Build Coastguard Worker 
set2fv(UniformHandle u,int arrayCount,const float v[]) const149*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set2fv(UniformHandle u,
150*c8dee2aaSAndroid Build Coastguard Worker                                   int arrayCount,
151*c8dee2aaSAndroid Build Coastguard Worker                                   const float v[]) const {
152*c8dee2aaSAndroid Build Coastguard Worker     this->setv<2, SkSLType::kFloat2, SkSLType::kHalf2>(u, arrayCount, v);
153*c8dee2aaSAndroid Build Coastguard Worker }
154*c8dee2aaSAndroid Build Coastguard Worker 
set3i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2) const155*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set3i(UniformHandle u,
156*c8dee2aaSAndroid Build Coastguard Worker                                  int32_t i0,
157*c8dee2aaSAndroid Build Coastguard Worker                                  int32_t i1,
158*c8dee2aaSAndroid Build Coastguard Worker                                  int32_t i2) const {
159*c8dee2aaSAndroid Build Coastguard Worker     int32_t v[3] = { i0, i1, i2 };
160*c8dee2aaSAndroid Build Coastguard Worker     this->set<3, SkSLType::kInt3, SkSLType::kShort3>(u, v);
161*c8dee2aaSAndroid Build Coastguard Worker }
162*c8dee2aaSAndroid Build Coastguard Worker 
set3iv(UniformHandle u,int arrayCount,const int32_t v[]) const163*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set3iv(UniformHandle u,
164*c8dee2aaSAndroid Build Coastguard Worker                                   int arrayCount,
165*c8dee2aaSAndroid Build Coastguard Worker                                   const int32_t v[]) const {
166*c8dee2aaSAndroid Build Coastguard Worker     this->setv<3, SkSLType::kInt3, SkSLType::kShort3>(u, arrayCount, v);
167*c8dee2aaSAndroid Build Coastguard Worker }
168*c8dee2aaSAndroid Build Coastguard Worker 
set3f(UniformHandle u,float v0,float v1,float v2) const169*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
170*c8dee2aaSAndroid Build Coastguard Worker     float v[3] = { v0, v1, v2 };
171*c8dee2aaSAndroid Build Coastguard Worker     this->set<3, SkSLType::kFloat3, SkSLType::kHalf3>(u, v);
172*c8dee2aaSAndroid Build Coastguard Worker }
173*c8dee2aaSAndroid Build Coastguard Worker 
set3fv(UniformHandle u,int arrayCount,const float v[]) const174*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set3fv(UniformHandle u,
175*c8dee2aaSAndroid Build Coastguard Worker                                   int arrayCount,
176*c8dee2aaSAndroid Build Coastguard Worker                                   const float v[]) const {
177*c8dee2aaSAndroid Build Coastguard Worker     this->setv<3, SkSLType::kFloat3, SkSLType::kHalf3>(u, arrayCount, v);
178*c8dee2aaSAndroid Build Coastguard Worker }
179*c8dee2aaSAndroid Build Coastguard Worker 
set4i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2,int32_t i3) const180*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set4i(UniformHandle u,
181*c8dee2aaSAndroid Build Coastguard Worker                                  int32_t i0,
182*c8dee2aaSAndroid Build Coastguard Worker                                  int32_t i1,
183*c8dee2aaSAndroid Build Coastguard Worker                                  int32_t i2,
184*c8dee2aaSAndroid Build Coastguard Worker                                  int32_t i3) const {
185*c8dee2aaSAndroid Build Coastguard Worker     int32_t v[4] = { i0, i1, i2, i3 };
186*c8dee2aaSAndroid Build Coastguard Worker     this->set<4, SkSLType::kInt4, SkSLType::kShort4>(u, v);
187*c8dee2aaSAndroid Build Coastguard Worker }
188*c8dee2aaSAndroid Build Coastguard Worker 
set4iv(UniformHandle u,int arrayCount,const int32_t v[]) const189*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set4iv(UniformHandle u,
190*c8dee2aaSAndroid Build Coastguard Worker                                   int arrayCount,
191*c8dee2aaSAndroid Build Coastguard Worker                                   const int32_t v[]) const {
192*c8dee2aaSAndroid Build Coastguard Worker     this->setv<4, SkSLType::kInt4, SkSLType::kShort4>(u, arrayCount, v);
193*c8dee2aaSAndroid Build Coastguard Worker }
194*c8dee2aaSAndroid Build Coastguard Worker 
set4f(UniformHandle u,float v0,float v1,float v2,float v3) const195*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set4f(UniformHandle u,
196*c8dee2aaSAndroid Build Coastguard Worker                                  float v0,
197*c8dee2aaSAndroid Build Coastguard Worker                                  float v1,
198*c8dee2aaSAndroid Build Coastguard Worker                                  float v2,
199*c8dee2aaSAndroid Build Coastguard Worker                                  float v3) const {
200*c8dee2aaSAndroid Build Coastguard Worker     float v[4] = { v0, v1, v2, v3 };
201*c8dee2aaSAndroid Build Coastguard Worker     this->set<4, SkSLType::kFloat4, SkSLType::kHalf4>(u, v);
202*c8dee2aaSAndroid Build Coastguard Worker }
203*c8dee2aaSAndroid Build Coastguard Worker 
set4fv(UniformHandle u,int arrayCount,const float v[]) const204*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::set4fv(UniformHandle u,
205*c8dee2aaSAndroid Build Coastguard Worker                                   int arrayCount,
206*c8dee2aaSAndroid Build Coastguard Worker                                   const float v[]) const {
207*c8dee2aaSAndroid Build Coastguard Worker     this->setv<4, SkSLType::kFloat4, SkSLType::kHalf4>(u, arrayCount, v);
208*c8dee2aaSAndroid Build Coastguard Worker }
209*c8dee2aaSAndroid Build Coastguard Worker 
setMatrix2f(UniformHandle u,const float matrix[]) const210*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
211*c8dee2aaSAndroid Build Coastguard Worker     this->setMatrices<2, SkSLType::kFloat2x2, SkSLType::kHalf2x2>(u, 1, matrix);
212*c8dee2aaSAndroid Build Coastguard Worker }
213*c8dee2aaSAndroid Build Coastguard Worker 
setMatrix2fv(UniformHandle u,int arrayCount,const float m[]) const214*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::setMatrix2fv(UniformHandle u, int arrayCount, const float m[]) const {
215*c8dee2aaSAndroid Build Coastguard Worker     this->setMatrices<2, SkSLType::kFloat2x2, SkSLType::kHalf2x2>(u, arrayCount, m);
216*c8dee2aaSAndroid Build Coastguard Worker }
217*c8dee2aaSAndroid Build Coastguard Worker 
setMatrix3f(UniformHandle u,const float matrix[]) const218*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
219*c8dee2aaSAndroid Build Coastguard Worker     this->setMatrices<3, SkSLType::kFloat3x3, SkSLType::kHalf3x3>(u, 1, matrix);
220*c8dee2aaSAndroid Build Coastguard Worker }
221*c8dee2aaSAndroid Build Coastguard Worker 
setMatrix3fv(UniformHandle u,int arrayCount,const float m[]) const222*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::setMatrix3fv(UniformHandle u, int arrayCount, const float m[]) const {
223*c8dee2aaSAndroid Build Coastguard Worker     this->setMatrices<3, SkSLType::kFloat3x3, SkSLType::kHalf3x3>(u, arrayCount, m);
224*c8dee2aaSAndroid Build Coastguard Worker }
225*c8dee2aaSAndroid Build Coastguard Worker 
setMatrix4f(UniformHandle u,const float matrix[]) const226*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
227*c8dee2aaSAndroid Build Coastguard Worker     this->setMatrices<4, SkSLType::kFloat4x4, SkSLType::kHalf4x4>(u, 1, matrix);
228*c8dee2aaSAndroid Build Coastguard Worker }
229*c8dee2aaSAndroid Build Coastguard Worker 
setMatrix4fv(UniformHandle u,int arrayCount,const float m[]) const230*c8dee2aaSAndroid Build Coastguard Worker void GrUniformDataManager::setMatrix4fv(UniformHandle u, int arrayCount, const float m[]) const {
231*c8dee2aaSAndroid Build Coastguard Worker     this->setMatrices<4, SkSLType::kFloat4x4, SkSLType::kHalf4x4>(u, arrayCount, m);
232*c8dee2aaSAndroid Build Coastguard Worker }
233*c8dee2aaSAndroid Build Coastguard Worker 
234*c8dee2aaSAndroid Build Coastguard Worker template <int N, SkSLType FullType, SkSLType HalfType>
setMatrices(UniformHandle u,int arrayCount,const float matrices[]) const235*c8dee2aaSAndroid Build Coastguard Worker inline void GrUniformDataManager::setMatrices(UniformHandle u,
236*c8dee2aaSAndroid Build Coastguard Worker                                               int arrayCount,
237*c8dee2aaSAndroid Build Coastguard Worker                                               const float matrices[]) const {
238*c8dee2aaSAndroid Build Coastguard Worker     const Uniform& uni = fUniforms[u.toIndex()];
239*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(uni.fType == FullType || uni.fType == HalfType);
240*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(arrayCount > 0);
241*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(arrayCount <= uni.fArrayCount ||
242*c8dee2aaSAndroid Build Coastguard Worker              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
243*c8dee2aaSAndroid Build Coastguard Worker 
244*c8dee2aaSAndroid Build Coastguard Worker     void* buffer = this->getBufferPtrAndMarkDirty(uni);
245*c8dee2aaSAndroid Build Coastguard Worker     if constexpr (N == 4) {
246*c8dee2aaSAndroid Build Coastguard Worker         this->copyUniforms(buffer, matrices, arrayCount * 16, uni.fType);
247*c8dee2aaSAndroid Build Coastguard Worker     } else {
248*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < arrayCount; ++i) {
249*c8dee2aaSAndroid Build Coastguard Worker             const float* matrix = &matrices[N * N * i];
250*c8dee2aaSAndroid Build Coastguard Worker             for (int j = 0; j < N; ++j) {
251*c8dee2aaSAndroid Build Coastguard Worker                 int uniformSize = this->copyUniforms(buffer, &matrix[j * N], N, uni.fType);
252*c8dee2aaSAndroid Build Coastguard Worker                 buffer = SkTAddOffset<void>(buffer, /*numUniforms*/4 * uniformSize);
253*c8dee2aaSAndroid Build Coastguard Worker             }
254*c8dee2aaSAndroid Build Coastguard Worker         }
255*c8dee2aaSAndroid Build Coastguard Worker     }
256*c8dee2aaSAndroid Build Coastguard Worker }
257