1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2015 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gl/GrGLUniformHandler.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gl/GrGLCaps.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gl/GrGLGpu.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gl/builders/GrGLProgramBuilder.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSLCompiler.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define GL_CALL(X) GR_GL_CALL(this->glGpu()->glInterface(), X) 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->glGpu()->glInterface(), R, X) 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool valid_name(const char* name) { 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // disallow unknown names that start with "sk_" 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!strncmp(name, GR_NO_MANGLE_PREFIX, strlen(GR_NO_MANGLE_PREFIX))) { 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return !strcmp(name, SkSL::Compiler::RTADJUST_NAME); 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrGLSLUniformHandler::UniformHandle GrGLUniformHandler::internalAddUniformArray( 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint32_t visibility, 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSLType type, 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSLPrecision precision, 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* name, 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool mangleName, 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int arrayCount, 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char** outName) { 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(name && strlen(name)); 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(valid_name(name)); 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(0 != visibility); 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeTemporarilyAcceptsPrecision(type)); 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot UniformInfo& uni = fUniforms.push_back(); 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uni.fVariable.setType(type); 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uni.fVariable.setTypeModifier(GrShaderVar::kUniform_TypeModifier); 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // TODO this is a bit hacky, lets think of a better way. Basically we need to be able to use 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // the uniform view matrix name in the GP, and the GP is immutable so it has to tell the PB 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // exactly what name it wants to use for the uniform view matrix. If we prefix anythings, then 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // the names will mismatch. I think the correct solution is to have all GPs which need the 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // uniform view matrix, they should upload the view matrix in their setData along with regular 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // uniforms. 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot char prefix = 'u'; 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if ('u' == name[0] || !strncmp(name, GR_NO_MANGLE_PREFIX, strlen(GR_NO_MANGLE_PREFIX))) { 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot prefix = '\0'; 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fProgramBuilder->nameVariable(uni.fVariable.accessName(), prefix, name, mangleName); 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uni.fVariable.setArrayCount(arrayCount); 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uni.fVisibility = visibility; 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uni.fVariable.setPrecision(precision); 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uni.fLocation = -1; 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (outName) { 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *outName = uni.fVariable.c_str(); 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return GrGLSLUniformHandler::UniformHandle(fUniforms.count() - 1); 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrGLSLUniformHandler::SamplerHandle GrGLUniformHandler::addSampler(uint32_t visibility, 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSwizzle swizzle, 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSLType type, 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSLPrecision precision, 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* name) { 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(name && strlen(name)); 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(0 != visibility); 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString mangleName; 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot char prefix = 'u'; 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fProgramBuilder->nameVariable(&mangleName, prefix, name, true); 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot UniformInfo& sampler = fSamplers.push_back(); 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(GrSLTypeIsCombinedSamplerType(type)); 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sampler.fVariable.setType(type); 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sampler.fVariable.setTypeModifier(GrShaderVar::kUniform_TypeModifier); 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sampler.fVariable.setPrecision(precision); 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sampler.fVariable.setName(mangleName); 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sampler.fLocation = -1; 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sampler.fVisibility = visibility; 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSamplerSwizzles.push_back(swizzle); 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fSamplers.count() == fSamplerSwizzles.count()); 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1); 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrGLSLUniformHandler::TexelBufferHandle GrGLUniformHandler::addTexelBuffer(uint32_t visibility, 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSLPrecision precision, 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* name) { 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(name && strlen(name)); 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(0 != visibility); 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString mangleName; 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot char prefix = 'u'; 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fProgramBuilder->nameVariable(&mangleName, prefix, name, true); 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot UniformInfo& texelBuffer = fTexelBuffers.push_back(); 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot texelBuffer.fVariable.setType(kBufferSampler_GrSLType); 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot texelBuffer.fVariable.setTypeModifier(GrShaderVar::kUniform_TypeModifier); 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot texelBuffer.fVariable.setPrecision(precision); 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot texelBuffer.fVariable.setName(mangleName); 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot texelBuffer.fLocation = -1; 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot texelBuffer.fVisibility = visibility; 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return GrGLSLUniformHandler::TexelBufferHandle(fTexelBuffers.count() - 1); 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrGLUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const { 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fUniforms.count(); ++i) { 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fUniforms[i].fVisibility & visibility) { 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUniforms[i].fVariable.appendDecl(fProgramBuilder->shaderCaps(), out); 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot out->append(";"); 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fSamplers.count(); ++i) { 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fSamplers[i].fVisibility & visibility) { 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSamplers[i].fVariable.appendDecl(fProgramBuilder->shaderCaps(), out); 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot out->append(";\n"); 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fTexelBuffers.count(); ++i) { 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fTexelBuffers[i].fVisibility & visibility) { 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fTexelBuffers[i].fVariable.appendDecl(fProgramBuilder->shaderCaps(), out); 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot out->append(";\n"); 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrGLUniformHandler::bindUniformLocations(GrGLuint programID, const GrGLCaps& caps) { 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (caps.bindUniformLocationSupport()) { 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int currUniform = 0; 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fUniforms.count(); ++i, ++currUniform) { 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GL_CALL(BindUniformLocation(programID, currUniform, fUniforms[i].fVariable.c_str())); 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUniforms[i].fLocation = currUniform; 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fSamplers.count(); ++i, ++currUniform) { 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GL_CALL(BindUniformLocation(programID, currUniform, fSamplers[i].fVariable.c_str())); 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSamplers[i].fLocation = currUniform; 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fTexelBuffers.count(); ++i, ++currUniform) { 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GL_CALL(BindUniformLocation(programID, currUniform, 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fTexelBuffers[i].fVariable.c_str())); 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fTexelBuffers[i].fLocation = currUniform; 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrGLUniformHandler::getUniformLocations(GrGLuint programID, const GrGLCaps& caps) { 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!caps.bindUniformLocationSupport()) { 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int count = fUniforms.count(); 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < count; ++i) { 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLint location; 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariable.c_str())); 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUniforms[i].fLocation = location; 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fSamplers.count(); ++i) { 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLint location; 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GL_CALL_RET(location, GetUniformLocation(programID, fSamplers[i].fVariable.c_str())); 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSamplers[i].fLocation = location; 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fTexelBuffers.count(); ++i) { 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLint location; 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GL_CALL_RET(location, GetUniformLocation(programID, 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fTexelBuffers[i].fVariable.c_str())); 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fTexelBuffers[i].fLocation = location; 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconst GrGLGpu* GrGLUniformHandler::glGpu() const { 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLProgramBuilder* glPB = (GrGLProgramBuilder*) fProgramBuilder; 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return glPB->gpu(); 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 175