Index: gpu/command_buffer/service/program_manager.cc |
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc |
index e40d23a3d6c071611e6bcc10d4a8a3579276328e..4b07ab7f9b49fe8361da84f41a9d91cc2cafe428 100644 |
--- a/gpu/command_buffer/service/program_manager.cc |
+++ b/gpu/command_buffer/service/program_manager.cc |
@@ -12,6 +12,7 @@ |
#include "base/memory/scoped_ptr.h" |
#include "base/string_number_conversions.h" |
#include "gpu/command_buffer/common/gles2_cmd_format.h" |
+#include "gpu/command_buffer/common/gles2_cmd_utils.h" |
#include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
namespace gpu { |
@@ -58,7 +59,8 @@ ProgramManager::ProgramInfo::ProgramInfo( |
service_id_(service_id), |
deleted_(false), |
valid_(false), |
- link_status_(false) { |
+ link_status_(false), |
+ uniforms_cleared_(false) { |
manager_->StartTracking(this); |
} |
@@ -88,10 +90,80 @@ void ProgramManager::ProgramInfo::UpdateLogInfo() { |
set_log_info(std::string(temp.get(), len).c_str()); |
} |
+void ProgramManager::ProgramInfo::ClearUniforms( |
+ std::vector<uint8>* zero_buffer) { |
+ DCHECK(zero_buffer); |
+ if (uniforms_cleared_) { |
+ return; |
+ } |
+ uniforms_cleared_ = true; |
+ for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { |
+ const UniformInfo& uniform_info = uniform_infos_[ii]; |
+ GLint location = uniform_info.element_locations[0]; |
+ GLsizei size = uniform_info.size; |
+ uint32 unit_size = GLES2Util::GetGLDataTypeSizeForUniforms( |
+ uniform_info.type); |
+ uint32 size_needed = size * unit_size; |
+ if (size_needed > zero_buffer->size()) { |
+ zero_buffer->resize(size_needed, 0u); |
+ } |
+ const void* zero = &(*zero_buffer)[0]; |
+ switch (uniform_info.type) { |
+ case GL_FLOAT: |
+ glUniform1fv(location, size, reinterpret_cast<const GLfloat*>(zero)); |
+ break; |
+ case GL_FLOAT_VEC2: |
+ glUniform2fv(location, size, reinterpret_cast<const GLfloat*>(zero)); |
+ break; |
+ case GL_FLOAT_VEC3: |
+ glUniform3fv(location, size, reinterpret_cast<const GLfloat*>(zero)); |
+ break; |
+ case GL_FLOAT_VEC4: |
+ glUniform4fv(location, size, reinterpret_cast<const GLfloat*>(zero)); |
+ break; |
+ case GL_INT: |
+ case GL_BOOL: |
+ case GL_SAMPLER_2D: |
+ case GL_SAMPLER_CUBE: |
+ case GL_SAMPLER_EXTERNAL_OES: |
+ glUniform1iv(location, size, reinterpret_cast<const GLint*>(zero)); |
+ break; |
+ case GL_INT_VEC2: |
+ case GL_BOOL_VEC2: |
+ glUniform2iv(location, size, reinterpret_cast<const GLint*>(zero)); |
+ break; |
+ case GL_INT_VEC3: |
+ case GL_BOOL_VEC3: |
+ glUniform3iv(location, size, reinterpret_cast<const GLint*>(zero)); |
+ break; |
+ case GL_INT_VEC4: |
+ case GL_BOOL_VEC4: |
+ glUniform4iv(location, size, reinterpret_cast<const GLint*>(zero)); |
+ break; |
+ case GL_FLOAT_MAT2: |
+ glUniformMatrix2fv( |
+ location, size, false, reinterpret_cast<const GLfloat*>(zero)); |
+ break; |
+ case GL_FLOAT_MAT3: |
+ glUniformMatrix3fv( |
+ location, size, false, reinterpret_cast<const GLfloat*>(zero)); |
+ break; |
+ case GL_FLOAT_MAT4: |
+ glUniformMatrix4fv( |
+ location, size, false, reinterpret_cast<const GLfloat*>(zero)); |
+ break; |
+ default: |
+ NOTREACHED(); |
+ break; |
+ } |
+ } |
+} |
+ |
void ProgramManager::ProgramInfo::Update() { |
Reset(); |
UpdateLogInfo(); |
link_status_ = true; |
+ uniforms_cleared_ = false; |
GLint num_attribs = 0; |
GLint max_len = 0; |
GLint max_location = -1; |
@@ -177,15 +249,15 @@ void ProgramManager::ProgramInfo::ExecuteBindAttribLocationCalls() { |
} |
} |
-void ProgramManager::ProgramInfo::Link() { |
+bool ProgramManager::ProgramInfo::Link() { |
ClearLinkStatus(); |
if (!CanLink()) { |
set_log_info("missing shaders"); |
- return; |
+ return false; |
} |
if (DetectAttribLocationBindingConflicts()) { |
set_log_info("glBindAttribLocation() conflicts"); |
- return; |
+ return false; |
} |
ExecuteBindAttribLocationCalls(); |
glLinkProgram(service_id()); |
@@ -196,6 +268,7 @@ void ProgramManager::ProgramInfo::Link() { |
} else { |
UpdateLogInfo(); |
} |
+ return true; |
Zhenyao Mo
2012/04/26 23:22:09
Here you should return success instead of true.
greggman
2012/04/26 23:41:12
thanks for catching that
done
|
} |
void ProgramManager::ProgramInfo::Validate() { |
@@ -692,6 +765,7 @@ void ProgramManager::UseProgram(ProgramManager::ProgramInfo* info) { |
DCHECK(info); |
DCHECK(IsOwned(info)); |
info->IncUseCount(); |
+ ClearUniforms(info); |
} |
void ProgramManager::UnuseProgram( |
@@ -704,6 +778,11 @@ void ProgramManager::UnuseProgram( |
RemoveProgramInfoIfUnused(shader_manager, info); |
} |
+void ProgramManager::ClearUniforms(ProgramManager::ProgramInfo* info) { |
+ DCHECK(info); |
+ info->ClearUniforms(&zero_); |
+} |
+ |
// Swizzles the locations to prevent developers from assuming they |
// can do math on uniforms. According to the OpenGL ES 2.0 spec |
// the location of "someuniform[1]" is not 'n' more than "someuniform[0]". |