1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2012 Google Inc. 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 "include/core/SkMatrix.h" 9cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLGpu.h" 10cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLProgramDataManager.h" 11cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLUniformHandler.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci#define ASSERT_ARRAY_UPLOAD_IN_BOUNDS(UNI, COUNT) \ 14cb93a386Sopenharmony_ci SkASSERT((COUNT) <= (UNI).fArrayCount || \ 15cb93a386Sopenharmony_ci (1 == (COUNT) && GrShaderVar::kNonArray == (UNI).fArrayCount)) 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ciGrGLProgramDataManager::GrGLProgramDataManager(GrGLGpu* gpu, const UniformInfoArray& uniforms) 18cb93a386Sopenharmony_ci : fGpu(gpu) { 19cb93a386Sopenharmony_ci fUniforms.push_back_n(uniforms.count()); 20cb93a386Sopenharmony_ci int i = 0; 21cb93a386Sopenharmony_ci for (const GLUniformInfo& builderUniform : uniforms.items()) { 22cb93a386Sopenharmony_ci Uniform& uniform = fUniforms[i++]; 23cb93a386Sopenharmony_ci SkASSERT(GrShaderVar::kNonArray == builderUniform.fVariable.getArrayCount() || 24cb93a386Sopenharmony_ci builderUniform.fVariable.getArrayCount() > 0); 25cb93a386Sopenharmony_ci SkDEBUGCODE( 26cb93a386Sopenharmony_ci uniform.fArrayCount = builderUniform.fVariable.getArrayCount(); 27cb93a386Sopenharmony_ci uniform.fType = builderUniform.fVariable.getType(); 28cb93a386Sopenharmony_ci ) 29cb93a386Sopenharmony_ci uniform.fLocation = builderUniform.fLocation; 30cb93a386Sopenharmony_ci } 31cb93a386Sopenharmony_ci} 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_civoid GrGLProgramDataManager::setSamplerUniforms(const UniformInfoArray& samplers, 34cb93a386Sopenharmony_ci int startUnit) const { 35cb93a386Sopenharmony_ci int i = 0; 36cb93a386Sopenharmony_ci for (const GLUniformInfo& sampler : samplers.items()) { 37cb93a386Sopenharmony_ci SkASSERT(sampler.fVisibility); 38cb93a386Sopenharmony_ci if (kUnusedUniform != sampler.fLocation) { 39cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform1i(sampler.fLocation, i + startUnit)); 40cb93a386Sopenharmony_ci } 41cb93a386Sopenharmony_ci ++i; 42cb93a386Sopenharmony_ci } 43cb93a386Sopenharmony_ci} 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_civoid GrGLProgramDataManager::set1i(UniformHandle u, int32_t i) const { 46cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 47cb93a386Sopenharmony_ci SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType); 48cb93a386Sopenharmony_ci SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount); 49cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 50cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform1i(uni.fLocation, i)); 51cb93a386Sopenharmony_ci } 52cb93a386Sopenharmony_ci} 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_civoid GrGLProgramDataManager::set1iv(UniformHandle u, 55cb93a386Sopenharmony_ci int arrayCount, 56cb93a386Sopenharmony_ci const int32_t v[]) const { 57cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 58cb93a386Sopenharmony_ci SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType); 59cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 60cb93a386Sopenharmony_ci ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 61cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 62cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform1iv(uni.fLocation, arrayCount, v)); 63cb93a386Sopenharmony_ci } 64cb93a386Sopenharmony_ci} 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_civoid GrGLProgramDataManager::set1f(UniformHandle u, float v0) const { 67cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 68cb93a386Sopenharmony_ci SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType); 69cb93a386Sopenharmony_ci SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount); 70cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 71cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform1f(uni.fLocation, v0)); 72cb93a386Sopenharmony_ci } 73cb93a386Sopenharmony_ci} 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_civoid GrGLProgramDataManager::set1fv(UniformHandle u, 76cb93a386Sopenharmony_ci int arrayCount, 77cb93a386Sopenharmony_ci const float v[]) const { 78cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 79cb93a386Sopenharmony_ci SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType); 80cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 81cb93a386Sopenharmony_ci ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 82cb93a386Sopenharmony_ci // This assert fires in some instances of the two-pt gradient for its VSParams. 83cb93a386Sopenharmony_ci // Once the uniform manager is responsible for inserting the duplicate uniform 84cb93a386Sopenharmony_ci // arrays in VS and FS driver bug workaround, this can be enabled. 85cb93a386Sopenharmony_ci // this->printUni(uni); 86cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 87cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform1fv(uni.fLocation, arrayCount, v)); 88cb93a386Sopenharmony_ci } 89cb93a386Sopenharmony_ci} 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_civoid GrGLProgramDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const { 92cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 93cb93a386Sopenharmony_ci SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType); 94cb93a386Sopenharmony_ci SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount); 95cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 96cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform2i(uni.fLocation, i0, i1)); 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci} 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_civoid GrGLProgramDataManager::set2iv(UniformHandle u, 101cb93a386Sopenharmony_ci int arrayCount, 102cb93a386Sopenharmony_ci const int32_t v[]) const { 103cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 104cb93a386Sopenharmony_ci SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType); 105cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 106cb93a386Sopenharmony_ci ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 107cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 108cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform2iv(uni.fLocation, arrayCount, v)); 109cb93a386Sopenharmony_ci } 110cb93a386Sopenharmony_ci} 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_civoid GrGLProgramDataManager::set2f(UniformHandle u, float v0, float v1) const { 113cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 114cb93a386Sopenharmony_ci SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType); 115cb93a386Sopenharmony_ci SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount); 116cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 117cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform2f(uni.fLocation, v0, v1)); 118cb93a386Sopenharmony_ci } 119cb93a386Sopenharmony_ci} 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_civoid GrGLProgramDataManager::set2fv(UniformHandle u, 122cb93a386Sopenharmony_ci int arrayCount, 123cb93a386Sopenharmony_ci const float v[]) const { 124cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 125cb93a386Sopenharmony_ci SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType); 126cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 127cb93a386Sopenharmony_ci ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 128cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 129cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform2fv(uni.fLocation, arrayCount, v)); 130cb93a386Sopenharmony_ci } 131cb93a386Sopenharmony_ci} 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_civoid GrGLProgramDataManager::set3i(UniformHandle u, int32_t i0, int32_t i1, int32_t i2) const { 134cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 135cb93a386Sopenharmony_ci SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType); 136cb93a386Sopenharmony_ci SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount); 137cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 138cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform3i(uni.fLocation, i0, i1, i2)); 139cb93a386Sopenharmony_ci } 140cb93a386Sopenharmony_ci} 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_civoid GrGLProgramDataManager::set3iv(UniformHandle u, 143cb93a386Sopenharmony_ci int arrayCount, 144cb93a386Sopenharmony_ci const int32_t v[]) const { 145cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 146cb93a386Sopenharmony_ci SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType); 147cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 148cb93a386Sopenharmony_ci ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 149cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 150cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform3iv(uni.fLocation, arrayCount, v)); 151cb93a386Sopenharmony_ci } 152cb93a386Sopenharmony_ci} 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_civoid GrGLProgramDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const { 155cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 156cb93a386Sopenharmony_ci SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType); 157cb93a386Sopenharmony_ci SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount); 158cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 159cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform3f(uni.fLocation, v0, v1, v2)); 160cb93a386Sopenharmony_ci } 161cb93a386Sopenharmony_ci} 162cb93a386Sopenharmony_ci 163cb93a386Sopenharmony_civoid GrGLProgramDataManager::set3fv(UniformHandle u, 164cb93a386Sopenharmony_ci int arrayCount, 165cb93a386Sopenharmony_ci const float v[]) const { 166cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 167cb93a386Sopenharmony_ci SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType); 168cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 169cb93a386Sopenharmony_ci ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 170cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 171cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform3fv(uni.fLocation, arrayCount, v)); 172cb93a386Sopenharmony_ci } 173cb93a386Sopenharmony_ci} 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_civoid GrGLProgramDataManager::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 const Uniform& uni = fUniforms[u.toIndex()]; 181cb93a386Sopenharmony_ci SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType); 182cb93a386Sopenharmony_ci SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount); 183cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 184cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform4i(uni.fLocation, i0, i1, i2, i3)); 185cb93a386Sopenharmony_ci } 186cb93a386Sopenharmony_ci} 187cb93a386Sopenharmony_ci 188cb93a386Sopenharmony_civoid GrGLProgramDataManager::set4iv(UniformHandle u, 189cb93a386Sopenharmony_ci int arrayCount, 190cb93a386Sopenharmony_ci const int32_t v[]) const { 191cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 192cb93a386Sopenharmony_ci SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType); 193cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 194cb93a386Sopenharmony_ci ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 195cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 196cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform4iv(uni.fLocation, arrayCount, v)); 197cb93a386Sopenharmony_ci } 198cb93a386Sopenharmony_ci} 199cb93a386Sopenharmony_ci 200cb93a386Sopenharmony_civoid GrGLProgramDataManager::set4f(UniformHandle u, 201cb93a386Sopenharmony_ci float v0, 202cb93a386Sopenharmony_ci float v1, 203cb93a386Sopenharmony_ci float v2, 204cb93a386Sopenharmony_ci float v3) const { 205cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 206cb93a386Sopenharmony_ci SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType); 207cb93a386Sopenharmony_ci SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount); 208cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 209cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform4f(uni.fLocation, v0, v1, v2, v3)); 210cb93a386Sopenharmony_ci } 211cb93a386Sopenharmony_ci} 212cb93a386Sopenharmony_ci 213cb93a386Sopenharmony_civoid GrGLProgramDataManager::set4fv(UniformHandle u, 214cb93a386Sopenharmony_ci int arrayCount, 215cb93a386Sopenharmony_ci const float v[]) const { 216cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 217cb93a386Sopenharmony_ci SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType); 218cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 219cb93a386Sopenharmony_ci ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 220cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 221cb93a386Sopenharmony_ci GR_GL_CALL(fGpu->glInterface(), Uniform4fv(uni.fLocation, arrayCount, v)); 222cb93a386Sopenharmony_ci } 223cb93a386Sopenharmony_ci} 224cb93a386Sopenharmony_ci 225cb93a386Sopenharmony_civoid GrGLProgramDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const { 226cb93a386Sopenharmony_ci this->setMatrices<2>(u, 1, matrix); 227cb93a386Sopenharmony_ci} 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_civoid GrGLProgramDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const { 230cb93a386Sopenharmony_ci this->setMatrices<3>(u, 1, matrix); 231cb93a386Sopenharmony_ci} 232cb93a386Sopenharmony_ci 233cb93a386Sopenharmony_civoid GrGLProgramDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const { 234cb93a386Sopenharmony_ci this->setMatrices<4>(u, 1, matrix); 235cb93a386Sopenharmony_ci} 236cb93a386Sopenharmony_ci 237cb93a386Sopenharmony_civoid GrGLProgramDataManager::setMatrix2fv(UniformHandle u, int arrayCount, const float m[]) const { 238cb93a386Sopenharmony_ci this->setMatrices<2>(u, arrayCount, m); 239cb93a386Sopenharmony_ci} 240cb93a386Sopenharmony_ci 241cb93a386Sopenharmony_civoid GrGLProgramDataManager::setMatrix3fv(UniformHandle u, int arrayCount, const float m[]) const { 242cb93a386Sopenharmony_ci this->setMatrices<3>(u, arrayCount, m); 243cb93a386Sopenharmony_ci} 244cb93a386Sopenharmony_ci 245cb93a386Sopenharmony_civoid GrGLProgramDataManager::setMatrix4fv(UniformHandle u, int arrayCount, const float m[]) const { 246cb93a386Sopenharmony_ci this->setMatrices<4>(u, arrayCount, m); 247cb93a386Sopenharmony_ci} 248cb93a386Sopenharmony_ci 249cb93a386Sopenharmony_citemplate<int N> struct set_uniform_matrix; 250cb93a386Sopenharmony_ci 251cb93a386Sopenharmony_citemplate<int N> inline void GrGLProgramDataManager::setMatrices(UniformHandle u, 252cb93a386Sopenharmony_ci int arrayCount, 253cb93a386Sopenharmony_ci const float matrices[]) const { 254cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 255cb93a386Sopenharmony_ci SkASSERT(uni.fType == kFloat2x2_GrSLType + (N - 2) || 256cb93a386Sopenharmony_ci uni.fType == kHalf2x2_GrSLType + (N - 2)); 257cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 258cb93a386Sopenharmony_ci ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 259cb93a386Sopenharmony_ci if (kUnusedUniform != uni.fLocation) { 260cb93a386Sopenharmony_ci set_uniform_matrix<N>::set(fGpu->glInterface(), uni.fLocation, arrayCount, matrices); 261cb93a386Sopenharmony_ci } 262cb93a386Sopenharmony_ci} 263cb93a386Sopenharmony_ci 264cb93a386Sopenharmony_citemplate<> struct set_uniform_matrix<2> { 265cb93a386Sopenharmony_ci inline static void set(const GrGLInterface* gli, const GrGLint loc, int cnt, const float m[]) { 266cb93a386Sopenharmony_ci GR_GL_CALL(gli, UniformMatrix2fv(loc, cnt, false, m)); 267cb93a386Sopenharmony_ci } 268cb93a386Sopenharmony_ci}; 269cb93a386Sopenharmony_ci 270cb93a386Sopenharmony_citemplate<> struct set_uniform_matrix<3> { 271cb93a386Sopenharmony_ci inline static void set(const GrGLInterface* gli, const GrGLint loc, int cnt, const float m[]) { 272cb93a386Sopenharmony_ci GR_GL_CALL(gli, UniformMatrix3fv(loc, cnt, false, m)); 273cb93a386Sopenharmony_ci } 274cb93a386Sopenharmony_ci}; 275cb93a386Sopenharmony_ci 276cb93a386Sopenharmony_citemplate<> struct set_uniform_matrix<4> { 277cb93a386Sopenharmony_ci inline static void set(const GrGLInterface* gli, const GrGLint loc, int cnt, const float m[]) { 278cb93a386Sopenharmony_ci GR_GL_CALL(gli, UniformMatrix4fv(loc, cnt, false, m)); 279cb93a386Sopenharmony_ci } 280cb93a386Sopenharmony_ci}; 281