Index: gpu/command_buffer/service/shader_manager.cc |
diff --git a/gpu/command_buffer/service/shader_manager.cc b/gpu/command_buffer/service/shader_manager.cc |
index fa071805eef226d9189e0ee640e0ea53b66ab80d..55754b7d4749f851ff6b0751ebe25ce443e46fa8 100644 |
--- a/gpu/command_buffer/service/shader_manager.cc |
+++ b/gpu/command_buffer/service/shader_manager.cc |
@@ -27,6 +27,7 @@ std::string GetTopVariableName(const std::string& fullname) { |
Shader::Shader(GLuint service_id, GLenum shader_type) |
: use_count_(0), |
shader_state_(kShaderStateWaiting), |
+ marked_for_deletion_(false), |
service_id_(service_id), |
shader_type_(shader_type), |
source_type_(kANGLE), |
@@ -36,6 +37,12 @@ Shader::Shader(GLuint service_id, GLenum shader_type) |
Shader::~Shader() { |
} |
+void Shader::Destroy() { |
+ if (service_id_) { |
+ DeleteServiceID(); |
+ } |
+} |
+ |
void Shader::RequestCompile(scoped_refptr<ShaderTranslatorInterface> translator, |
TranslatedShaderSourceType type) { |
shader_state_ = kShaderStateCompileRequested; |
@@ -105,6 +112,8 @@ void Shader::DoCompile() { |
// We cannot reach here if we are using the shader translator. |
// All invalid shaders must be rejected by the translator. |
// All translated shaders must compile. |
+ std::string translator_log = log_info_; |
+ |
GLint max_len = 0; |
glGetShaderiv(service_id_, GL_INFO_LOG_LENGTH, &max_len); |
log_info_.resize(max_len); |
@@ -115,9 +124,11 @@ void Shader::DoCompile() { |
DCHECK(len == 0 || log_info_[len] == '\0'); |
log_info_.resize(len); |
} |
+ |
LOG_IF(ERROR, translator) |
<< "Shader translator allowed/produced an invalid shader " |
<< "unless the driver is buggy:" |
+ << "\n--Log from shader translator--\n" << translator_log |
<< "\n--original-shader--\n" << last_compiled_source_ |
<< "\n--translated-shader--\n" << source_for_driver |
<< "\n--info-log--\n" << log_info_; |
@@ -131,13 +142,22 @@ void Shader::IncUseCount() { |
void Shader::DecUseCount() { |
--use_count_; |
DCHECK_GE(use_count_, 0); |
+ if (service_id_ && use_count_ == 0 && marked_for_deletion_) { |
+ DeleteServiceID(); |
+ } |
} |
-void Shader::Delete() { |
- if (use_count_ > 0) { |
- // If attached, compile the shader before we delete it. |
- DoCompile(); |
+void Shader::MarkForDeletion() { |
+ DCHECK(!marked_for_deletion_); |
+ DCHECK_NE(service_id_, 0u); |
+ |
+ marked_for_deletion_ = true; |
+ if (use_count_ == 0) { |
+ DeleteServiceID(); |
} |
+} |
+ |
+void Shader::DeleteServiceID() { |
DCHECK_NE(service_id_, 0u); |
glDeleteShader(service_id_); |
service_id_ = 0; |
@@ -189,9 +209,7 @@ void ShaderManager::Destroy(bool have_context) { |
while (!shaders_.empty()) { |
if (have_context) { |
Shader* shader = shaders_.begin()->second.get(); |
- if (!shader->IsDeleted()) { |
- shader->Delete(); |
- } |
+ shader->Destroy(); |
} |
shaders_.erase(shaders_.begin()); |
} |
@@ -254,7 +272,7 @@ void ShaderManager::RemoveShader(Shader* shader) { |
void ShaderManager::Delete(Shader* shader) { |
DCHECK(shader); |
DCHECK(IsOwned(shader)); |
- shader->Delete(); |
+ shader->MarkForDeletion(); |
RemoveShader(shader); |
} |