Panda3D
Loading...
Searching...
No Matches
textureStagePool.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 textureStagePool.cxx
10 * @author drose
11 * @date 2010-05-03
12 */
13
14#include "textureStagePool.h"
15#include "config_gobj.h"
16#include "mutexHolder.h"
17#include "configVariableEnum.h"
18#include "string_utils.h"
19
20using std::istream;
21using std::ostream;
22using std::string;
23
24TextureStagePool *TextureStagePool::_global_ptr = nullptr;
25
26
27/**
28 * Lists the contents of the TextureStage pool to the indicated output stream.
29 */
31write(ostream &out) {
32 get_global_ptr()->ns_list_contents(out);
33}
34
35/**
36 * The constructor is not intended to be called directly; there's only
37 * supposed to be one TextureStagePool in the universe and it constructs
38 * itself.
39 */
40TextureStagePool::
41TextureStagePool() {
42 ConfigVariableEnum<Mode> texture_stage_pool_mode
43 ("texture-stage-pool-mode", M_none,
44 PRC_DESC("Defines the initial value of TextureStagePool::set_mode(). "
45 "Set this to 'none' to disable the use of the TextureStagePool, "
46 "to 'name' to group TextureStages by name only, or 'unique' "
47 "to group together only identical TextureStages."));
48 _mode = texture_stage_pool_mode.get_value();
49}
50
51/**
52 * The nonstatic implementation of get_stage().
53 */
54TextureStage *TextureStagePool::
55ns_get_stage(TextureStage *temp) {
56 MutexHolder holder(_lock);
57
58 switch (_mode) {
59 case M_none:
60 return temp;
61
62 case M_name:
63 {
64 StagesByName::iterator ni = _stages_by_name.find(temp->get_name());
65 if (ni == _stages_by_name.end()) {
66 ni = _stages_by_name.insert(StagesByName::value_type(temp->get_name(), temp)).first;
67 } else {
68 if ((*ni).first != (*ni).second->get_name()) {
69 // The pointer no longer matches the original name. Save a new one.
70 (*ni).second = temp;
71 }
72 }
73 return (*ni).second;
74 }
75
76 case M_unique:
77 {
78 CPT(TextureStage) cpttemp = temp;
79 StagesByProperties::iterator si = _stages_by_properties.find(cpttemp);
80 if (si == _stages_by_properties.end()) {
81 si = _stages_by_properties.insert(StagesByProperties::value_type(new TextureStage(*temp), temp)).first;
82 } else {
83 if (*(*si).first != *(*si).second) {
84 // The pointer no longer matches its original value. Save a new
85 // one.
86 (*si).second = temp;
87 }
88 }
89 return (*si).second;
90 }
91 }
92
93 return nullptr;
94}
95
96/**
97 * The nonstatic implementation of release_stage().
98 */
99void TextureStagePool::
100ns_release_stage(TextureStage *temp) {
101 MutexHolder holder(_lock);
102
103 switch (_mode) {
104 case M_none:
105 break;
106
107 case M_name:
108 _stages_by_name.erase(temp->get_name());
109 break;
110
111 case M_unique:
112 {
113 CPT(TextureStage) cpttemp = temp;
114 _stages_by_properties.erase(cpttemp);
115 }
116 break;
117 }
118}
119
120/**
121 * The nonstatic implementation of release_all_stages().
122 */
123void TextureStagePool::
124ns_release_all_stages() {
125 MutexHolder holder(_lock);
126
127 _stages_by_name.clear();
128 _stages_by_properties.clear();
129}
130
131/**
132 *
133 */
134void TextureStagePool::
135ns_set_mode(TextureStagePool::Mode mode) {
136 MutexHolder holder(_lock);
137
138 if (_mode != mode) {
139 _stages_by_name.clear();
140 _stages_by_properties.clear();
141 _mode = mode;
142 }
143}
144
145/**
146 *
147 */
148TextureStagePool::Mode TextureStagePool::
149ns_get_mode() {
150 MutexHolder holder(_lock);
151
152 return _mode;
153}
154
155/**
156 * The nonstatic implementation of garbage_collect().
157 */
158int TextureStagePool::
159ns_garbage_collect() {
160 MutexHolder holder(_lock);
161
162 switch (_mode) {
163 case M_none:
164 return 0;
165
166 case M_name:
167 {
168 int num_released = 0;
169 StagesByName new_set;
170
171 StagesByName::iterator ni;
172 for (ni = _stages_by_name.begin(); ni != _stages_by_name.end(); ++ni) {
173 const string &name = (*ni).first;
174 TextureStage *ts2 = (*ni).second;
175 if (name != ts2->get_name() || ts2->get_ref_count() == 1) {
176 if (gobj_cat.is_debug()) {
177 gobj_cat.debug()
178 << "Releasing " << name << "\n";
179 }
180 ++num_released;
181 } else {
182 new_set.insert(new_set.end(), *ni);
183 }
184 }
185
186 _stages_by_name.swap(new_set);
187 return num_released;
188 }
189
190 case M_unique:
191 {
192 int num_released = 0;
193 StagesByProperties new_set;
194
195 StagesByProperties::iterator si;
196 for (si = _stages_by_properties.begin(); si != _stages_by_properties.end(); ++si) {
197 const TextureStage *ts1 = (*si).first;
198 TextureStage *ts2 = (*si).second;
199 if ((*ts1) != (*ts2) || ts2->get_ref_count() == 1) {
200 if (gobj_cat.is_debug()) {
201 gobj_cat.debug()
202 << "Releasing " << *ts1 << "\n";
203 }
204 ++num_released;
205 } else {
206 new_set.insert(new_set.end(), *si);
207 }
208 }
209
210 _stages_by_properties.swap(new_set);
211 return num_released;
212 }
213 }
214
215 return 0;
216}
217
218/**
219 * The nonstatic implementation of list_contents().
220 */
221void TextureStagePool::
222ns_list_contents(ostream &out) const {
223 MutexHolder holder(_lock);
224
225 out << "TextureStagePool in mode " << _mode << "\n";
226
227 switch (_mode) {
228 case M_none:
229 break;
230
231 case M_name:
232 {
233 out << _stages_by_name.size() << " TextureStages:\n";
234 StagesByName::const_iterator ni;
235 for (ni = _stages_by_name.begin(); ni != _stages_by_name.end(); ++ni) {
236 const string &name = (*ni).first;
237 TextureStage *ts2 = (*ni).second;
238 out << " " << name
239 << " (count = " << ts2->get_ref_count() << ")\n";
240 }
241 }
242 break;
243
244 case M_unique:
245 {
246 out << _stages_by_properties.size() << " TextureStages:\n";
247 StagesByProperties::const_iterator si;
248 for (si = _stages_by_properties.begin(); si != _stages_by_properties.end(); ++si) {
249 const TextureStage *ts1 = (*si).first;
250 TextureStage *ts2 = (*si).second;
251 out << " " << *ts1
252 << " (count = " << ts2->get_ref_count() << ")\n";
253 }
254 }
255 break;
256 }
257}
258
259/**
260 * Initializes and/or returns the global pointer to the one TextureStagePool
261 * object in the system.
262 */
263TextureStagePool *TextureStagePool::
264get_global_ptr() {
265 if (_global_ptr == nullptr) {
266 _global_ptr = new TextureStagePool;
267 }
268 return _global_ptr;
269}
270
271/**
272 *
273 */
274ostream &
275operator << (ostream &out, TextureStagePool::Mode mode) {
276 switch (mode) {
277 case TextureStagePool::M_none:
278 return out << "none";
279
280 case TextureStagePool::M_name:
281 return out << "name";
282
283 case TextureStagePool::M_unique:
284 return out << "unique";
285 }
286
287 return out << "**invalid mode (" << (int)mode << ")**";
288}
289
290/**
291 *
292 */
293istream &
294operator >> (istream &in, TextureStagePool::Mode &mode) {
295 string word;
296 in >> word;
297
298 if (cmp_nocase(word, "none") == 0) {
299 mode = TextureStagePool::M_none;
300 } else if (cmp_nocase(word, "name") == 0) {
301 mode = TextureStagePool::M_name;
302 } else if (cmp_nocase(word, "unique") == 0) {
303 mode = TextureStagePool::M_unique;
304
305 } else {
306 gobj_cat->error() << "Invalid TextureStagePool mode value: " << word << "\n";
307 mode = TextureStagePool::M_none;
308 }
309
310 return in;
311}
This class specializes ConfigVariable as an enumerated type.
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
Definition mutexHolder.h:25
get_ref_count
Returns the current reference count.
The TextureStagePool (there is only one in the universe) serves to unify different pointers to the sa...
static void write(std::ostream &out)
Lists the contents of the TextureStage pool to the indicated output stream.
Defines the properties of a named stage of the multitexture pipeline.
get_name
Returns the name of this texture stage.
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.