17ea439b2203855db97330b25945b87dd4b170b8begdaniel/* 27ea439b2203855db97330b25945b87dd4b170b8begdaniel * Copyright 2015 Google Inc. 37ea439b2203855db97330b25945b87dd4b170b8begdaniel * 47ea439b2203855db97330b25945b87dd4b170b8begdaniel * Use of this source code is governed by a BSD-style license that can be 57ea439b2203855db97330b25945b87dd4b170b8begdaniel * found in the LICENSE file. 67ea439b2203855db97330b25945b87dd4b170b8begdaniel */ 77ea439b2203855db97330b25945b87dd4b170b8begdaniel 87ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "gl/GrGLUniformHandler.h" 97ea439b2203855db97330b25945b87dd4b170b8begdaniel 107ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "gl/GrGLCaps.h" 117ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "gl/GrGLGpu.h" 127ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "gl/builders/GrGLProgramBuilder.h" 137ea439b2203855db97330b25945b87dd4b170b8begdaniel 147ea439b2203855db97330b25945b87dd4b170b8begdaniel#define GL_CALL(X) GR_GL_CALL(this->glGpu()->glInterface(), X) 157ea439b2203855db97330b25945b87dd4b170b8begdaniel#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->glGpu()->glInterface(), R, X) 167ea439b2203855db97330b25945b87dd4b170b8begdaniel 177ea439b2203855db97330b25945b87dd4b170b8begdanielGrGLSLUniformHandler::UniformHandle GrGLUniformHandler::internalAddUniformArray( 187ea439b2203855db97330b25945b87dd4b170b8begdaniel uint32_t visibility, 197ea439b2203855db97330b25945b87dd4b170b8begdaniel GrSLType type, 207ea439b2203855db97330b25945b87dd4b170b8begdaniel GrSLPrecision precision, 217ea439b2203855db97330b25945b87dd4b170b8begdaniel const char* name, 227ea439b2203855db97330b25945b87dd4b170b8begdaniel bool mangleName, 237ea439b2203855db97330b25945b87dd4b170b8begdaniel int arrayCount, 247ea439b2203855db97330b25945b87dd4b170b8begdaniel const char** outName) { 257ea439b2203855db97330b25945b87dd4b170b8begdaniel SkASSERT(name && strlen(name)); 267ea439b2203855db97330b25945b87dd4b170b8begdaniel SkASSERT(0 != visibility); 275f2d8e28c4f8ec0ead92eb613254063ace4e90b4cdalton SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeAcceptsPrecision(type)); 287ea439b2203855db97330b25945b87dd4b170b8begdaniel 297ea439b2203855db97330b25945b87dd4b170b8begdaniel UniformInfo& uni = fUniforms.push_back(); 307ea439b2203855db97330b25945b87dd4b170b8begdaniel uni.fVariable.setType(type); 3199938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon uni.fVariable.setTypeModifier(GrShaderVar::kUniform_TypeModifier); 327ea439b2203855db97330b25945b87dd4b170b8begdaniel // TODO this is a bit hacky, lets think of a better way. Basically we need to be able to use 337ea439b2203855db97330b25945b87dd4b170b8begdaniel // the uniform view matrix name in the GP, and the GP is immutable so it has to tell the PB 347ea439b2203855db97330b25945b87dd4b170b8begdaniel // exactly what name it wants to use for the uniform view matrix. If we prefix anythings, then 357ea439b2203855db97330b25945b87dd4b170b8begdaniel // the names will mismatch. I think the correct solution is to have all GPs which need the 367ea439b2203855db97330b25945b87dd4b170b8begdaniel // uniform view matrix, they should upload the view matrix in their setData along with regular 377ea439b2203855db97330b25945b87dd4b170b8begdaniel // uniforms. 387ea439b2203855db97330b25945b87dd4b170b8begdaniel char prefix = 'u'; 397ea439b2203855db97330b25945b87dd4b170b8begdaniel if ('u' == name[0]) { 407ea439b2203855db97330b25945b87dd4b170b8begdaniel prefix = '\0'; 417ea439b2203855db97330b25945b87dd4b170b8begdaniel } 427ea439b2203855db97330b25945b87dd4b170b8begdaniel fProgramBuilder->nameVariable(uni.fVariable.accessName(), prefix, name, mangleName); 437ea439b2203855db97330b25945b87dd4b170b8begdaniel uni.fVariable.setArrayCount(arrayCount); 447ea439b2203855db97330b25945b87dd4b170b8begdaniel uni.fVisibility = visibility; 457ea439b2203855db97330b25945b87dd4b170b8begdaniel uni.fVariable.setPrecision(precision); 46101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon uni.fLocation = -1; 477ea439b2203855db97330b25945b87dd4b170b8begdaniel 487ea439b2203855db97330b25945b87dd4b170b8begdaniel if (outName) { 497ea439b2203855db97330b25945b87dd4b170b8begdaniel *outName = uni.fVariable.c_str(); 507ea439b2203855db97330b25945b87dd4b170b8begdaniel } 517ea439b2203855db97330b25945b87dd4b170b8begdaniel return GrGLSLUniformHandler::UniformHandle(fUniforms.count() - 1); 527ea439b2203855db97330b25945b87dd4b170b8begdaniel} 537ea439b2203855db97330b25945b87dd4b170b8begdaniel 54101b844d6ba031de5c4e95b43f9292f266799237Brian SalomonGrGLSLUniformHandler::SamplerHandle GrGLUniformHandler::addSampler(uint32_t visibility, 55101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon GrSwizzle swizzle, 56101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon GrSLType type, 57101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon GrSLPrecision precision, 58101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon const char* name) { 5909aa1fce69b214714171db12c341aebd78dd29eaegdaniel SkASSERT(name && strlen(name)); 6009aa1fce69b214714171db12c341aebd78dd29eaegdaniel SkASSERT(0 != visibility); 61101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon 6209aa1fce69b214714171db12c341aebd78dd29eaegdaniel SkString mangleName; 6309aa1fce69b214714171db12c341aebd78dd29eaegdaniel char prefix = 'u'; 6409aa1fce69b214714171db12c341aebd78dd29eaegdaniel fProgramBuilder->nameVariable(&mangleName, prefix, name, true); 65101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon 66101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon UniformInfo& sampler = fSamplers.push_back(); 67101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon SkASSERT(GrSLTypeIsCombinedSamplerType(type)); 68101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon sampler.fVariable.setType(type); 6999938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon sampler.fVariable.setTypeModifier(GrShaderVar::kUniform_TypeModifier); 70101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon sampler.fVariable.setPrecision(precision); 71101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon sampler.fVariable.setName(mangleName); 72101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon sampler.fLocation = -1; 73101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon sampler.fVisibility = visibility; 74101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon fSamplerSwizzles.push_back(swizzle); 75101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon SkASSERT(fSamplers.count() == fSamplerSwizzles.count()); 7609aa1fce69b214714171db12c341aebd78dd29eaegdaniel return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1); 7709aa1fce69b214714171db12c341aebd78dd29eaegdaniel} 7809aa1fce69b214714171db12c341aebd78dd29eaegdaniel 79f9f451213a3951d8a61568998de2ddbd643f6693Brian SalomonGrGLSLUniformHandler::ImageStorageHandle GrGLUniformHandler::addImageStorage( 80f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon uint32_t visibility, GrSLType type, GrImageStorageFormat format, GrSLMemoryModel model, 81f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon GrSLRestrict restrict, GrIOType ioType, const char* name) { 82f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon SkASSERT(name && strlen(name)); 83f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon SkASSERT(0 != visibility); 84f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon SkString mangleName; 85f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon char prefix = 'u'; 86f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon fProgramBuilder->nameVariable(&mangleName, prefix, name, true); 87f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon 88f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon UniformInfo& imageStorage = fImageStorages.push_back(); 89f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon imageStorage.fVariable.setName(mangleName); 90f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon 91f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon SkASSERT(GrSLTypeIsImageStorage(type)); 92f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon imageStorage.fVariable.setType(type); 93f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon imageStorage.fVariable.setTypeModifier(GrShaderVar::kUniform_TypeModifier); 94f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon imageStorage.fVariable.setImageStorageFormat(format); 95f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon imageStorage.fVariable.setMemoryModel(model); 96f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon imageStorage.fVariable.setRestrict(restrict); 97f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon imageStorage.fVariable.setIOType(ioType); 98f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon imageStorage.fVariable.setPrecision(kHigh_GrSLPrecision); 99f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon imageStorage.fLocation = -1; 100f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon imageStorage.fVisibility = visibility; 101f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon return GrGLSLUniformHandler::ImageStorageHandle(fImageStorages.count() - 1); 102f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon} 103f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon 1045e58ceea8569f0d90ff7e3daf5de2def50407212cdaltonvoid GrGLUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const { 1057ea439b2203855db97330b25945b87dd4b170b8begdaniel for (int i = 0; i < fUniforms.count(); ++i) { 1067ea439b2203855db97330b25945b87dd4b170b8begdaniel if (fUniforms[i].fVisibility & visibility) { 10794efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon fUniforms[i].fVariable.appendDecl(fProgramBuilder->shaderCaps(), out); 108f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon out->append(";"); 1097ea439b2203855db97330b25945b87dd4b170b8begdaniel } 1107ea439b2203855db97330b25945b87dd4b170b8begdaniel } 11109aa1fce69b214714171db12c341aebd78dd29eaegdaniel for (int i = 0; i < fSamplers.count(); ++i) { 112101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon if (fSamplers[i].fVisibility & visibility) { 11394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon fSamplers[i].fVariable.appendDecl(fProgramBuilder->shaderCaps(), out); 11409aa1fce69b214714171db12c341aebd78dd29eaegdaniel out->append(";\n"); 11509aa1fce69b214714171db12c341aebd78dd29eaegdaniel } 11609aa1fce69b214714171db12c341aebd78dd29eaegdaniel } 117f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon for (int i = 0; i < fImageStorages.count(); ++i) { 118f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon if (fImageStorages[i].fVisibility & visibility) { 11994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon fImageStorages[i].fVariable.appendDecl(fProgramBuilder->shaderCaps(), out); 120f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon out->append(";"); 121f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon } 122f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon } 1237ea439b2203855db97330b25945b87dd4b170b8begdaniel} 1247ea439b2203855db97330b25945b87dd4b170b8begdaniel 1257ea439b2203855db97330b25945b87dd4b170b8begdanielvoid GrGLUniformHandler::bindUniformLocations(GrGLuint programID, const GrGLCaps& caps) { 1267ea439b2203855db97330b25945b87dd4b170b8begdaniel if (caps.bindUniformLocationSupport()) { 127f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon int currUniform = 0; 128f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon for (int i = 0; i < fUniforms.count(); ++i, ++currUniform) { 129f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon GL_CALL(BindUniformLocation(programID, currUniform, fUniforms[i].fVariable.c_str())); 130f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon fUniforms[i].fLocation = currUniform; 131be34882042048db096baca32ddf4a8b472529804Brian Salomon } 132f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon for (int i = 0; i < fSamplers.count(); ++i, ++currUniform) { 133f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon GL_CALL(BindUniformLocation(programID, currUniform, fSamplers[i].fVariable.c_str())); 134f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon fSamplers[i].fLocation = currUniform; 135f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon } 136f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon for (int i = 0; i < fImageStorages.count(); ++i) { 137f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon GL_CALL(BindUniformLocation(programID, currUniform, 138f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon fImageStorages[i].fVariable.c_str())); 139f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon fImageStorages[i].fLocation = currUniform; 14009aa1fce69b214714171db12c341aebd78dd29eaegdaniel } 1417ea439b2203855db97330b25945b87dd4b170b8begdaniel } 1427ea439b2203855db97330b25945b87dd4b170b8begdaniel} 1437ea439b2203855db97330b25945b87dd4b170b8begdaniel 1447ea439b2203855db97330b25945b87dd4b170b8begdanielvoid GrGLUniformHandler::getUniformLocations(GrGLuint programID, const GrGLCaps& caps) { 1457ea439b2203855db97330b25945b87dd4b170b8begdaniel if (!caps.bindUniformLocationSupport()) { 1467ea439b2203855db97330b25945b87dd4b170b8begdaniel int count = fUniforms.count(); 1477ea439b2203855db97330b25945b87dd4b170b8begdaniel for (int i = 0; i < count; ++i) { 1487ea439b2203855db97330b25945b87dd4b170b8begdaniel GrGLint location; 1497ea439b2203855db97330b25945b87dd4b170b8begdaniel GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariable.c_str())); 1507ea439b2203855db97330b25945b87dd4b170b8begdaniel fUniforms[i].fLocation = location; 1517ea439b2203855db97330b25945b87dd4b170b8begdaniel } 15209aa1fce69b214714171db12c341aebd78dd29eaegdaniel for (int i = 0; i < fSamplers.count(); ++i) { 15309aa1fce69b214714171db12c341aebd78dd29eaegdaniel GrGLint location; 154101b844d6ba031de5c4e95b43f9292f266799237Brian Salomon GL_CALL_RET(location, GetUniformLocation(programID, fSamplers[i].fVariable.c_str())); 15509aa1fce69b214714171db12c341aebd78dd29eaegdaniel fSamplers[i].fLocation = location; 15609aa1fce69b214714171db12c341aebd78dd29eaegdaniel } 157f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon for (int i = 0; i < fImageStorages.count(); ++i) { 158f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon GrGLint location; 159f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon GL_CALL_RET(location, GetUniformLocation(programID, 160f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon fImageStorages[i].fVariable.c_str())); 161f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon fImageStorages[i].fLocation = location; 162f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon } 1637ea439b2203855db97330b25945b87dd4b170b8begdaniel } 1647ea439b2203855db97330b25945b87dd4b170b8begdaniel} 1657ea439b2203855db97330b25945b87dd4b170b8begdaniel 1667ea439b2203855db97330b25945b87dd4b170b8begdanielconst GrGLGpu* GrGLUniformHandler::glGpu() const { 1677ea439b2203855db97330b25945b87dd4b170b8begdaniel GrGLProgramBuilder* glPB = (GrGLProgramBuilder*) fProgramBuilder; 1687ea439b2203855db97330b25945b87dd4b170b8begdaniel return glPB->gpu(); 1697ea439b2203855db97330b25945b87dd4b170b8begdaniel} 170