summaryrefslogtreecommitdiff
path: root/chromium/gpu/command_buffer/service/shader_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/gpu/command_buffer/service/shader_manager.cc')
-rw-r--r--chromium/gpu/command_buffer/service/shader_manager.cc187
1 files changed, 187 insertions, 0 deletions
diff --git a/chromium/gpu/command_buffer/service/shader_manager.cc b/chromium/gpu/command_buffer/service/shader_manager.cc
new file mode 100644
index 00000000000..a95b04ced08
--- /dev/null
+++ b/chromium/gpu/command_buffer/service/shader_manager.cc
@@ -0,0 +1,187 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/shader_manager.h"
+
+#include <utility>
+
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+
+namespace gpu {
+namespace gles2 {
+
+Shader::Shader(GLuint service_id, GLenum shader_type)
+ : use_count_(0),
+ service_id_(service_id),
+ shader_type_(shader_type),
+ valid_(false) {
+}
+
+Shader::~Shader() {
+}
+
+void Shader::IncUseCount() {
+ ++use_count_;
+}
+
+void Shader::DecUseCount() {
+ --use_count_;
+ DCHECK_GE(use_count_, 0);
+}
+
+void Shader::MarkAsDeleted() {
+ DCHECK_NE(service_id_, 0u);
+ service_id_ = 0;
+}
+
+void Shader::SetStatus(
+ bool valid, const char* log, ShaderTranslatorInterface* translator) {
+ valid_ = valid;
+ log_info_.reset(log ? new std::string(log) : NULL);
+ if (translator && valid) {
+ attrib_map_ = translator->attrib_map();
+ uniform_map_ = translator->uniform_map();
+ name_map_ = translator->name_map();
+ } else {
+ attrib_map_.clear();
+ uniform_map_.clear();
+ name_map_.clear();
+ }
+ if (valid && source_.get()) {
+ signature_source_.reset(new std::string(source_->c_str()));
+ } else {
+ signature_source_.reset();
+ }
+}
+
+const Shader::VariableInfo*
+ Shader::GetAttribInfo(
+ const std::string& name) const {
+ VariableMap::const_iterator it = attrib_map_.find(name);
+ return it != attrib_map_.end() ? &it->second : NULL;
+}
+
+const std::string* Shader::GetAttribMappedName(
+ const std::string& original_name) const {
+ for (VariableMap::const_iterator it = attrib_map_.begin();
+ it != attrib_map_.end(); ++it) {
+ if (it->second.name == original_name)
+ return &(it->first);
+ }
+ return NULL;
+}
+
+const std::string* Shader::GetOriginalNameFromHashedName(
+ const std::string& hashed_name) const {
+ NameMap::const_iterator it = name_map_.find(hashed_name);
+ if (it != name_map_.end())
+ return &(it->second);
+ return NULL;
+}
+
+const Shader::VariableInfo*
+ Shader::GetUniformInfo(
+ const std::string& name) const {
+ VariableMap::const_iterator it = uniform_map_.find(name);
+ return it != uniform_map_.end() ? &it->second : NULL;
+}
+
+ShaderManager::ShaderManager() {}
+
+ShaderManager::~ShaderManager() {
+ DCHECK(shaders_.empty());
+}
+
+void ShaderManager::Destroy(bool have_context) {
+ while (!shaders_.empty()) {
+ if (have_context) {
+ Shader* shader = shaders_.begin()->second.get();
+ if (!shader->IsDeleted()) {
+ glDeleteShader(shader->service_id());
+ shader->MarkAsDeleted();
+ }
+ }
+ shaders_.erase(shaders_.begin());
+ }
+}
+
+Shader* ShaderManager::CreateShader(
+ GLuint client_id,
+ GLuint service_id,
+ GLenum shader_type) {
+ std::pair<ShaderMap::iterator, bool> result =
+ shaders_.insert(std::make_pair(
+ client_id, scoped_refptr<Shader>(
+ new Shader(service_id, shader_type))));
+ DCHECK(result.second);
+ return result.first->second.get();
+}
+
+Shader* ShaderManager::GetShader(GLuint client_id) {
+ ShaderMap::iterator it = shaders_.find(client_id);
+ return it != shaders_.end() ? it->second.get() : NULL;
+}
+
+bool ShaderManager::GetClientId(GLuint service_id, GLuint* client_id) const {
+ // This doesn't need to be fast. It's only used during slow queries.
+ for (ShaderMap::const_iterator it = shaders_.begin();
+ it != shaders_.end(); ++it) {
+ if (it->second->service_id() == service_id) {
+ *client_id = it->first;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ShaderManager::IsOwned(Shader* shader) {
+ for (ShaderMap::iterator it = shaders_.begin();
+ it != shaders_.end(); ++it) {
+ if (it->second.get() == shader) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void ShaderManager::RemoveShader(Shader* shader) {
+ DCHECK(shader);
+ DCHECK(IsOwned(shader));
+ if (shader->IsDeleted() && !shader->InUse()) {
+ for (ShaderMap::iterator it = shaders_.begin();
+ it != shaders_.end(); ++it) {
+ if (it->second.get() == shader) {
+ shaders_.erase(it);
+ return;
+ }
+ }
+ NOTREACHED();
+ }
+}
+
+void ShaderManager::MarkAsDeleted(Shader* shader) {
+ DCHECK(shader);
+ DCHECK(IsOwned(shader));
+ shader->MarkAsDeleted();
+ RemoveShader(shader);
+}
+
+void ShaderManager::UseShader(Shader* shader) {
+ DCHECK(shader);
+ DCHECK(IsOwned(shader));
+ shader->IncUseCount();
+}
+
+void ShaderManager::UnuseShader(Shader* shader) {
+ DCHECK(shader);
+ DCHECK(IsOwned(shader));
+ shader->DecUseCount();
+ RemoveShader(shader);
+}
+
+} // namespace gles2
+} // namespace gpu
+
+