blob: a95b04ced080e8c3707fd331f47d16e5e6861523 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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
3// found in the LICENSE file.
4
5#include "gpu/command_buffer/service/shader_manager.h"
6
7#include <utility>
8
9#include "base/logging.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010010#include "base/strings/string_util.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000011
12namespace gpu {
13namespace gles2 {
14
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000015Shader::Shader(GLuint service_id, GLenum shader_type)
Torne (Richard Coles)58218062012-11-14 11:43:16 +000016 : use_count_(0),
17 service_id_(service_id),
18 shader_type_(shader_type),
Ben Murdochbb1529c2013-08-08 10:24:53 +010019 valid_(false) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000020}
21
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000022Shader::~Shader() {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000023}
24
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000025void Shader::IncUseCount() {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000026 ++use_count_;
27}
28
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000029void Shader::DecUseCount() {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000030 --use_count_;
31 DCHECK_GE(use_count_, 0);
32}
33
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000034void Shader::MarkAsDeleted() {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000035 DCHECK_NE(service_id_, 0u);
36 service_id_ = 0;
37}
38
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000039void Shader::SetStatus(
Torne (Richard Coles)58218062012-11-14 11:43:16 +000040 bool valid, const char* log, ShaderTranslatorInterface* translator) {
41 valid_ = valid;
42 log_info_.reset(log ? new std::string(log) : NULL);
43 if (translator && valid) {
44 attrib_map_ = translator->attrib_map();
45 uniform_map_ = translator->uniform_map();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000046 name_map_ = translator->name_map();
Torne (Richard Coles)58218062012-11-14 11:43:16 +000047 } else {
48 attrib_map_.clear();
49 uniform_map_.clear();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000050 name_map_.clear();
Torne (Richard Coles)58218062012-11-14 11:43:16 +000051 }
Ben Murdochbb1529c2013-08-08 10:24:53 +010052 if (valid && source_.get()) {
53 signature_source_.reset(new std::string(source_->c_str()));
54 } else {
55 signature_source_.reset();
56 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +000057}
58
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000059const Shader::VariableInfo*
60 Shader::GetAttribInfo(
Torne (Richard Coles)58218062012-11-14 11:43:16 +000061 const std::string& name) const {
62 VariableMap::const_iterator it = attrib_map_.find(name);
63 return it != attrib_map_.end() ? &it->second : NULL;
64}
65
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000066const std::string* Shader::GetAttribMappedName(
Torne (Richard Coles)58218062012-11-14 11:43:16 +000067 const std::string& original_name) const {
68 for (VariableMap::const_iterator it = attrib_map_.begin();
69 it != attrib_map_.end(); ++it) {
70 if (it->second.name == original_name)
71 return &(it->first);
72 }
73 return NULL;
74}
75
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000076const std::string* Shader::GetOriginalNameFromHashedName(
77 const std::string& hashed_name) const {
78 NameMap::const_iterator it = name_map_.find(hashed_name);
79 if (it != name_map_.end())
80 return &(it->second);
81 return NULL;
82}
83
84const Shader::VariableInfo*
85 Shader::GetUniformInfo(
Torne (Richard Coles)58218062012-11-14 11:43:16 +000086 const std::string& name) const {
87 VariableMap::const_iterator it = uniform_map_.find(name);
88 return it != uniform_map_.end() ? &it->second : NULL;
89}
90
91ShaderManager::ShaderManager() {}
92
93ShaderManager::~ShaderManager() {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000094 DCHECK(shaders_.empty());
Torne (Richard Coles)58218062012-11-14 11:43:16 +000095}
96
97void ShaderManager::Destroy(bool have_context) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000098 while (!shaders_.empty()) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000099 if (have_context) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100100 Shader* shader = shaders_.begin()->second.get();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000101 if (!shader->IsDeleted()) {
102 glDeleteShader(shader->service_id());
103 shader->MarkAsDeleted();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000104 }
105 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000106 shaders_.erase(shaders_.begin());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000107 }
108}
109
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000110Shader* ShaderManager::CreateShader(
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000111 GLuint client_id,
112 GLuint service_id,
113 GLenum shader_type) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000114 std::pair<ShaderMap::iterator, bool> result =
115 shaders_.insert(std::make_pair(
116 client_id, scoped_refptr<Shader>(
117 new Shader(service_id, shader_type))));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000118 DCHECK(result.second);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100119 return result.first->second.get();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000120}
121
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000122Shader* ShaderManager::GetShader(GLuint client_id) {
123 ShaderMap::iterator it = shaders_.find(client_id);
Ben Murdocheb525c52013-07-10 11:40:50 +0100124 return it != shaders_.end() ? it->second.get() : NULL;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000125}
126
127bool ShaderManager::GetClientId(GLuint service_id, GLuint* client_id) const {
128 // This doesn't need to be fast. It's only used during slow queries.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000129 for (ShaderMap::const_iterator it = shaders_.begin();
130 it != shaders_.end(); ++it) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000131 if (it->second->service_id() == service_id) {
132 *client_id = it->first;
133 return true;
134 }
135 }
136 return false;
137}
138
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000139bool ShaderManager::IsOwned(Shader* shader) {
140 for (ShaderMap::iterator it = shaders_.begin();
141 it != shaders_.end(); ++it) {
142 if (it->second.get() == shader) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000143 return true;
144 }
145 }
146 return false;
147}
148
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000149void ShaderManager::RemoveShader(Shader* shader) {
150 DCHECK(shader);
151 DCHECK(IsOwned(shader));
152 if (shader->IsDeleted() && !shader->InUse()) {
153 for (ShaderMap::iterator it = shaders_.begin();
154 it != shaders_.end(); ++it) {
155 if (it->second.get() == shader) {
156 shaders_.erase(it);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000157 return;
158 }
159 }
160 NOTREACHED();
161 }
162}
163
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000164void ShaderManager::MarkAsDeleted(Shader* shader) {
165 DCHECK(shader);
166 DCHECK(IsOwned(shader));
167 shader->MarkAsDeleted();
168 RemoveShader(shader);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000169}
170
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000171void ShaderManager::UseShader(Shader* shader) {
172 DCHECK(shader);
173 DCHECK(IsOwned(shader));
174 shader->IncUseCount();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000175}
176
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000177void ShaderManager::UnuseShader(Shader* shader) {
178 DCHECK(shader);
179 DCHECK(IsOwned(shader));
180 shader->DecUseCount();
181 RemoveShader(shader);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000182}
183
184} // namespace gles2
185} // namespace gpu
186
187