00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "textureStagePool.h"
00017 #include "config_gobj.h"
00018 #include "mutexHolder.h"
00019 #include "configVariableEnum.h"
00020
00021 TextureStagePool *TextureStagePool::_global_ptr = (TextureStagePool *)NULL;
00022
00023
00024
00025
00026
00027
00028
00029
00030 void TextureStagePool::
00031 write(ostream &out) {
00032 get_global_ptr()->ns_list_contents(out);
00033 }
00034
00035
00036
00037
00038
00039
00040
00041
00042 TextureStagePool::
00043 TextureStagePool() {
00044 ConfigVariableEnum<Mode> texture_stage_pool_mode
00045 ("texture-stage-pool-mode", M_none,
00046 PRC_DESC("Defines the initial value of TextureStagePool::set_mode(). "
00047 "Set this to 'none' to disable the use of the TextureStagePool, "
00048 "to 'name' to group TextureStages by name only, or 'unique' "
00049 "to group together only identical TextureStages."));
00050 _mode = texture_stage_pool_mode.get_value();
00051 }
00052
00053
00054
00055
00056
00057
00058 TextureStage *TextureStagePool::
00059 ns_get_stage(TextureStage *temp) {
00060 MutexHolder holder(_lock);
00061
00062 switch (_mode) {
00063 case M_none:
00064 return temp;
00065
00066 case M_name:
00067 {
00068 StagesByName::iterator ni = _stages_by_name.find(temp->get_name());
00069 if (ni == _stages_by_name.end()) {
00070 ni = _stages_by_name.insert(StagesByName::value_type(temp->get_name(), temp)).first;
00071 } else {
00072 if ((*ni).first != (*ni).second->get_name()) {
00073
00074
00075 (*ni).second = temp;
00076 }
00077 }
00078 return (*ni).second;
00079 }
00080
00081 case M_unique:
00082 {
00083 CPT(TextureStage) cpttemp = temp;
00084 StagesByProperties::iterator si = _stages_by_properties.find(cpttemp);
00085 if (si == _stages_by_properties.end()) {
00086 si = _stages_by_properties.insert(StagesByProperties::value_type(new TextureStage(*temp), temp)).first;
00087 } else {
00088 if (*(*si).first != *(*si).second) {
00089
00090
00091 (*si).second = temp;
00092 }
00093 }
00094 return (*si).second;
00095 }
00096 }
00097
00098 return NULL;
00099 }
00100
00101
00102
00103
00104
00105
00106 void TextureStagePool::
00107 ns_release_stage(TextureStage *temp) {
00108 MutexHolder holder(_lock);
00109
00110 switch (_mode) {
00111 case M_none:
00112 break;
00113
00114 case M_name:
00115 _stages_by_name.erase(temp->get_name());
00116 break;
00117
00118 case M_unique:
00119 {
00120 CPT(TextureStage) cpttemp = temp;
00121 _stages_by_properties.erase(cpttemp);
00122 }
00123 break;
00124 }
00125 }
00126
00127
00128
00129
00130
00131
00132 void TextureStagePool::
00133 ns_release_all_stages() {
00134 MutexHolder holder(_lock);
00135
00136 _stages_by_name.clear();
00137 _stages_by_properties.clear();
00138 }
00139
00140
00141
00142
00143
00144
00145 void TextureStagePool::
00146 ns_set_mode(TextureStagePool::Mode mode) {
00147 MutexHolder holder(_lock);
00148
00149 if (_mode != mode) {
00150 _stages_by_name.clear();
00151 _stages_by_properties.clear();
00152 _mode = mode;
00153 }
00154 }
00155
00156
00157
00158
00159
00160
00161 TextureStagePool::Mode TextureStagePool::
00162 ns_get_mode() {
00163 MutexHolder holder(_lock);
00164
00165 return _mode;
00166 }
00167
00168
00169
00170
00171
00172
00173 int TextureStagePool::
00174 ns_garbage_collect() {
00175 MutexHolder holder(_lock);
00176
00177 switch (_mode) {
00178 case M_none:
00179 return 0;
00180
00181 case M_name:
00182 {
00183 int num_released = 0;
00184 StagesByName new_set;
00185
00186 StagesByName::iterator ni;
00187 for (ni = _stages_by_name.begin(); ni != _stages_by_name.end(); ++ni) {
00188 const string &name = (*ni).first;
00189 TextureStage *ts2 = (*ni).second;
00190 if (name != ts2->get_name() || ts2->get_ref_count() == 1) {
00191 if (gobj_cat.is_debug()) {
00192 gobj_cat.debug()
00193 << "Releasing " << name << "\n";
00194 }
00195 ++num_released;
00196 } else {
00197 new_set.insert(new_set.end(), *ni);
00198 }
00199 }
00200
00201 _stages_by_name.swap(new_set);
00202 return num_released;
00203 }
00204
00205 case M_unique:
00206 {
00207 int num_released = 0;
00208 StagesByProperties new_set;
00209
00210 StagesByProperties::iterator si;
00211 for (si = _stages_by_properties.begin(); si != _stages_by_properties.end(); ++si) {
00212 const TextureStage *ts1 = (*si).first;
00213 TextureStage *ts2 = (*si).second;
00214 if ((*ts1) != (*ts2) || ts2->get_ref_count() == 1) {
00215 if (gobj_cat.is_debug()) {
00216 gobj_cat.debug()
00217 << "Releasing " << *ts1 << "\n";
00218 }
00219 ++num_released;
00220 } else {
00221 new_set.insert(new_set.end(), *si);
00222 }
00223 }
00224
00225 _stages_by_properties.swap(new_set);
00226 return num_released;
00227 }
00228 }
00229
00230 return 0;
00231 }
00232
00233
00234
00235
00236
00237
00238 void TextureStagePool::
00239 ns_list_contents(ostream &out) const {
00240 MutexHolder holder(_lock);
00241
00242 out << "TextureStagePool in mode " << _mode << "\n";
00243
00244 switch (_mode) {
00245 case M_none:
00246 break;
00247
00248 case M_name:
00249 {
00250 out << _stages_by_name.size() << " TextureStages:\n";
00251 StagesByName::const_iterator ni;
00252 for (ni = _stages_by_name.begin(); ni != _stages_by_name.end(); ++ni) {
00253 const string &name = (*ni).first;
00254 TextureStage *ts2 = (*ni).second;
00255 out << " " << name
00256 << " (count = " << ts2->get_ref_count() << ")\n";
00257 }
00258 }
00259 break;
00260
00261 case M_unique:
00262 {
00263 out << _stages_by_properties.size() << " TextureStages:\n";
00264 StagesByProperties::const_iterator si;
00265 for (si = _stages_by_properties.begin(); si != _stages_by_properties.end(); ++si) {
00266 const TextureStage *ts1 = (*si).first;
00267 TextureStage *ts2 = (*si).second;
00268 out << " " << *ts1
00269 << " (count = " << ts2->get_ref_count() << ")\n";
00270 }
00271 }
00272 break;
00273 }
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 TextureStagePool *TextureStagePool::
00283 get_global_ptr() {
00284 if (_global_ptr == (TextureStagePool *)NULL) {
00285 _global_ptr = new TextureStagePool;
00286 }
00287 return _global_ptr;
00288 }
00289
00290
00291
00292
00293
00294 ostream &
00295 operator << (ostream &out, TextureStagePool::Mode mode) {
00296 switch (mode) {
00297 case TextureStagePool::M_none:
00298 return out << "none";
00299
00300 case TextureStagePool::M_name:
00301 return out << "name";
00302
00303 case TextureStagePool::M_unique:
00304 return out << "unique";
00305 }
00306
00307 return out << "**invalid mode (" << (int)mode << ")**";
00308 }
00309
00310
00311
00312
00313
00314 istream &
00315 operator >> (istream &in, TextureStagePool::Mode &mode) {
00316 string word;
00317 in >> word;
00318
00319 if (cmp_nocase(word, "none") == 0) {
00320 mode = TextureStagePool::M_none;
00321 } else if (cmp_nocase(word, "name") == 0) {
00322 mode = TextureStagePool::M_name;
00323 } else if (cmp_nocase(word, "unique") == 0) {
00324 mode = TextureStagePool::M_unique;
00325
00326 } else {
00327 gobj_cat->error() << "Invalid TextureStagePool mode value: " << word << "\n";
00328 mode = TextureStagePool::M_none;
00329 }
00330
00331 return in;
00332 }