• 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/ganesh/GrUniformDataManager.h"
9 
10 #include "src/base/SkHalf.h"
11 #include "src/gpu/ganesh/GrShaderVar.h"
12 
13 // ensure that these types are the sizes the uniform data is expecting
14 static_assert(sizeof(int32_t) == 4);
15 static_assert(sizeof(float) == 4);
16 static_assert(sizeof(short) == 2);
17 static_assert(sizeof(SkHalf) == 2);
18 
GrUniformDataManager(uint32_t uniformCount,uint32_t uniformSize)19 GrUniformDataManager::GrUniformDataManager(uint32_t uniformCount, uint32_t uniformSize)
20     : fUniformSize(uniformSize)
21     , fUniformsDirty(false) {
22     fUniformData.reset(uniformSize);
23     fUniforms.push_back_n(uniformCount);
24     // subclasses fill in the uniforms in their constructor
25 }
26 
getBufferPtrAndMarkDirty(const Uniform & uni) const27 void* GrUniformDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
28     fUniformsDirty = true;
29     return static_cast<char*>(fUniformData.get()) + uni.fOffset;
30 }
31 
copyUniforms(void * dest,const void * src,int numUniforms,SkSLType uniformType) const32 int GrUniformDataManager::copyUniforms(void* dest,
33                                        const void* src,
34                                        int numUniforms,
35                                        SkSLType uniformType) const {
36     if (fWrite16BitUniforms) {
37         switch (uniformType) {
38             case SkSLType::kHalf:
39             case SkSLType::kHalf2:
40             case SkSLType::kHalf3:
41             case SkSLType::kHalf4:
42             case SkSLType::kHalf2x2:
43             case SkSLType::kHalf3x3:
44             case SkSLType::kHalf4x4: {
45                 const float* floatBits = static_cast<const float*>(src);
46                 SkHalf* halfBits = static_cast<SkHalf*>(dest);
47                 while (numUniforms-- > 0) {
48                     *halfBits++ = SkFloatToHalf(*floatBits++);
49                 }
50                 return 2;
51             }
52 
53             case SkSLType::kShort:
54             case SkSLType::kShort2:
55             case SkSLType::kShort3:
56             case SkSLType::kShort4:
57             case SkSLType::kUShort:
58             case SkSLType::kUShort2:
59             case SkSLType::kUShort3:
60             case SkSLType::kUShort4: {
61                 const int32_t* intBits = static_cast<const int32_t*>(src);
62                 short* shortBits = static_cast<short*>(dest);
63                 while (numUniforms-- > 0) {
64                     *shortBits++ = (short)(*intBits++);
65                 }
66                 return 2;
67             }
68 
69             default:
70                 // Fall through to memcpy below.
71                 break;
72         }
73     }
74 
75     memcpy(dest, src, numUniforms * 4);
76     return 4;
77 }
78 
79 template <int N, SkSLType FullType, SkSLType HalfType>
set(UniformHandle u,const void * v) const80 void GrUniformDataManager::set(UniformHandle u, const void* v) const {
81     const Uniform& uni = fUniforms[u.toIndex()];
82     SkASSERT(uni.fType == FullType || uni.fType == HalfType);
83     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
84     void* buffer = this->getBufferPtrAndMarkDirty(uni);
85     this->copyUniforms(buffer, v, N, uni.fType);
86 }
87 
88 template <int N, SkSLType FullType, SkSLType HalfType>
setv(UniformHandle u,int arrayCount,const void * v) const89 void GrUniformDataManager::setv(UniformHandle u, int arrayCount, const void* v) const {
90     const Uniform& uni = fUniforms[u.toIndex()];
91     SkASSERT(uni.fType == FullType || uni.fType == HalfType);
92     SkASSERT(arrayCount > 0);
93     SkASSERT(arrayCount <= uni.fArrayCount ||
94              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
95 
96     void* buffer = this->getBufferPtrAndMarkDirty(uni);
97     if constexpr (N == 4) {
98         this->copyUniforms(buffer, v, arrayCount * 4, uni.fType);
99     } else {
100         for (int i = 0; i < arrayCount; ++i) {
101             int uniformSize = this->copyUniforms(buffer, v, N, uni.fType);
102             buffer = SkTAddOffset<void>(buffer, /*numUniforms*/4 * uniformSize);
103             v = static_cast<const char*>(v) + N * 4;
104         }
105     }
106 }
107 
set1i(UniformHandle u,int32_t i0) const108 void GrUniformDataManager::set1i(UniformHandle u, int32_t i0) const {
109     this->set<1, SkSLType::kInt, SkSLType::kShort>(u, &i0);
110 }
111 
set1iv(UniformHandle u,int arrayCount,const int32_t v[]) const112 void GrUniformDataManager::set1iv(UniformHandle u,
113                                   int arrayCount,
114                                   const int32_t v[]) const {
115     this->setv<1, SkSLType::kInt, SkSLType::kShort>(u, arrayCount, v);
116 }
117 
set1f(UniformHandle u,float v0) const118 void GrUniformDataManager::set1f(UniformHandle u, float v0) const {
119     this->set<1, SkSLType::kFloat, SkSLType::kHalf>(u, &v0);
120 }
121 
set1fv(UniformHandle u,int arrayCount,const float v[]) const122 void GrUniformDataManager::set1fv(UniformHandle u,
123                                   int arrayCount,
124                                   const float v[]) const {
125     this->setv<1, SkSLType::kFloat, SkSLType::kHalf>(u, arrayCount, v);
126 }
127 
set2i(UniformHandle u,int32_t i0,int32_t i1) const128 void GrUniformDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
129     int32_t v[2] = { i0, i1 };
130     this->set<2, SkSLType::kInt2, SkSLType::kShort2>(u, v);
131 }
132 
set2iv(UniformHandle u,int arrayCount,const int32_t v[]) const133 void GrUniformDataManager::set2iv(UniformHandle u,
134                                   int arrayCount,
135                                   const int32_t v[]) const {
136     this->setv<2, SkSLType::kInt2, SkSLType::kShort2>(u, arrayCount, v);
137 }
138 
set2f(UniformHandle u,float v0,float v1) const139 void GrUniformDataManager::set2f(UniformHandle u, float v0, float v1) const {
140     float v[2] = { v0, v1 };
141     this->set<2, SkSLType::kFloat2, SkSLType::kHalf2>(u, v);
142 }
143 
set2fv(UniformHandle u,int arrayCount,const float v[]) const144 void GrUniformDataManager::set2fv(UniformHandle u,
145                                   int arrayCount,
146                                   const float v[]) const {
147     this->setv<2, SkSLType::kFloat2, SkSLType::kHalf2>(u, arrayCount, v);
148 }
149 
set3i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2) const150 void GrUniformDataManager::set3i(UniformHandle u,
151                                  int32_t i0,
152                                  int32_t i1,
153                                  int32_t i2) const {
154     int32_t v[3] = { i0, i1, i2 };
155     this->set<3, SkSLType::kInt3, SkSLType::kShort3>(u, v);
156 }
157 
set3iv(UniformHandle u,int arrayCount,const int32_t v[]) const158 void GrUniformDataManager::set3iv(UniformHandle u,
159                                   int arrayCount,
160                                   const int32_t v[]) const {
161     this->setv<3, SkSLType::kInt3, SkSLType::kShort3>(u, arrayCount, v);
162 }
163 
set3f(UniformHandle u,float v0,float v1,float v2) const164 void GrUniformDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
165     float v[3] = { v0, v1, v2 };
166     this->set<3, SkSLType::kFloat3, SkSLType::kHalf3>(u, v);
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     this->setv<3, SkSLType::kFloat3, SkSLType::kHalf3>(u, arrayCount, v);
173 }
174 
set4i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2,int32_t i3) const175 void GrUniformDataManager::set4i(UniformHandle u,
176                                  int32_t i0,
177                                  int32_t i1,
178                                  int32_t i2,
179                                  int32_t i3) const {
180     int32_t v[4] = { i0, i1, i2, i3 };
181     this->set<4, SkSLType::kInt4, SkSLType::kShort4>(u, v);
182 }
183 
set4iv(UniformHandle u,int arrayCount,const int32_t v[]) const184 void GrUniformDataManager::set4iv(UniformHandle u,
185                                   int arrayCount,
186                                   const int32_t v[]) const {
187     this->setv<4, SkSLType::kInt4, SkSLType::kShort4>(u, arrayCount, v);
188 }
189 
set4f(UniformHandle u,float v0,float v1,float v2,float v3) const190 void GrUniformDataManager::set4f(UniformHandle u,
191                                  float v0,
192                                  float v1,
193                                  float v2,
194                                  float v3) const {
195     float v[4] = { v0, v1, v2, v3 };
196     this->set<4, SkSLType::kFloat4, SkSLType::kHalf4>(u, v);
197 }
198 
set4fv(UniformHandle u,int arrayCount,const float v[]) const199 void GrUniformDataManager::set4fv(UniformHandle u,
200                                   int arrayCount,
201                                   const float v[]) const {
202     this->setv<4, SkSLType::kFloat4, SkSLType::kHalf4>(u, arrayCount, v);
203 }
204 
setMatrix2f(UniformHandle u,const float matrix[]) const205 void GrUniformDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
206     this->setMatrices<2, SkSLType::kFloat2x2, SkSLType::kHalf2x2>(u, 1, matrix);
207 }
208 
setMatrix2fv(UniformHandle u,int arrayCount,const float m[]) const209 void GrUniformDataManager::setMatrix2fv(UniformHandle u, int arrayCount, const float m[]) const {
210     this->setMatrices<2, SkSLType::kFloat2x2, SkSLType::kHalf2x2>(u, arrayCount, m);
211 }
212 
setMatrix3f(UniformHandle u,const float matrix[]) const213 void GrUniformDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
214     this->setMatrices<3, SkSLType::kFloat3x3, SkSLType::kHalf3x3>(u, 1, matrix);
215 }
216 
setMatrix3fv(UniformHandle u,int arrayCount,const float m[]) const217 void GrUniformDataManager::setMatrix3fv(UniformHandle u, int arrayCount, const float m[]) const {
218     this->setMatrices<3, SkSLType::kFloat3x3, SkSLType::kHalf3x3>(u, arrayCount, m);
219 }
220 
setMatrix4f(UniformHandle u,const float matrix[]) const221 void GrUniformDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
222     this->setMatrices<4, SkSLType::kFloat4x4, SkSLType::kHalf4x4>(u, 1, matrix);
223 }
224 
setMatrix4fv(UniformHandle u,int arrayCount,const float m[]) const225 void GrUniformDataManager::setMatrix4fv(UniformHandle u, int arrayCount, const float m[]) const {
226     this->setMatrices<4, SkSLType::kFloat4x4, SkSLType::kHalf4x4>(u, arrayCount, m);
227 }
228 
229 template <int N, SkSLType FullType, SkSLType HalfType>
setMatrices(UniformHandle u,int arrayCount,const float matrices[]) const230 inline void GrUniformDataManager::setMatrices(UniformHandle u,
231                                               int arrayCount,
232                                               const float matrices[]) const {
233     const Uniform& uni = fUniforms[u.toIndex()];
234     SkASSERT(uni.fType == FullType || uni.fType == HalfType);
235     SkASSERT(arrayCount > 0);
236     SkASSERT(arrayCount <= uni.fArrayCount ||
237              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
238 
239     void* buffer = this->getBufferPtrAndMarkDirty(uni);
240     if constexpr (N == 4) {
241         this->copyUniforms(buffer, matrices, arrayCount * 16, uni.fType);
242     } else {
243         for (int i = 0; i < arrayCount; ++i) {
244             const float* matrix = &matrices[N * N * i];
245             for (int j = 0; j < N; ++j) {
246                 int uniformSize = this->copyUniforms(buffer, &matrix[j * N], N, uni.fType);
247                 buffer = SkTAddOffset<void>(buffer, /*numUniforms*/4 * uniformSize);
248             }
249         }
250     }
251 }
252