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 |