blob: b3ea27ed19faf0210f228bf86c439b52d4d98728 [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),
19 valid_(false),
20 compilation_status_(NOT_COMPILED) {
21}
22
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000023Shader::~Shader() {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000024}
25
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000026void Shader::IncUseCount() {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000027 ++use_count_;
28}
29
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000030void Shader::DecUseCount() {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000031 --use_count_;
32 DCHECK_GE(use_count_, 0);
33}
34
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000035void Shader::MarkAsDeleted() {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000036 DCHECK_NE(service_id_, 0u);
37 service_id_ = 0;
38}
39
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000040void Shader::SetStatus(
Torne (Richard Coles)58218062012-11-14 11:43:16 +000041 bool valid, const char* log, ShaderTranslatorInterface* translator) {
42 valid_ = valid;
43 log_info_.reset(log ? new std::string(log) : NULL);
44 if (translator && valid) {
45 attrib_map_ = translator->attrib_map();
46 uniform_map_ = translator->uniform_map();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000047 name_map_ = translator->name_map();
Torne (Richard Coles)58218062012-11-14 11:43:16 +000048 } else {
49 attrib_map_.clear();
50 uniform_map_.clear();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000051 name_map_.clear();
Torne (Richard Coles)58218062012-11-14 11:43:16 +000052 }
53}
54
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000055const Shader::VariableInfo*
56 Shader::GetAttribInfo(
Torne (Richard Coles)58218062012-11-14 11:43:16 +000057 const std::string& name) const {
58 VariableMap::const_iterator it = attrib_map_.find(name);
59 return it != attrib_map_.end() ? &it->second : NULL;
60}
61
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000062const std::string* Shader::GetAttribMappedName(
Torne (Richard Coles)58218062012-11-14 11:43:16 +000063 const std::string& original_name) const {
64 for (VariableMap::const_iterator it = attrib_map_.begin();
65 it != attrib_map_.end(); ++it) {
66 if (it->second.name == original_name)
67 return &(it->first);
68 }
69 return NULL;
70}
71
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000072const std::string* Shader::GetOriginalNameFromHashedName(
73 const std::string& hashed_name) const {
74 NameMap::const_iterator it = name_map_.find(hashed_name);
75 if (it != name_map_.end())
76 return &(it->second);
77 return NULL;
78}
79
80const Shader::VariableInfo*
81 Shader::GetUniformInfo(
Torne (Richard Coles)58218062012-11-14 11:43:16 +000082 const std::string& name) const {
83 VariableMap::const_iterator it = uniform_map_.find(name);
84 return it != uniform_map_.end() ? &it->second : NULL;
85}
86
87ShaderManager::ShaderManager() {}
88
89ShaderManager::~ShaderManager() {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000090 DCHECK(shaders_.empty());
Torne (Richard Coles)58218062012-11-14 11:43:16 +000091}
92
93void ShaderManager::Destroy(bool have_context) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000094 while (!shaders_.empty()) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000095 if (have_context) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010096 Shader* shader = shaders_.begin()->second.get();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000097 if (!shader->IsDeleted()) {
98 glDeleteShader(shader->service_id());
99 shader->MarkAsDeleted();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000100 }
101 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000102 shaders_.erase(shaders_.begin());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000103 }
104}
105
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000106Shader* ShaderManager::CreateShader(
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000107 GLuint client_id,
108 GLuint service_id,
109 GLenum shader_type) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000110 std::pair<ShaderMap::iterator, bool> result =
111 shaders_.insert(std::make_pair(
112 client_id, scoped_refptr<Shader>(
113 new Shader(service_id, shader_type))));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000114 DCHECK(result.second);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100115 return result.first->second.get();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000116}
117
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000118Shader* ShaderManager::GetShader(GLuint client_id) {
119 ShaderMap::iterator it = shaders_.find(client_id);
120 return it != shaders_.end() ? it->second : NULL;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000121}
122
123bool ShaderManager::GetClientId(GLuint service_id, GLuint* client_id) const {
124 // This doesn't need to be fast. It's only used during slow queries.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000125 for (ShaderMap::const_iterator it = shaders_.begin();
126 it != shaders_.end(); ++it) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000127 if (it->second->service_id() == service_id) {
128 *client_id = it->first;
129 return true;
130 }
131 }
132 return false;
133}
134
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000135bool ShaderManager::IsOwned(Shader* shader) {
136 for (ShaderMap::iterator it = shaders_.begin();
137 it != shaders_.end(); ++it) {
138 if (it->second.get() == shader) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000139 return true;
140 }
141 }
142 return false;
143}
144
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000145void ShaderManager::RemoveShader(Shader* shader) {
146 DCHECK(shader);
147 DCHECK(IsOwned(shader));
148 if (shader->IsDeleted() && !shader->InUse()) {
149 for (ShaderMap::iterator it = shaders_.begin();
150 it != shaders_.end(); ++it) {
151 if (it->second.get() == shader) {
152 shaders_.erase(it);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000153 return;
154 }
155 }
156 NOTREACHED();
157 }
158}
159
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000160void ShaderManager::MarkAsDeleted(Shader* shader) {
161 DCHECK(shader);
162 DCHECK(IsOwned(shader));
163 shader->MarkAsDeleted();
164 RemoveShader(shader);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000165}
166
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000167void ShaderManager::UseShader(Shader* shader) {
168 DCHECK(shader);
169 DCHECK(IsOwned(shader));
170 shader->IncUseCount();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000171}
172
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000173void ShaderManager::UnuseShader(Shader* shader) {
174 DCHECK(shader);
175 DCHECK(IsOwned(shader));
176 shader->DecUseCount();
177 RemoveShader(shader);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000178}
179
180} // namespace gles2
181} // namespace gpu
182
183