Panda3D

shaderPool.cxx
Go to the documentation of this file.
1 /**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file shaderPool.cxx
10 * @author aignacio
11 * @date 2006-03
12 */
13
14 #include "shaderPool.h"
15 #include "config_putil.h"
16 #include "config_express.h"
17 #include "virtualFileSystem.h"
18 #include "loader.h"
19 #include "shader.h"
20 #include "string_utils.h"
21
22 ShaderPool *ShaderPool::_global_ptr = nullptr;
23
24 /**
25 * Lists the contents of the shader pool to the indicated output stream.
26 */
27 void ShaderPool::
28 write(std::ostream &out) {
29 get_ptr()->ns_list_contents(out);
30 }
31
32 /**
33 * The nonstatic implementation of has_shader().
34 */
35 bool ShaderPool::
36 ns_has_shader(const Filename &orig_filename) {
37 Filename filename;
38 resolve_filename(filename, orig_filename);
39
40 LightMutexHolder holder(_lock);
41 Shaders::const_iterator ti;
42 ti = _shaders.find(filename);
43 if (ti != _shaders.end()) {
44 // This shader was previously loaded.
45 return true;
46 }
47
48 return false;
49 }
50
51 /**
52 * The nonstatic implementation of load_shader().
53 */
54 CPT(Shader) ShaderPool::
55 ns_load_shader(const Filename &orig_filename) {
56 Filename filename;
57 resolve_filename(filename, orig_filename);
58
59 {
60 LightMutexHolder holder(_lock);
61
62 Shaders::const_iterator ti;
63 ti = _shaders.find(filename);
64 if (ti != _shaders.end()) {
65 // This shader was previously loaded.
66 return (*ti).second;
67 }
68 }
69
70 // The shader was not found in the pool.
71 gobj_cat.info()
72 << "Loading shader " << filename << "\n";
73
74 Shader::ShaderLanguage lang = Shader::SL_none;
75
76 // Do some guesswork to see if we can figure out the shader language from
77 // the file extension. This is really just guesswork - there are no
78 // standardized extensions for shaders, especially for GLSL. These are the
79 // ones that appear to be closest to "standard".
80 std::string ext = downcase(filename.get_extension());
81 if (ext == "cg" || ext == "sha") {
82 // "sha" is for historical reasons.
83 lang = Shader::SL_Cg;
84
85 } else if (ext == "glsl" || ext == "vert" || ext == "frag" ||
86 ext == "geom" || ext == "tesc" || ext == "tese" ||
87 ext == "comp") {
88 lang = Shader::SL_GLSL;
89 }
90
91 PT(Shader) shader = Shader::load(filename, lang);
92 if (shader == nullptr) {
93 // This shader was not found or could not be read.
94 return nullptr;
95 }
96
97 {
98 LightMutexHolder holder(_lock);
99
100 // Now try again. Someone may have loaded the shader in another thread.
101 Shaders::const_iterator ti;
102 ti = _shaders.find(filename);
103 if (ti != _shaders.end()) {
104 // This shader was previously loaded.
105 return (*ti).second;
106 }
107
108 _shaders[filename] = shader;
109 }
110
111 return shader;
112 }
113
114 /**
115 * The nonstatic implementation of add_shader().
116 */
117 void ShaderPool::
118 ns_add_shader(const Filename &orig_filename, Shader *shader) {
119 Filename filename;
120 resolve_filename(filename, orig_filename);
121
122 LightMutexHolder holder(_lock);
123 // We blow away whatever shader was there previously, if any.
124 _shaders[filename] = shader;
125 }
126
127 /**
128 * The nonstatic implementation of release_shader().
129 */
130 void ShaderPool::
131 ns_release_shader(const Filename &filename) {
132 LightMutexHolder holder(_lock);
133
134 Shaders::iterator ti;
135 ti = _shaders.find(filename);
136 if (ti != _shaders.end()) {
137 _shaders.erase(ti);
138 }
139 }
140
141 /**
142 * The nonstatic implementation of release_all_shaders().
143 */
144 void ShaderPool::
145 ns_release_all_shaders() {
146 LightMutexHolder holder(_lock);
147
148 _shaders.clear();
149 }
150
151 /**
152 * The nonstatic implementation of garbage_collect().
153 */
154 int ShaderPool::
155 ns_garbage_collect() {
156 LightMutexHolder holder(_lock);
157
158 int num_released = 0;
159 Shaders new_set;
160
161 Shaders::iterator ti;
162 for (ti = _shaders.begin(); ti != _shaders.end(); ++ti) {
163 CPT(Shader) shader = (*ti).second;
164 if (shader->get_ref_count() == 1) {
165 /*
166 if (shader_cat.is_debug()) {
167 shader_cat.debug()
168 << "Releasing " << (*ti).first << "\n";
169 }
170 */
171 num_released++;
172 } else {
173 new_set.insert(new_set.end(), *ti);
174 }
175 }
176
177 _shaders.swap(new_set);
178 return num_released;
179 }
180
181 /**
182 * The nonstatic implementation of list_contents().
183 */
184 void ShaderPool::
185 ns_list_contents(std::ostream &out) const {
186 LightMutexHolder holder(_lock);
187
188 out << _shaders.size() << " shaders:\n";
189 Shaders::const_iterator ti;
190 for (ti = _shaders.begin(); ti != _shaders.end(); ++ti) {
191 CPT(Shader) shader = (*ti).second;
192 out << " " << (*ti).first
193 << " (count = " << shader->get_ref_count() << ")\n";
194 }
195 }
196
197
198 /**
199 * Searches for the indicated filename along the model path.
200 */
201 void ShaderPool::
202 resolve_filename(Filename &new_filename, const Filename &orig_filename) {
203 new_filename = orig_filename;
204 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
205 vfs->resolve_filename(new_filename, get_model_path());
206 }
207
208 /**
209 * Initializes and/or returns the global pointer to the one ShaderPool object
210 * in the system.
211 */
212 ShaderPool *ShaderPool::
213 get_ptr() {
214 if (_global_ptr == nullptr) {
215 _global_ptr = new ShaderPool;
216 }
217 return _global_ptr;
218 }
Filename
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
Filename::get_extension
std::string get_extension() const
Returns the file extension.
Definition: filename.I:400
LightMutexHolder
Similar to MutexHolder, but for a light mutex.
Definition: lightMutexHolder.h:25
ShaderPool
This is the preferred interface for loading shaders for the TextNode system.
Definition: shaderPool.h:28
ShaderPool::write
static void write(std::ostream &out)
Lists the contents of the shader pool to the indicated output stream.
Definition: shaderPool.cxx:28
Shader
Definition: shader.h:49
VirtualFileSystem
A hierarchy of directories and files that appears to be one continuous file system,...
Definition: virtualFileSystem.h:40
VirtualFileSystem::resolve_filename
bool resolve_filename(Filename &filename, const DSearchPath &searchpath, const std::string &default_extension=std::string()) const
Searches the given search path for the filename.
Definition: virtualFileSystem.cxx:640
VirtualFileSystem::get_global_ptr
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
Definition: virtualFileSystem.cxx:741
config_express.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_putil.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
loader.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
CPT
CPT(Shader) ShaderPool
The nonstatic implementation of load_shader().
Definition: shaderPool.cxx:54
shaderPool.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
shader.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
downcase
string downcase(const string &s)
Returns the input string with all uppercase letters converted to lowercase.
Definition: string_utils.cxx:71
string_utils.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtualFileSystem.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.