1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/gl/GrGLUniformManager.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,280 @@ 1.4 +/* 1.5 + * Copyright 2012 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "gl/GrGLShaderBuilder.h" 1.12 +#include "gl/GrGLProgram.h" 1.13 +#include "gl/GrGLUniformHandle.h" 1.14 +#include "gl/GrGpuGL.h" 1.15 +#include "SkMatrix.h" 1.16 + 1.17 +#define ASSERT_ARRAY_UPLOAD_IN_BOUNDS(UNI, COUNT) \ 1.18 + SkASSERT(arrayCount <= uni.fArrayCount || \ 1.19 + (1 == arrayCount && GrGLShaderVar::kNonArray == uni.fArrayCount)) 1.20 + 1.21 +GrGLUniformManager::GrGLUniformManager(GrGpuGL* gpu) : fGpu(gpu) { 1.22 + // skbug.com/2056 1.23 + fUsingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL; 1.24 +} 1.25 + 1.26 +GrGLUniformManager::UniformHandle GrGLUniformManager::appendUniform(GrSLType type, int arrayCount) { 1.27 + int idx = fUniforms.count(); 1.28 + Uniform& uni = fUniforms.push_back(); 1.29 + SkASSERT(GrGLShaderVar::kNonArray == arrayCount || arrayCount > 0); 1.30 + uni.fArrayCount = arrayCount; 1.31 + uni.fType = type; 1.32 + uni.fVSLocation = kUnusedUniform; 1.33 + uni.fFSLocation = kUnusedUniform; 1.34 + return GrGLUniformManager::UniformHandle::CreateFromUniformIndex(idx); 1.35 +} 1.36 + 1.37 +void GrGLUniformManager::setSampler(UniformHandle u, GrGLint texUnit) const { 1.38 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.39 + SkASSERT(uni.fType == kSampler2D_GrSLType); 1.40 + SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount); 1.41 + // FIXME: We still insert a single sampler uniform for every stage. If the shader does not 1.42 + // reference the sampler then the compiler may have optimized it out. Uncomment this assert 1.43 + // once stages insert their own samplers. 1.44 + // SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.45 + if (kUnusedUniform != uni.fFSLocation) { 1.46 + GR_GL_CALL(fGpu->glInterface(), Uniform1i(uni.fFSLocation, texUnit)); 1.47 + } 1.48 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.49 + GR_GL_CALL(fGpu->glInterface(), Uniform1i(uni.fVSLocation, texUnit)); 1.50 + } 1.51 +} 1.52 + 1.53 +void GrGLUniformManager::set1f(UniformHandle u, GrGLfloat v0) const { 1.54 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.55 + SkASSERT(uni.fType == kFloat_GrSLType); 1.56 + SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount); 1.57 + SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.58 + if (kUnusedUniform != uni.fFSLocation) { 1.59 + GR_GL_CALL(fGpu->glInterface(), Uniform1f(uni.fFSLocation, v0)); 1.60 + } 1.61 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.62 + GR_GL_CALL(fGpu->glInterface(), Uniform1f(uni.fVSLocation, v0)); 1.63 + } 1.64 +} 1.65 + 1.66 +void GrGLUniformManager::set1fv(UniformHandle u, 1.67 + int arrayCount, 1.68 + const GrGLfloat v[]) const { 1.69 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.70 + SkASSERT(uni.fType == kFloat_GrSLType); 1.71 + SkASSERT(arrayCount > 0); 1.72 + ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 1.73 + // This assert fires in some instances of the two-pt gradient for its VSParams. 1.74 + // Once the uniform manager is responsible for inserting the duplicate uniform 1.75 + // arrays in VS and FS driver bug workaround, this can be enabled. 1.76 + //SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.77 + if (kUnusedUniform != uni.fFSLocation) { 1.78 + GR_GL_CALL(fGpu->glInterface(), Uniform1fv(uni.fFSLocation, arrayCount, v)); 1.79 + } 1.80 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.81 + GR_GL_CALL(fGpu->glInterface(), Uniform1fv(uni.fVSLocation, arrayCount, v)); 1.82 + } 1.83 +} 1.84 + 1.85 +void GrGLUniformManager::set2f(UniformHandle u, GrGLfloat v0, GrGLfloat v1) const { 1.86 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.87 + SkASSERT(uni.fType == kVec2f_GrSLType); 1.88 + SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount); 1.89 + SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.90 + if (kUnusedUniform != uni.fFSLocation) { 1.91 + GR_GL_CALL(fGpu->glInterface(), Uniform2f(uni.fFSLocation, v0, v1)); 1.92 + } 1.93 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.94 + GR_GL_CALL(fGpu->glInterface(), Uniform2f(uni.fVSLocation, v0, v1)); 1.95 + } 1.96 +} 1.97 + 1.98 +void GrGLUniformManager::set2fv(UniformHandle u, 1.99 + int arrayCount, 1.100 + const GrGLfloat v[]) const { 1.101 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.102 + SkASSERT(uni.fType == kVec2f_GrSLType); 1.103 + SkASSERT(arrayCount > 0); 1.104 + ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 1.105 + SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.106 + if (kUnusedUniform != uni.fFSLocation) { 1.107 + GR_GL_CALL(fGpu->glInterface(), Uniform2fv(uni.fFSLocation, arrayCount, v)); 1.108 + } 1.109 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.110 + GR_GL_CALL(fGpu->glInterface(), Uniform2fv(uni.fVSLocation, arrayCount, v)); 1.111 + } 1.112 +} 1.113 + 1.114 +void GrGLUniformManager::set3f(UniformHandle u, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) const { 1.115 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.116 + SkASSERT(uni.fType == kVec3f_GrSLType); 1.117 + SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount); 1.118 + SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.119 + if (kUnusedUniform != uni.fFSLocation) { 1.120 + GR_GL_CALL(fGpu->glInterface(), Uniform3f(uni.fFSLocation, v0, v1, v2)); 1.121 + } 1.122 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.123 + GR_GL_CALL(fGpu->glInterface(), Uniform3f(uni.fVSLocation, v0, v1, v2)); 1.124 + } 1.125 +} 1.126 + 1.127 +void GrGLUniformManager::set3fv(UniformHandle u, 1.128 + int arrayCount, 1.129 + const GrGLfloat v[]) const { 1.130 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.131 + SkASSERT(uni.fType == kVec3f_GrSLType); 1.132 + SkASSERT(arrayCount > 0); 1.133 + ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 1.134 + SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.135 + if (kUnusedUniform != uni.fFSLocation) { 1.136 + GR_GL_CALL(fGpu->glInterface(), Uniform3fv(uni.fFSLocation, arrayCount, v)); 1.137 + } 1.138 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.139 + GR_GL_CALL(fGpu->glInterface(), Uniform3fv(uni.fVSLocation, arrayCount, v)); 1.140 + } 1.141 +} 1.142 + 1.143 +void GrGLUniformManager::set4f(UniformHandle u, 1.144 + GrGLfloat v0, 1.145 + GrGLfloat v1, 1.146 + GrGLfloat v2, 1.147 + GrGLfloat v3) const { 1.148 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.149 + SkASSERT(uni.fType == kVec4f_GrSLType); 1.150 + SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount); 1.151 + SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.152 + if (kUnusedUniform != uni.fFSLocation) { 1.153 + GR_GL_CALL(fGpu->glInterface(), Uniform4f(uni.fFSLocation, v0, v1, v2, v3)); 1.154 + } 1.155 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.156 + GR_GL_CALL(fGpu->glInterface(), Uniform4f(uni.fVSLocation, v0, v1, v2, v3)); 1.157 + } 1.158 +} 1.159 + 1.160 +void GrGLUniformManager::set4fv(UniformHandle u, 1.161 + int arrayCount, 1.162 + const GrGLfloat v[]) const { 1.163 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.164 + SkASSERT(uni.fType == kVec4f_GrSLType); 1.165 + SkASSERT(arrayCount > 0); 1.166 + ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 1.167 + SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.168 + if (kUnusedUniform != uni.fFSLocation) { 1.169 + GR_GL_CALL(fGpu->glInterface(), Uniform4fv(uni.fFSLocation, arrayCount, v)); 1.170 + } 1.171 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.172 + GR_GL_CALL(fGpu->glInterface(), Uniform4fv(uni.fVSLocation, arrayCount, v)); 1.173 + } 1.174 +} 1.175 + 1.176 +void GrGLUniformManager::setMatrix3f(UniformHandle u, const GrGLfloat matrix[]) const { 1.177 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.178 + SkASSERT(uni.fType == kMat33f_GrSLType); 1.179 + SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount); 1.180 + // TODO: Re-enable this assert once texture matrices aren't forced on all effects 1.181 + // SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.182 + if (kUnusedUniform != uni.fFSLocation) { 1.183 + GR_GL_CALL(fGpu->glInterface(), UniformMatrix3fv(uni.fFSLocation, 1, false, matrix)); 1.184 + } 1.185 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.186 + GR_GL_CALL(fGpu->glInterface(), UniformMatrix3fv(uni.fVSLocation, 1, false, matrix)); 1.187 + } 1.188 +} 1.189 + 1.190 +void GrGLUniformManager::setMatrix4f(UniformHandle u, const GrGLfloat matrix[]) const { 1.191 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.192 + SkASSERT(uni.fType == kMat44f_GrSLType); 1.193 + SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount); 1.194 + SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.195 + if (kUnusedUniform != uni.fFSLocation) { 1.196 + GR_GL_CALL(fGpu->glInterface(), UniformMatrix4fv(uni.fFSLocation, 1, false, matrix)); 1.197 + } 1.198 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.199 + GR_GL_CALL(fGpu->glInterface(), UniformMatrix4fv(uni.fVSLocation, 1, false, matrix)); 1.200 + } 1.201 +} 1.202 + 1.203 +void GrGLUniformManager::setMatrix3fv(UniformHandle u, 1.204 + int arrayCount, 1.205 + const GrGLfloat matrices[]) const { 1.206 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.207 + SkASSERT(uni.fType == kMat33f_GrSLType); 1.208 + SkASSERT(arrayCount > 0); 1.209 + ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 1.210 + SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.211 + if (kUnusedUniform != uni.fFSLocation) { 1.212 + GR_GL_CALL(fGpu->glInterface(), 1.213 + UniformMatrix3fv(uni.fFSLocation, arrayCount, false, matrices)); 1.214 + } 1.215 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.216 + GR_GL_CALL(fGpu->glInterface(), 1.217 + UniformMatrix3fv(uni.fVSLocation, arrayCount, false, matrices)); 1.218 + } 1.219 +} 1.220 + 1.221 +void GrGLUniformManager::setMatrix4fv(UniformHandle u, 1.222 + int arrayCount, 1.223 + const GrGLfloat matrices[]) const { 1.224 + const Uniform& uni = fUniforms[u.toUniformIndex()]; 1.225 + SkASSERT(uni.fType == kMat44f_GrSLType); 1.226 + SkASSERT(arrayCount > 0); 1.227 + ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount); 1.228 + SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation); 1.229 + if (kUnusedUniform != uni.fFSLocation) { 1.230 + GR_GL_CALL(fGpu->glInterface(), 1.231 + UniformMatrix4fv(uni.fFSLocation, arrayCount, false, matrices)); 1.232 + } 1.233 + if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) { 1.234 + GR_GL_CALL(fGpu->glInterface(), 1.235 + UniformMatrix4fv(uni.fVSLocation, arrayCount, false, matrices)); 1.236 + } 1.237 +} 1.238 + 1.239 +void GrGLUniformManager::setSkMatrix(UniformHandle u, const SkMatrix& matrix) const { 1.240 + GrGLfloat mt[] = { 1.241 + matrix.get(SkMatrix::kMScaleX), 1.242 + matrix.get(SkMatrix::kMSkewY), 1.243 + matrix.get(SkMatrix::kMPersp0), 1.244 + matrix.get(SkMatrix::kMSkewX), 1.245 + matrix.get(SkMatrix::kMScaleY), 1.246 + matrix.get(SkMatrix::kMPersp1), 1.247 + matrix.get(SkMatrix::kMTransX), 1.248 + matrix.get(SkMatrix::kMTransY), 1.249 + matrix.get(SkMatrix::kMPersp2), 1.250 + }; 1.251 + this->setMatrix3f(u, mt); 1.252 +} 1.253 + 1.254 + 1.255 +void GrGLUniformManager::getUniformLocations(GrGLuint programID, const BuilderUniformArray& uniforms) { 1.256 + SkASSERT(uniforms.count() == fUniforms.count()); 1.257 + int count = fUniforms.count(); 1.258 + for (int i = 0; i < count; ++i) { 1.259 + SkASSERT(uniforms[i].fVariable.getType() == fUniforms[i].fType); 1.260 + SkASSERT(uniforms[i].fVariable.getArrayCount() == fUniforms[i].fArrayCount); 1.261 + GrGLint location; 1.262 + // TODO: Move the Xoom uniform array in both FS and VS bug workaround here. 1.263 + if (fUsingBindUniform) { 1.264 + location = i; 1.265 + GR_GL_CALL(fGpu->glInterface(), 1.266 + BindUniformLocation(programID, location, uniforms[i].fVariable.c_str())); 1.267 + } else { 1.268 + GR_GL_CALL_RET(fGpu->glInterface(), location, 1.269 + GetUniformLocation(programID, uniforms[i].fVariable.c_str())); 1.270 + } 1.271 + if (GrGLShaderBuilder::kVertex_Visibility & uniforms[i].fVisibility) { 1.272 + fUniforms[i].fVSLocation = location; 1.273 + } 1.274 + if (GrGLShaderBuilder::kFragment_Visibility & uniforms[i].fVisibility) { 1.275 + fUniforms[i].fFSLocation = location; 1.276 + } 1.277 + } 1.278 +} 1.279 + 1.280 +const GrGLUniformManager::BuilderUniform& 1.281 +GrGLUniformManager::getBuilderUniform(const BuilderUniformArray& array, UniformHandle handle) const { 1.282 + return array[handle.toUniformIndex()]; 1.283 +}