1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 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 "src/gpu/gl/GrGLUniformHandler.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h" 11cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLCaps.h" 12cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLGpu.h" 13cb93a386Sopenharmony_ci#include "src/gpu/gl/builders/GrGLProgramBuilder.h" 14cb93a386Sopenharmony_ci#include "src/sksl/SkSLCompiler.h" 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ci#define GL_CALL(X) GR_GL_CALL(this->glGpu()->glInterface(), X) 17cb93a386Sopenharmony_ci#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->glGpu()->glInterface(), R, X) 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_cibool valid_name(const char* name) { 20cb93a386Sopenharmony_ci // disallow unknown names that start with "sk_" 21cb93a386Sopenharmony_ci if (!strncmp(name, GR_NO_MANGLE_PREFIX, strlen(GR_NO_MANGLE_PREFIX))) { 22cb93a386Sopenharmony_ci return !strcmp(name, SkSL::Compiler::RTADJUST_NAME); 23cb93a386Sopenharmony_ci } 24cb93a386Sopenharmony_ci return true; 25cb93a386Sopenharmony_ci} 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ciGrGLSLUniformHandler::UniformHandle GrGLUniformHandler::internalAddUniformArray( 28cb93a386Sopenharmony_ci const GrFragmentProcessor* owner, 29cb93a386Sopenharmony_ci uint32_t visibility, 30cb93a386Sopenharmony_ci GrSLType type, 31cb93a386Sopenharmony_ci const char* name, 32cb93a386Sopenharmony_ci bool mangleName, 33cb93a386Sopenharmony_ci int arrayCount, 34cb93a386Sopenharmony_ci const char** outName) { 35cb93a386Sopenharmony_ci SkASSERT(name && strlen(name)); 36cb93a386Sopenharmony_ci SkASSERT(valid_name(name)); 37cb93a386Sopenharmony_ci SkASSERT(0 != visibility); 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ci // TODO this is a bit hacky, lets think of a better way. Basically we need to be able to use 40cb93a386Sopenharmony_ci // the uniform view matrix name in the GP, and the GP is immutable so it has to tell the PB 41cb93a386Sopenharmony_ci // exactly what name it wants to use for the uniform view matrix. If we prefix anythings, then 42cb93a386Sopenharmony_ci // the names will mismatch. I think the correct solution is to have all GPs which need the 43cb93a386Sopenharmony_ci // uniform view matrix, they should upload the view matrix in their setData along with regular 44cb93a386Sopenharmony_ci // uniforms. 45cb93a386Sopenharmony_ci char prefix = 'u'; 46cb93a386Sopenharmony_ci if ('u' == name[0] || !strncmp(name, GR_NO_MANGLE_PREFIX, strlen(GR_NO_MANGLE_PREFIX))) { 47cb93a386Sopenharmony_ci prefix = '\0'; 48cb93a386Sopenharmony_ci } 49cb93a386Sopenharmony_ci SkString resolvedName = fProgramBuilder->nameVariable(prefix, name, mangleName); 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci GLUniformInfo tempInfo; 52cb93a386Sopenharmony_ci tempInfo.fVariable = GrShaderVar{std::move(resolvedName), 53cb93a386Sopenharmony_ci type, 54cb93a386Sopenharmony_ci GrShaderVar::TypeModifier::Uniform, 55cb93a386Sopenharmony_ci arrayCount}; 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci tempInfo.fVisibility = visibility; 58cb93a386Sopenharmony_ci tempInfo.fOwner = owner; 59cb93a386Sopenharmony_ci tempInfo.fRawName = SkString(name); 60cb93a386Sopenharmony_ci tempInfo.fLocation = -1; 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_ci fUniforms.push_back(tempInfo); 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci if (outName) { 65cb93a386Sopenharmony_ci *outName = fUniforms.back().fVariable.c_str(); 66cb93a386Sopenharmony_ci } 67cb93a386Sopenharmony_ci return GrGLSLUniformHandler::UniformHandle(fUniforms.count() - 1); 68cb93a386Sopenharmony_ci} 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ciGrGLSLUniformHandler::SamplerHandle GrGLUniformHandler::addSampler( 71cb93a386Sopenharmony_ci const GrBackendFormat& backendFormat, GrSamplerState, const GrSwizzle& swizzle, 72cb93a386Sopenharmony_ci const char* name, const GrShaderCaps* shaderCaps) { 73cb93a386Sopenharmony_ci SkASSERT(name && strlen(name)); 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci constexpr char prefix = 'u'; 76cb93a386Sopenharmony_ci SkString mangleName = fProgramBuilder->nameVariable(prefix, name, true); 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci GrTextureType type = backendFormat.textureType(); 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci GLUniformInfo tempInfo; 81cb93a386Sopenharmony_ci tempInfo.fVariable = GrShaderVar{std::move(mangleName), 82cb93a386Sopenharmony_ci GrSLCombinedSamplerTypeForTextureType(type), 83cb93a386Sopenharmony_ci GrShaderVar::TypeModifier::Uniform}; 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci tempInfo.fVisibility = kFragment_GrShaderFlag; 86cb93a386Sopenharmony_ci tempInfo.fOwner = nullptr; 87cb93a386Sopenharmony_ci tempInfo.fRawName = SkString(name); 88cb93a386Sopenharmony_ci tempInfo.fLocation = -1; 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_ci fSamplers.push_back(tempInfo); 91cb93a386Sopenharmony_ci fSamplerSwizzles.push_back(swizzle); 92cb93a386Sopenharmony_ci SkASSERT(fSamplers.count() == fSamplerSwizzles.count()); 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_ci return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1); 95cb93a386Sopenharmony_ci} 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_civoid GrGLUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const { 98cb93a386Sopenharmony_ci for (const UniformInfo& uniform : fUniforms.items()) { 99cb93a386Sopenharmony_ci if (uniform.fVisibility & visibility) { 100cb93a386Sopenharmony_ci uniform.fVariable.appendDecl(fProgramBuilder->shaderCaps(), out); 101cb93a386Sopenharmony_ci out->append(";"); 102cb93a386Sopenharmony_ci } 103cb93a386Sopenharmony_ci } 104cb93a386Sopenharmony_ci for (const UniformInfo& sampler : fSamplers.items()) { 105cb93a386Sopenharmony_ci if (sampler.fVisibility & visibility) { 106cb93a386Sopenharmony_ci sampler.fVariable.appendDecl(fProgramBuilder->shaderCaps(), out); 107cb93a386Sopenharmony_ci out->append(";\n"); 108cb93a386Sopenharmony_ci } 109cb93a386Sopenharmony_ci } 110cb93a386Sopenharmony_ci} 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_civoid GrGLUniformHandler::bindUniformLocations(GrGLuint programID, const GrGLCaps& caps) { 113cb93a386Sopenharmony_ci if (caps.bindUniformLocationSupport()) { 114cb93a386Sopenharmony_ci int currUniform = 0; 115cb93a386Sopenharmony_ci for (GLUniformInfo& uniform : fUniforms.items()) { 116cb93a386Sopenharmony_ci GL_CALL(BindUniformLocation(programID, currUniform, uniform.fVariable.c_str())); 117cb93a386Sopenharmony_ci uniform.fLocation = currUniform; 118cb93a386Sopenharmony_ci ++currUniform; 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci for (GLUniformInfo& sampler : fSamplers.items()) { 121cb93a386Sopenharmony_ci GL_CALL(BindUniformLocation(programID, currUniform, sampler.fVariable.c_str())); 122cb93a386Sopenharmony_ci sampler.fLocation = currUniform; 123cb93a386Sopenharmony_ci ++currUniform; 124cb93a386Sopenharmony_ci } 125cb93a386Sopenharmony_ci } 126cb93a386Sopenharmony_ci} 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_civoid GrGLUniformHandler::getUniformLocations(GrGLuint programID, const GrGLCaps& caps, bool force) { 129cb93a386Sopenharmony_ci if (!caps.bindUniformLocationSupport() || force) { 130cb93a386Sopenharmony_ci for (GLUniformInfo& uniform : fUniforms.items()) { 131cb93a386Sopenharmony_ci GrGLint location; 132cb93a386Sopenharmony_ci GL_CALL_RET(location, GetUniformLocation(programID, uniform.fVariable.c_str())); 133cb93a386Sopenharmony_ci uniform.fLocation = location; 134cb93a386Sopenharmony_ci } 135cb93a386Sopenharmony_ci for (GLUniformInfo& sampler : fSamplers.items()) { 136cb93a386Sopenharmony_ci GrGLint location; 137cb93a386Sopenharmony_ci GL_CALL_RET(location, GetUniformLocation(programID, sampler.fVariable.c_str())); 138cb93a386Sopenharmony_ci sampler.fLocation = location; 139cb93a386Sopenharmony_ci } 140cb93a386Sopenharmony_ci } 141cb93a386Sopenharmony_ci} 142cb93a386Sopenharmony_ci 143cb93a386Sopenharmony_ciconst GrGLGpu* GrGLUniformHandler::glGpu() const { 144cb93a386Sopenharmony_ci GrGLProgramBuilder* glPB = (GrGLProgramBuilder*) fProgramBuilder; 145cb93a386Sopenharmony_ci return glPB->gpu(); 146cb93a386Sopenharmony_ci} 147