Panda3D
Loading...
Searching...
No Matches
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
22ShaderPool *ShaderPool::_global_ptr = nullptr;
23
24/**
25 * Lists the contents of the shader pool to the indicated output stream.
26 */
28write(std::ostream &out) {
29 get_ptr()->ns_list_contents(out);
30}
31
32/**
33 * The nonstatic implementation of has_shader().
34 */
35bool ShaderPool::
36ns_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 */
54CPT(Shader) ShaderPool::
55ns_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 */
117void ShaderPool::
118ns_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 */
130void ShaderPool::
131ns_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 */
144void ShaderPool::
145ns_release_all_shaders() {
146 LightMutexHolder holder(_lock);
147
148 _shaders.clear();
149}
150
151/**
152 * The nonstatic implementation of garbage_collect().
153 */
154int ShaderPool::
155ns_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 */
184void ShaderPool::
185ns_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 */
201void ShaderPool::
202resolve_filename(Filename &new_filename, const Filename &orig_filename) {
203 new_filename = orig_filename;
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 */
212ShaderPool *ShaderPool::
213get_ptr() {
214 if (_global_ptr == nullptr) {
215 _global_ptr = new ShaderPool;
216 }
217 return _global_ptr;
218}
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
std::string get_extension() const
Returns the file extension.
Definition filename.I:400
Similar to MutexHolder, but for a light mutex.
This is the preferred interface for loading shaders for the TextNode system.
Definition shaderPool.h:28
static void write(std::ostream &out)
Lists the contents of the shader pool to the indicated output stream.
A hierarchy of directories and files that appears to be one continuous file system,...
bool resolve_filename(Filename &filename, const DSearchPath &searchpath, const std::string &default_extension=std::string()) const
Searches the given search path for the filename.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
string downcase(const string &s)
Returns the input string with all uppercase letters converted to lowercase.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.