1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2020 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/GrUniformDataManager.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/private/SkHalf.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrShaderVar.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci// ensure that these types are the sizes the uniform data is expecting 14cb93a386Sopenharmony_cistatic_assert(sizeof(int32_t) == 4); 15cb93a386Sopenharmony_cistatic_assert(sizeof(float) == 4); 16cb93a386Sopenharmony_cistatic_assert(sizeof(short) == 2); 17cb93a386Sopenharmony_cistatic_assert(sizeof(SkHalf) == 2); 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ciGrUniformDataManager::GrUniformDataManager(uint32_t uniformCount, uint32_t uniformSize) 20cb93a386Sopenharmony_ci : fUniformSize(uniformSize) 21cb93a386Sopenharmony_ci , fUniformsDirty(false) { 22cb93a386Sopenharmony_ci fUniformData.reset(uniformSize); 23cb93a386Sopenharmony_ci fUniforms.push_back_n(uniformCount); 24cb93a386Sopenharmony_ci // subclasses fill in the uniforms in their constructor 25cb93a386Sopenharmony_ci} 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_civoid* GrUniformDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const { 28cb93a386Sopenharmony_ci fUniformsDirty = true; 29cb93a386Sopenharmony_ci return static_cast<char*>(fUniformData.get()) + uni.fOffset; 30cb93a386Sopenharmony_ci} 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ciint GrUniformDataManager::copyUniforms(void* dest, 33cb93a386Sopenharmony_ci const void* src, 34cb93a386Sopenharmony_ci int numUniforms, 35cb93a386Sopenharmony_ci GrSLType uniformType) const { 36cb93a386Sopenharmony_ci if (fWrite16BitUniforms) { 37cb93a386Sopenharmony_ci switch (uniformType) { 38cb93a386Sopenharmony_ci case kHalf_GrSLType: 39cb93a386Sopenharmony_ci case kHalf2_GrSLType: 40cb93a386Sopenharmony_ci case kHalf3_GrSLType: 41cb93a386Sopenharmony_ci case kHalf4_GrSLType: 42cb93a386Sopenharmony_ci case kHalf2x2_GrSLType: 43cb93a386Sopenharmony_ci case kHalf3x3_GrSLType: 44cb93a386Sopenharmony_ci case kHalf4x4_GrSLType: { 45cb93a386Sopenharmony_ci const float* floatBits = static_cast<const float*>(src); 46cb93a386Sopenharmony_ci SkHalf* halfBits = static_cast<SkHalf*>(dest); 47cb93a386Sopenharmony_ci while (numUniforms-- > 0) { 48cb93a386Sopenharmony_ci *halfBits++ = SkFloatToHalf(*floatBits++); 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci return 2; 51cb93a386Sopenharmony_ci } 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci case kShort_GrSLType: 54cb93a386Sopenharmony_ci case kShort2_GrSLType: 55cb93a386Sopenharmony_ci case kShort3_GrSLType: 56cb93a386Sopenharmony_ci case kShort4_GrSLType: 57cb93a386Sopenharmony_ci case kUShort_GrSLType: 58cb93a386Sopenharmony_ci case kUShort2_GrSLType: 59cb93a386Sopenharmony_ci case kUShort3_GrSLType: 60cb93a386Sopenharmony_ci case kUShort4_GrSLType: { 61cb93a386Sopenharmony_ci const int32_t* intBits = static_cast<const int32_t*>(src); 62cb93a386Sopenharmony_ci short* shortBits = static_cast<short*>(dest); 63cb93a386Sopenharmony_ci while (numUniforms-- > 0) { 64cb93a386Sopenharmony_ci *shortBits++ = (short)(*intBits++); 65cb93a386Sopenharmony_ci } 66cb93a386Sopenharmony_ci return 2; 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci default: 70cb93a386Sopenharmony_ci // Fall through to memcpy below. 71cb93a386Sopenharmony_ci break; 72cb93a386Sopenharmony_ci } 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci memcpy(dest, src, numUniforms * 4); 76cb93a386Sopenharmony_ci return 4; 77cb93a386Sopenharmony_ci} 78cb93a386Sopenharmony_ci 79cb93a386Sopenharmony_citemplate <int N, GrSLType FullType, GrSLType HalfType> 80cb93a386Sopenharmony_civoid GrUniformDataManager::set(UniformHandle u, const void* v) const { 81cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 82cb93a386Sopenharmony_ci SkASSERT(uni.fType == FullType || uni.fType == HalfType); 83cb93a386Sopenharmony_ci SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount); 84cb93a386Sopenharmony_ci void* buffer = this->getBufferPtrAndMarkDirty(uni); 85cb93a386Sopenharmony_ci this->copyUniforms(buffer, v, N, uni.fType); 86cb93a386Sopenharmony_ci} 87cb93a386Sopenharmony_ci 88cb93a386Sopenharmony_citemplate <int N, GrSLType FullType, GrSLType HalfType> 89cb93a386Sopenharmony_civoid GrUniformDataManager::setv(UniformHandle u, int arrayCount, const void* v) const { 90cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 91cb93a386Sopenharmony_ci SkASSERT(uni.fType == FullType || uni.fType == HalfType); 92cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 93cb93a386Sopenharmony_ci SkASSERT(arrayCount <= uni.fArrayCount || 94cb93a386Sopenharmony_ci (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount)); 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci void* buffer = this->getBufferPtrAndMarkDirty(uni); 97cb93a386Sopenharmony_ci if constexpr (N == 4) { 98cb93a386Sopenharmony_ci this->copyUniforms(buffer, v, arrayCount * 4, uni.fType); 99cb93a386Sopenharmony_ci } else { 100cb93a386Sopenharmony_ci for (int i = 0; i < arrayCount; ++i) { 101cb93a386Sopenharmony_ci int uniformSize = this->copyUniforms(buffer, v, N, uni.fType); 102cb93a386Sopenharmony_ci buffer = SkTAddOffset<void>(buffer, /*numUniforms*/4 * uniformSize); 103cb93a386Sopenharmony_ci v = static_cast<const char*>(v) + N * 4; 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci} 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_civoid GrUniformDataManager::set1i(UniformHandle u, int32_t i0) const { 109cb93a386Sopenharmony_ci this->set<1, kInt_GrSLType, kShort_GrSLType>(u, &i0); 110cb93a386Sopenharmony_ci} 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_civoid GrUniformDataManager::set1iv(UniformHandle u, 113cb93a386Sopenharmony_ci int arrayCount, 114cb93a386Sopenharmony_ci const int32_t v[]) const { 115cb93a386Sopenharmony_ci this->setv<1, kInt_GrSLType, kShort_GrSLType>(u, arrayCount, v); 116cb93a386Sopenharmony_ci} 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_civoid GrUniformDataManager::set1f(UniformHandle u, float v0) const { 119cb93a386Sopenharmony_ci this->set<1, kFloat_GrSLType, kHalf_GrSLType>(u, &v0); 120cb93a386Sopenharmony_ci} 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_civoid GrUniformDataManager::set1fv(UniformHandle u, 123cb93a386Sopenharmony_ci int arrayCount, 124cb93a386Sopenharmony_ci const float v[]) const { 125cb93a386Sopenharmony_ci this->setv<1, kFloat_GrSLType, kHalf_GrSLType>(u, arrayCount, v); 126cb93a386Sopenharmony_ci} 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_civoid GrUniformDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const { 129cb93a386Sopenharmony_ci int32_t v[2] = { i0, i1 }; 130cb93a386Sopenharmony_ci this->set<2, kInt2_GrSLType, kShort2_GrSLType>(u, v); 131cb93a386Sopenharmony_ci} 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_civoid GrUniformDataManager::set2iv(UniformHandle u, 134cb93a386Sopenharmony_ci int arrayCount, 135cb93a386Sopenharmony_ci const int32_t v[]) const { 136cb93a386Sopenharmony_ci this->setv<2, kInt2_GrSLType, kShort2_GrSLType>(u, arrayCount, v); 137cb93a386Sopenharmony_ci} 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_civoid GrUniformDataManager::set2f(UniformHandle u, float v0, float v1) const { 140cb93a386Sopenharmony_ci float v[2] = { v0, v1 }; 141cb93a386Sopenharmony_ci this->set<2, kFloat2_GrSLType, kHalf2_GrSLType>(u, v); 142cb93a386Sopenharmony_ci} 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_civoid GrUniformDataManager::set2fv(UniformHandle u, 145cb93a386Sopenharmony_ci int arrayCount, 146cb93a386Sopenharmony_ci const float v[]) const { 147cb93a386Sopenharmony_ci this->setv<2, kFloat2_GrSLType, kHalf2_GrSLType>(u, arrayCount, v); 148cb93a386Sopenharmony_ci} 149cb93a386Sopenharmony_ci 150cb93a386Sopenharmony_civoid GrUniformDataManager::set3i(UniformHandle u, 151cb93a386Sopenharmony_ci int32_t i0, 152cb93a386Sopenharmony_ci int32_t i1, 153cb93a386Sopenharmony_ci int32_t i2) const { 154cb93a386Sopenharmony_ci int32_t v[3] = { i0, i1, i2 }; 155cb93a386Sopenharmony_ci this->set<3, kInt3_GrSLType, kShort3_GrSLType>(u, v); 156cb93a386Sopenharmony_ci} 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_civoid GrUniformDataManager::set3iv(UniformHandle u, 159cb93a386Sopenharmony_ci int arrayCount, 160cb93a386Sopenharmony_ci const int32_t v[]) const { 161cb93a386Sopenharmony_ci this->setv<3, kInt3_GrSLType, kShort3_GrSLType>(u, arrayCount, v); 162cb93a386Sopenharmony_ci} 163cb93a386Sopenharmony_ci 164cb93a386Sopenharmony_civoid GrUniformDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const { 165cb93a386Sopenharmony_ci float v[3] = { v0, v1, v2 }; 166cb93a386Sopenharmony_ci this->set<3, kFloat3_GrSLType, kHalf3_GrSLType>(u, v); 167cb93a386Sopenharmony_ci} 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_civoid GrUniformDataManager::set3fv(UniformHandle u, 170cb93a386Sopenharmony_ci int arrayCount, 171cb93a386Sopenharmony_ci const float v[]) const { 172cb93a386Sopenharmony_ci this->setv<3, kFloat3_GrSLType, kHalf3_GrSLType>(u, arrayCount, v); 173cb93a386Sopenharmony_ci} 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_civoid GrUniformDataManager::set4i(UniformHandle u, 176cb93a386Sopenharmony_ci int32_t i0, 177cb93a386Sopenharmony_ci int32_t i1, 178cb93a386Sopenharmony_ci int32_t i2, 179cb93a386Sopenharmony_ci int32_t i3) const { 180cb93a386Sopenharmony_ci int32_t v[4] = { i0, i1, i2, i3 }; 181cb93a386Sopenharmony_ci this->set<4, kInt4_GrSLType, kShort4_GrSLType>(u, v); 182cb93a386Sopenharmony_ci} 183cb93a386Sopenharmony_ci 184cb93a386Sopenharmony_civoid GrUniformDataManager::set4iv(UniformHandle u, 185cb93a386Sopenharmony_ci int arrayCount, 186cb93a386Sopenharmony_ci const int32_t v[]) const { 187cb93a386Sopenharmony_ci this->setv<4, kInt4_GrSLType, kShort4_GrSLType>(u, arrayCount, v); 188cb93a386Sopenharmony_ci} 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_civoid GrUniformDataManager::set4f(UniformHandle u, 191cb93a386Sopenharmony_ci float v0, 192cb93a386Sopenharmony_ci float v1, 193cb93a386Sopenharmony_ci float v2, 194cb93a386Sopenharmony_ci float v3) const { 195cb93a386Sopenharmony_ci float v[4] = { v0, v1, v2, v3 }; 196cb93a386Sopenharmony_ci this->set<4, kFloat4_GrSLType, kHalf4_GrSLType>(u, v); 197cb93a386Sopenharmony_ci} 198cb93a386Sopenharmony_ci 199cb93a386Sopenharmony_civoid GrUniformDataManager::set4fv(UniformHandle u, 200cb93a386Sopenharmony_ci int arrayCount, 201cb93a386Sopenharmony_ci const float v[]) const { 202cb93a386Sopenharmony_ci this->setv<4, kFloat4_GrSLType, kHalf4_GrSLType>(u, arrayCount, v); 203cb93a386Sopenharmony_ci} 204cb93a386Sopenharmony_ci 205cb93a386Sopenharmony_civoid GrUniformDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const { 206cb93a386Sopenharmony_ci this->setMatrices<2, kFloat2x2_GrSLType, kHalf2x2_GrSLType>(u, 1, matrix); 207cb93a386Sopenharmony_ci} 208cb93a386Sopenharmony_ci 209cb93a386Sopenharmony_civoid GrUniformDataManager::setMatrix2fv(UniformHandle u, int arrayCount, const float m[]) const { 210cb93a386Sopenharmony_ci this->setMatrices<2, kFloat2x2_GrSLType, kHalf2x2_GrSLType>(u, arrayCount, m); 211cb93a386Sopenharmony_ci} 212cb93a386Sopenharmony_ci 213cb93a386Sopenharmony_civoid GrUniformDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const { 214cb93a386Sopenharmony_ci this->setMatrices<3, kFloat3x3_GrSLType, kHalf3x3_GrSLType>(u, 1, matrix); 215cb93a386Sopenharmony_ci} 216cb93a386Sopenharmony_ci 217cb93a386Sopenharmony_civoid GrUniformDataManager::setMatrix3fv(UniformHandle u, int arrayCount, const float m[]) const { 218cb93a386Sopenharmony_ci this->setMatrices<3, kFloat3x3_GrSLType, kHalf3x3_GrSLType>(u, arrayCount, m); 219cb93a386Sopenharmony_ci} 220cb93a386Sopenharmony_ci 221cb93a386Sopenharmony_civoid GrUniformDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const { 222cb93a386Sopenharmony_ci this->setMatrices<4, kFloat4x4_GrSLType, kHalf4x4_GrSLType>(u, 1, matrix); 223cb93a386Sopenharmony_ci} 224cb93a386Sopenharmony_ci 225cb93a386Sopenharmony_civoid GrUniformDataManager::setMatrix4fv(UniformHandle u, int arrayCount, const float m[]) const { 226cb93a386Sopenharmony_ci this->setMatrices<4, kFloat4x4_GrSLType, kHalf4x4_GrSLType>(u, arrayCount, m); 227cb93a386Sopenharmony_ci} 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_citemplate <int N, GrSLType FullType, GrSLType HalfType> 230cb93a386Sopenharmony_ciinline void GrUniformDataManager::setMatrices(UniformHandle u, 231cb93a386Sopenharmony_ci int arrayCount, 232cb93a386Sopenharmony_ci const float matrices[]) const { 233cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 234cb93a386Sopenharmony_ci SkASSERT(uni.fType == FullType || uni.fType == HalfType); 235cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 236cb93a386Sopenharmony_ci SkASSERT(arrayCount <= uni.fArrayCount || 237cb93a386Sopenharmony_ci (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount)); 238cb93a386Sopenharmony_ci 239cb93a386Sopenharmony_ci void* buffer = this->getBufferPtrAndMarkDirty(uni); 240cb93a386Sopenharmony_ci if constexpr (N == 4) { 241cb93a386Sopenharmony_ci this->copyUniforms(buffer, matrices, arrayCount * 16, uni.fType); 242cb93a386Sopenharmony_ci } else { 243cb93a386Sopenharmony_ci for (int i = 0; i < arrayCount; ++i) { 244cb93a386Sopenharmony_ci const float* matrix = &matrices[N * N * i]; 245cb93a386Sopenharmony_ci for (int j = 0; j < N; ++j) { 246cb93a386Sopenharmony_ci int uniformSize = this->copyUniforms(buffer, &matrix[j * N], N, uni.fType); 247cb93a386Sopenharmony_ci buffer = SkTAddOffset<void>(buffer, /*numUniforms*/4 * uniformSize); 248cb93a386Sopenharmony_ci } 249cb93a386Sopenharmony_ci } 250cb93a386Sopenharmony_ci } 251cb93a386Sopenharmony_ci} 252