| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/command_buffer/service/shader_manager.h" | 5 #include "gpu/command_buffer/service/shader_manager.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 | 11 |
| 12 namespace gpu { | 12 namespace gpu { |
| 13 namespace gles2 { | 13 namespace gles2 { |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 // Given a variable name | a[0].b.c[0] |, return |a|. | 17 // Given a variable name | a[0].b.c[0] |, return |a|. |
| 18 std::string GetTopVariableName(const std::string& fullname) { | 18 std::string GetTopVariableName(const std::string& fullname) { |
| 19 size_t pos = fullname.find_first_of("[."); | 19 size_t pos = fullname.find_first_of("[."); |
| 20 if (pos == std::string::npos) | 20 if (pos == std::string::npos) |
| 21 return fullname; | 21 return fullname; |
| 22 return fullname.substr(0, pos); | 22 return fullname.substr(0, pos); |
| 23 } | 23 } |
| 24 | 24 |
| 25 } // namespace anonymous | 25 } // namespace anonymous |
| 26 | 26 |
| 27 Shader::Shader(GLuint service_id, GLenum shader_type) | 27 Shader::Shader(GLuint service_id, GLenum shader_type) |
| 28 : use_count_(0), | 28 : use_count_(0), |
| 29 shader_state_(kShaderStateWaiting), | 29 shader_state_(kShaderStateWaiting), |
| 30 marked_for_deletion_(false), |
| 30 service_id_(service_id), | 31 service_id_(service_id), |
| 31 shader_type_(shader_type), | 32 shader_type_(shader_type), |
| 32 source_type_(kANGLE), | 33 source_type_(kANGLE), |
| 33 valid_(false) { | 34 valid_(false) { |
| 34 } | 35 } |
| 35 | 36 |
| 36 Shader::~Shader() { | 37 Shader::~Shader() { |
| 37 } | 38 } |
| 38 | 39 |
| 40 void Shader::Destroy() { |
| 41 if (service_id_) { |
| 42 DeleteServiceID(); |
| 43 } |
| 44 } |
| 45 |
| 39 void Shader::RequestCompile(scoped_refptr<ShaderTranslatorInterface> translator, | 46 void Shader::RequestCompile(scoped_refptr<ShaderTranslatorInterface> translator, |
| 40 TranslatedShaderSourceType type) { | 47 TranslatedShaderSourceType type) { |
| 41 shader_state_ = kShaderStateCompileRequested; | 48 shader_state_ = kShaderStateCompileRequested; |
| 42 translator_ = translator; | 49 translator_ = translator; |
| 43 source_type_ = type; | 50 source_type_ = type; |
| 44 last_compiled_source_ = source_; | 51 last_compiled_source_ = source_; |
| 45 } | 52 } |
| 46 | 53 |
| 47 void Shader::DoCompile() { | 54 void Shader::DoCompile() { |
| 48 // We require that RequestCompile() must be called before DoCompile(), | 55 // We require that RequestCompile() must be called before DoCompile(), |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 GLint status = GL_FALSE; | 105 GLint status = GL_FALSE; |
| 99 glGetShaderiv(service_id_, GL_COMPILE_STATUS, &status); | 106 glGetShaderiv(service_id_, GL_COMPILE_STATUS, &status); |
| 100 if (status == GL_TRUE) { | 107 if (status == GL_TRUE) { |
| 101 valid_ = true; | 108 valid_ = true; |
| 102 } else { | 109 } else { |
| 103 valid_ = false; | 110 valid_ = false; |
| 104 | 111 |
| 105 // We cannot reach here if we are using the shader translator. | 112 // We cannot reach here if we are using the shader translator. |
| 106 // All invalid shaders must be rejected by the translator. | 113 // All invalid shaders must be rejected by the translator. |
| 107 // All translated shaders must compile. | 114 // All translated shaders must compile. |
| 115 std::string translator_log = log_info_; |
| 116 |
| 108 GLint max_len = 0; | 117 GLint max_len = 0; |
| 109 glGetShaderiv(service_id_, GL_INFO_LOG_LENGTH, &max_len); | 118 glGetShaderiv(service_id_, GL_INFO_LOG_LENGTH, &max_len); |
| 110 log_info_.resize(max_len); | 119 log_info_.resize(max_len); |
| 111 if (max_len) { | 120 if (max_len) { |
| 112 GLint len = 0; | 121 GLint len = 0; |
| 113 glGetShaderInfoLog(service_id_, log_info_.size(), &len, &log_info_.at(0)); | 122 glGetShaderInfoLog(service_id_, log_info_.size(), &len, &log_info_.at(0)); |
| 114 DCHECK(max_len == 0 || len < max_len); | 123 DCHECK(max_len == 0 || len < max_len); |
| 115 DCHECK(len == 0 || log_info_[len] == '\0'); | 124 DCHECK(len == 0 || log_info_[len] == '\0'); |
| 116 log_info_.resize(len); | 125 log_info_.resize(len); |
| 117 } | 126 } |
| 127 |
| 118 LOG_IF(ERROR, translator) | 128 LOG_IF(ERROR, translator) |
| 119 << "Shader translator allowed/produced an invalid shader " | 129 << "Shader translator allowed/produced an invalid shader " |
| 120 << "unless the driver is buggy:" | 130 << "unless the driver is buggy:" |
| 131 << "\n--Log from shader translator--\n" << translator_log |
| 121 << "\n--original-shader--\n" << last_compiled_source_ | 132 << "\n--original-shader--\n" << last_compiled_source_ |
| 122 << "\n--translated-shader--\n" << source_for_driver | 133 << "\n--translated-shader--\n" << source_for_driver |
| 123 << "\n--info-log--\n" << log_info_; | 134 << "\n--info-log--\n" << log_info_; |
| 124 } | 135 } |
| 125 } | 136 } |
| 126 | 137 |
| 127 void Shader::IncUseCount() { | 138 void Shader::IncUseCount() { |
| 128 ++use_count_; | 139 ++use_count_; |
| 129 } | 140 } |
| 130 | 141 |
| 131 void Shader::DecUseCount() { | 142 void Shader::DecUseCount() { |
| 132 --use_count_; | 143 --use_count_; |
| 133 DCHECK_GE(use_count_, 0); | 144 DCHECK_GE(use_count_, 0); |
| 145 if (service_id_ && use_count_ == 0 && marked_for_deletion_) { |
| 146 DeleteServiceID(); |
| 147 } |
| 134 } | 148 } |
| 135 | 149 |
| 136 void Shader::Delete() { | 150 void Shader::MarkForDeletion() { |
| 137 if (use_count_ > 0) { | 151 DCHECK(!marked_for_deletion_); |
| 138 // If attached, compile the shader before we delete it. | 152 DCHECK_NE(service_id_, 0u); |
| 139 DoCompile(); | 153 |
| 154 marked_for_deletion_ = true; |
| 155 if (use_count_ == 0) { |
| 156 DeleteServiceID(); |
| 140 } | 157 } |
| 158 } |
| 159 |
| 160 void Shader::DeleteServiceID() { |
| 141 DCHECK_NE(service_id_, 0u); | 161 DCHECK_NE(service_id_, 0u); |
| 142 glDeleteShader(service_id_); | 162 glDeleteShader(service_id_); |
| 143 service_id_ = 0; | 163 service_id_ = 0; |
| 144 } | 164 } |
| 145 | 165 |
| 146 const sh::Attribute* Shader::GetAttribInfo(const std::string& name) const { | 166 const sh::Attribute* Shader::GetAttribInfo(const std::string& name) const { |
| 147 // Vertex attributes can't be arrays or structs (GLSL ES 3.00.4, section | 167 // Vertex attributes can't be arrays or structs (GLSL ES 3.00.4, section |
| 148 // 4.3.4, "Input Variables"), so |name| is the top level name used as | 168 // 4.3.4, "Input Variables"), so |name| is the top level name used as |
| 149 // the AttributeMap key. | 169 // the AttributeMap key. |
| 150 AttributeMap::const_iterator it = attrib_map_.find(name); | 170 AttributeMap::const_iterator it = attrib_map_.find(name); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 ShaderManager::ShaderManager() {} | 202 ShaderManager::ShaderManager() {} |
| 183 | 203 |
| 184 ShaderManager::~ShaderManager() { | 204 ShaderManager::~ShaderManager() { |
| 185 DCHECK(shaders_.empty()); | 205 DCHECK(shaders_.empty()); |
| 186 } | 206 } |
| 187 | 207 |
| 188 void ShaderManager::Destroy(bool have_context) { | 208 void ShaderManager::Destroy(bool have_context) { |
| 189 while (!shaders_.empty()) { | 209 while (!shaders_.empty()) { |
| 190 if (have_context) { | 210 if (have_context) { |
| 191 Shader* shader = shaders_.begin()->second.get(); | 211 Shader* shader = shaders_.begin()->second.get(); |
| 192 if (!shader->IsDeleted()) { | 212 shader->Destroy(); |
| 193 shader->Delete(); | |
| 194 } | |
| 195 } | 213 } |
| 196 shaders_.erase(shaders_.begin()); | 214 shaders_.erase(shaders_.begin()); |
| 197 } | 215 } |
| 198 } | 216 } |
| 199 | 217 |
| 200 Shader* ShaderManager::CreateShader( | 218 Shader* ShaderManager::CreateShader( |
| 201 GLuint client_id, | 219 GLuint client_id, |
| 202 GLuint service_id, | 220 GLuint service_id, |
| 203 GLenum shader_type) { | 221 GLenum shader_type) { |
| 204 std::pair<ShaderMap::iterator, bool> result = | 222 std::pair<ShaderMap::iterator, bool> result = |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 return; | 265 return; |
| 248 } | 266 } |
| 249 } | 267 } |
| 250 NOTREACHED(); | 268 NOTREACHED(); |
| 251 } | 269 } |
| 252 } | 270 } |
| 253 | 271 |
| 254 void ShaderManager::Delete(Shader* shader) { | 272 void ShaderManager::Delete(Shader* shader) { |
| 255 DCHECK(shader); | 273 DCHECK(shader); |
| 256 DCHECK(IsOwned(shader)); | 274 DCHECK(IsOwned(shader)); |
| 257 shader->Delete(); | 275 shader->MarkForDeletion(); |
| 258 RemoveShader(shader); | 276 RemoveShader(shader); |
| 259 } | 277 } |
| 260 | 278 |
| 261 void ShaderManager::UseShader(Shader* shader) { | 279 void ShaderManager::UseShader(Shader* shader) { |
| 262 DCHECK(shader); | 280 DCHECK(shader); |
| 263 DCHECK(IsOwned(shader)); | 281 DCHECK(IsOwned(shader)); |
| 264 shader->IncUseCount(); | 282 shader->IncUseCount(); |
| 265 } | 283 } |
| 266 | 284 |
| 267 void ShaderManager::UnuseShader(Shader* shader) { | 285 void ShaderManager::UnuseShader(Shader* shader) { |
| 268 DCHECK(shader); | 286 DCHECK(shader); |
| 269 DCHECK(IsOwned(shader)); | 287 DCHECK(IsOwned(shader)); |
| 270 shader->DecUseCount(); | 288 shader->DecUseCount(); |
| 271 RemoveShader(shader); | 289 RemoveShader(shader); |
| 272 } | 290 } |
| 273 | 291 |
| 274 } // namespace gles2 | 292 } // namespace gles2 |
| 275 } // namespace gpu | 293 } // namespace gpu |
| OLD | NEW |