| 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 service_id_(service_id), | 30 service_id_(service_id), |
| 30 shader_type_(shader_type), | 31 shader_type_(shader_type), |
| 31 valid_(false) { | 32 valid_(false) { |
| 32 } | 33 } |
| 33 | 34 |
| 34 Shader::~Shader() { | 35 Shader::~Shader() { |
| 35 } | 36 } |
| 36 | 37 |
| 38 void Shader::RequestCompile() { |
| 39 shader_state_ = kShaderStateCompileRequested; |
| 40 last_compiled_source_ = source_; |
| 41 } |
| 42 |
| 37 void Shader::DoCompile(ShaderTranslatorInterface* translator, | 43 void Shader::DoCompile(ShaderTranslatorInterface* translator, |
| 38 TranslatedShaderSourceType type) { | 44 TranslatedShaderSourceType type) { |
| 45 // We require that RequestCompile() must be called before DoCompile(), |
| 46 // so we can return early if the shader state is not what we expect. |
| 47 if (shader_state_ != kShaderStateCompileRequested) { |
| 48 return; |
| 49 } |
| 50 |
| 51 // Signify the shader has been compiled, whether or not it is valid |
| 52 // is dependent on the |valid_| member variable. |
| 53 shader_state_ = kShaderStateCompiled; |
| 54 |
| 39 // Translate GL ES 2.0 shader to Desktop GL shader and pass that to | 55 // Translate GL ES 2.0 shader to Desktop GL shader and pass that to |
| 40 // glShaderSource and then glCompileShader. | 56 // glShaderSource and then glCompileShader. |
| 41 const char* source_for_driver = source_.c_str(); | 57 const char* source_for_driver = last_compiled_source_.c_str(); |
| 42 if (translator) { | 58 if (translator) { |
| 43 valid_ = translator->Translate(source_, | 59 valid_ = translator->Translate(last_compiled_source_, |
| 44 &log_info_, | 60 &log_info_, |
| 45 &translated_source_, | 61 &translated_source_, |
| 46 &attrib_map_, | 62 &attrib_map_, |
| 47 &uniform_map_, | 63 &uniform_map_, |
| 48 &varying_map_, | 64 &varying_map_, |
| 49 &name_map_); | 65 &name_map_); |
| 50 if (!valid_) { | 66 if (!valid_) { |
| 51 return; | 67 return; |
| 52 } | 68 } |
| 53 signature_source_ = source_; | |
| 54 source_for_driver = translated_source_.c_str(); | 69 source_for_driver = translated_source_.c_str(); |
| 55 } | 70 } |
| 56 | 71 |
| 57 glShaderSource(service_id_, 1, &source_for_driver, NULL); | 72 glShaderSource(service_id_, 1, &source_for_driver, NULL); |
| 58 glCompileShader(service_id_); | 73 glCompileShader(service_id_); |
| 59 if (type == kANGLE) { | 74 if (type == kANGLE) { |
| 60 GLint max_len = 0; | 75 GLint max_len = 0; |
| 61 glGetShaderiv(service_id_, | 76 glGetShaderiv(service_id_, |
| 62 GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, | 77 GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, |
| 63 &max_len); | 78 &max_len); |
| 64 scoped_ptr<char[]> buffer(new char[max_len]); | 79 translated_source_.resize(max_len); |
| 65 GLint len = 0; | 80 GLint len = 0; |
| 66 glGetTranslatedShaderSourceANGLE( | 81 glGetTranslatedShaderSourceANGLE( |
| 67 service_id_, max_len, &len, buffer.get()); | 82 service_id_, translated_source_.size(), |
| 83 &len, &translated_source_.at(0)); |
| 68 DCHECK(max_len == 0 || len < max_len); | 84 DCHECK(max_len == 0 || len < max_len); |
| 69 DCHECK(len == 0 || buffer[len] == '\0'); | 85 DCHECK(len == 0 || translated_source_[len] == '\0'); |
| 70 translated_source_ = std::string(buffer.get(), len); | 86 translated_source_.resize(len); |
| 71 } | 87 } |
| 72 | 88 |
| 73 GLint status = GL_FALSE; | 89 GLint status = GL_FALSE; |
| 74 glGetShaderiv(service_id_, GL_COMPILE_STATUS, &status); | 90 glGetShaderiv(service_id_, GL_COMPILE_STATUS, &status); |
| 75 if (status != GL_TRUE) { | 91 if (status != GL_TRUE) { |
| 76 // We cannot reach here if we are using the shader translator. | 92 // We cannot reach here if we are using the shader translator. |
| 77 // All invalid shaders must be rejected by the translator. | 93 // All invalid shaders must be rejected by the translator. |
| 78 // All translated shaders must compile. | 94 // All translated shaders must compile. |
| 79 GLint max_len = 0; | 95 GLint max_len = 0; |
| 80 glGetShaderiv(service_id_, GL_INFO_LOG_LENGTH, &max_len); | 96 glGetShaderiv(service_id_, GL_INFO_LOG_LENGTH, &max_len); |
| 81 scoped_ptr<char[]> buffer(new char[max_len]); | 97 log_info_.resize(max_len); |
| 82 GLint len = 0; | 98 GLint len = 0; |
| 83 glGetShaderInfoLog(service_id_, max_len, &len, buffer.get()); | 99 glGetShaderInfoLog(service_id_, log_info_.size(), &len, &log_info_.at(0)); |
| 84 DCHECK(max_len == 0 || len < max_len); | 100 DCHECK(max_len == 0 || len < max_len); |
| 85 DCHECK(len == 0 || buffer[len] == '\0'); | 101 DCHECK(len == 0 || log_info_[len] == '\0'); |
| 86 valid_ = false; | 102 valid_ = false; |
| 87 log_info_ = std::string(buffer.get(), len); | 103 log_info_.resize(len); |
| 88 LOG_IF(ERROR, translator) | 104 LOG_IF(ERROR, translator) |
| 89 << "Shader translator allowed/produced an invalid shader " | 105 << "Shader translator allowed/produced an invalid shader " |
| 90 << "unless the driver is buggy:" | 106 << "unless the driver is buggy:" |
| 91 << "\n--original-shader--\n" << source_ | 107 << "\n--original-shader--\n" << last_compiled_source_ |
| 92 << "\n--translated-shader--\n" << source_for_driver | 108 << "\n--translated-shader--\n" << source_for_driver |
| 93 << "\n--info-log--\n" << log_info_; | 109 << "\n--info-log--\n" << log_info_; |
| 94 } | 110 } |
| 95 } | 111 } |
| 96 | 112 |
| 97 void Shader::IncUseCount() { | 113 void Shader::IncUseCount() { |
| 98 ++use_count_; | 114 ++use_count_; |
| 99 } | 115 } |
| 100 | 116 |
| 101 void Shader::DecUseCount() { | 117 void Shader::DecUseCount() { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 DCHECK(shader); | 250 DCHECK(shader); |
| 235 DCHECK(IsOwned(shader)); | 251 DCHECK(IsOwned(shader)); |
| 236 shader->DecUseCount(); | 252 shader->DecUseCount(); |
| 237 RemoveShader(shader); | 253 RemoveShader(shader); |
| 238 } | 254 } |
| 239 | 255 |
| 240 } // namespace gles2 | 256 } // namespace gles2 |
| 241 } // namespace gpu | 257 } // namespace gpu |
| 242 | 258 |
| 243 | 259 |
| OLD | NEW |