From: Marius Renn Date: Mon, 1 Aug 2011 18:47:58 +0000 (-0700) Subject: Bugfix (5064211): Fix uniform access and lookups to work on non-TEGRA. X-Git-Tag: android-x86-7.1-r1~849^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=dbdc075e52caead0e08643ddfb68ff2e99d6af21;p=android-x86%2Fsystem-media.git Bugfix (5064211): Fix uniform access and lookups to work on non-TEGRA. Change-Id: I75f80db09d9836754c7071ed8fd3c88ab317d989 --- diff --git a/mca/filterfw/native/core/shader_program.cpp b/mca/filterfw/native/core/shader_program.cpp index 06319484..63d68ab3 100644 --- a/mca/filterfw/native/core/shader_program.cpp +++ b/mca/filterfw/native/core/shader_program.cpp @@ -284,6 +284,9 @@ bool ShaderProgram::CompileAndLink() { GLuint shaders[2] = { vertex_shader_, fragment_shader_ }; program_ = LinkProgram(shaders, 2); + // Scan for all uniforms in the program + ScanUniforms(); + // Check if we manage all coordinates if (program_ != 0) { ProgramVar tex_coord_attr = glGetAttribLocation(program_, TexCoordAttributeName().c_str()); @@ -376,6 +379,21 @@ GLuint ShaderProgram::LinkProgram(GLuint* shaders, GLuint count) { return program; } +void ShaderProgram::ScanUniforms() { + int uniform_count; + int buffer_size; + GLenum type; + GLint capacity; + glGetProgramiv(program_, GL_ACTIVE_UNIFORMS, &uniform_count); + glGetProgramiv(program_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &buffer_size); + std::vector name(buffer_size); + for (int i = 0; i < uniform_count; ++i) { + glGetActiveUniform(program_, i, buffer_size, NULL, &capacity, &type, &name[0]); + ProgramVar uniform_id = glGetUniformLocation(program_, &name[0]); + uniform_indices_[uniform_id] = i; + } +} + bool ShaderProgram::PushCoords(ProgramVar attr, float* coords) { // If the shader does not define these, we simply ignore the coordinates, and assume that the // user is managing coordinates. @@ -624,13 +642,21 @@ bool ShaderProgram::CheckValueMult(const std::string& var_type, bool ShaderProgram::CheckVarValid(ProgramVar var) { if (!IsVarValid(var)) { - LOGE("Shader Program: Attempting to set invalid variable!"); + LOGE("Shader Program: Attempting to access invalid variable!"); return false; } return true; } // Uniforms //////////////////////////////////////////////////////////////////// +bool ShaderProgram::CheckUniformValid(ProgramVar var) { + if (!IsVarValid(var) || uniform_indices_.find(var) == uniform_indices_.end()) { + LOGE("Shader Program: Attempting to access unknown uniform %d!", var); + return false; + } + return true; +} + int ShaderProgram::MaxUniformCount() { // Here we return the minimum of the max uniform count for fragment and vertex // shaders. @@ -675,7 +701,7 @@ bool ShaderProgram::SetUniformValue(ProgramVar var, float value) { bool ShaderProgram::SetUniformValue(ProgramVar var, const int* values, int count) { - if (!CheckVarValid(var)) + if (!CheckUniformValid(var)) return false; // Make sure we have values at all @@ -688,7 +714,7 @@ bool ShaderProgram::SetUniformValue(ProgramVar var, GLint capacity; GLenum type; char name[128]; - glGetActiveUniform(program_, var, 128, NULL, &capacity, &type, name); + glGetActiveUniform(program_, IndexOfUniform(var), 128, NULL, &capacity, &type, name); // Make sure passed values are compatible const int components = GLEnv::NumberOfComponents(type); @@ -726,7 +752,7 @@ bool ShaderProgram::SetUniformValue(ProgramVar var, bool ShaderProgram::SetUniformValue(ProgramVar var, const float* values, int count) { - if (!CheckVarValid(var)) + if (!CheckUniformValid(var)) return false; // Make sure we have values at all @@ -739,7 +765,7 @@ bool ShaderProgram::SetUniformValue(ProgramVar var, GLint capacity; GLenum type; char name[128]; - glGetActiveUniform(program_, var, 128, NULL, &capacity, &type, name); + glGetActiveUniform(program_, IndexOfUniform(var), 128, NULL, &capacity, &type, name); // Make sure passed values are compatible const int components = GLEnv::NumberOfComponents(type); @@ -810,11 +836,11 @@ bool ShaderProgram::SetUniformValue(const std::string& name, const Value& value) Value ShaderProgram::GetUniformValue(const std::string& name) { ProgramVar var = GetUniform(name); - if (IsVarValid(var)) { + if (CheckUniformValid(var)) { // Get uniform information GLint capacity; GLenum type; - glGetActiveUniform(program_, var, 0, NULL, &capacity, &type, NULL); + glGetActiveUniform(program_, IndexOfUniform(var), 0, NULL, &capacity, &type, NULL); if (!GLEnv::CheckGLError("Get Active Uniform")) { // Get value based on type, and wrap in value object switch(type) { @@ -900,6 +926,10 @@ Value ShaderProgram::GetUniformValue(const std::string& name) { return MakeNullValue(); } +GLuint ShaderProgram::IndexOfUniform(ProgramVar var) { + return uniform_indices_[var]; +} + // Attributes ////////////////////////////////////////////////////////////////////////////////////// int ShaderProgram::MaxAttributeCount() { GLint result; diff --git a/mca/filterfw/native/core/shader_program.h b/mca/filterfw/native/core/shader_program.h index ddb3b98a..2063175e 100644 --- a/mca/filterfw/native/core/shader_program.h +++ b/mca/filterfw/native/core/shader_program.h @@ -433,6 +433,13 @@ class ShaderProgram { } }; + // Scans for all uniforms in the shader and creates index -> id map. + void ScanUniforms(); + + // Returns the index of the given uniform. The caller must make sure + // that the variable id passed is valid. + GLuint IndexOfUniform(ProgramVar var); + // Binds the given input textures. bool BindInputTextures(const std::vector& textures, const std::vector& targets); @@ -477,6 +484,10 @@ class ShaderProgram { // not. static bool CheckVarValid(ProgramVar var); + // Returns true if the uniform specified by var is an active uniform in the + // program. + bool CheckUniformValid(ProgramVar var); + // Store an attribute to use when rendering. bool StoreAttribute(VertexAttrib attrib); @@ -531,6 +542,9 @@ class ShaderProgram { bool blending_; int sfactor_; int dfactor_; + + // Map from uniform ids to indices + std::map uniform_indices_; }; } // namespace filterfw