15 #include "geomMunger.h"
17 #include "geomCacheManager.h"
18 #include "lightMutexHolder.h"
19 #include "lightReMutexHolder.h"
20 #include "pStatTimer.h"
22 GeomMunger::Registry *GeomMunger::_registry = NULL;
38 Registry *registry = get_registry();
40 _registered_key = registry->_mungers.end();
54 Registry *registry = get_registry();
56 _registered_key = registry->_mungers.end();
67 nassertv(!_is_registered);
78 nassertv(_formats_by_animation.empty());
91 nassertv(_is_registered);
112 bool force,
Thread *current_thread) {
121 Geom::Cache::const_iterator ci = geom->_cache.find(&key);
122 if (ci == geom->_cache.end()) {
125 entry = (*ci).second;
127 nassertr(entry->_source == geom,
false);
132 entry->refresh(current_thread);
136 if (cdata->_source == geom &&
137 cdata->_geom_result != (
Geom *)NULL &&
138 geom->
get_modified(current_thread) <= cdata->_geom_result->get_modified(current_thread) &&
139 data->
get_modified(current_thread) <= cdata->_data_result->get_modified(current_thread)) {
142 geom = cdata->_geom_result;
143 data = cdata->_data_result;
159 PStatTimer timer(_munge_pcollector, current_thread);
161 PT(
Geom) orig_geom = (
Geom *)geom.p();
162 data = munge_data(data);
163 munge_geom_impl(geom, data, current_thread);
168 #ifdef USE_MOVE_SEMANTICS
176 bool inserted = orig_geom->_cache.insert(Geom::Cache::value_type(&entry->_key, entry)).second;
187 entry->record(current_thread);
192 cdata->_source = (
Geom *)orig_geom.p();
193 cdata->set_result(geom, data);
205 do_munge_format(const GeomVertexFormat *format,
207 nassertr(_is_registered, NULL);
208 nassertr(format->is_registered(), NULL);
212 Formats &formats = _formats_by_animation[animation];
214 Formats::iterator fi;
215 fi = formats.find(format);
216 if (fi != formats.end()) {
223 CPT(GeomVertexFormat) derived_format = munge_format_impl(format, animation);
224 nassertr(derived_format->is_registered(), NULL);
227 bool inserted = formats.insert(Formats::value_type(format, derived_format)).second;
228 nassertr(inserted, NULL);
230 return derived_format;
252 nassertr(_is_registered, NULL);
254 CPT(GeomVertexFormat) orig_format = data->get_format();
255 CPT(GeomVertexFormat) new_format =
256 munge_format(orig_format, orig_format->get_animation());
258 if (new_format == orig_format) {
263 return data->convert_to(new_format);
284 do_premunge_format(const GeomVertexFormat *format) {
285 nassertr(_is_registered, NULL);
286 nassertr(format->is_registered(), NULL);
290 Formats::iterator fi;
291 fi = _premunge_formats.find(format);
292 if (fi != _premunge_formats.end()) {
299 CPT(GeomVertexFormat) derived_format = premunge_format_impl(format);
300 nassertr(derived_format->is_registered(), NULL);
303 bool inserted = _premunge_formats.insert(Formats::value_type(format, derived_format)).second;
304 nassertr(inserted, NULL);
306 return derived_format;
316 premunge_format_impl(const GeomVertexFormat *orig) {
328 nassertr(_is_registered, NULL);
330 CPT(GeomVertexFormat) orig_format = data->get_format();
331 CPT(GeomVertexFormat) new_format = premunge_format(orig_format);
333 if (new_format == orig_format) {
338 return data->convert_to(new_format);
361 compare_to_impl(
const GeomMunger *other)
const {
376 geom_compare_to_impl(
const GeomMunger *other)
const {
387 if (_registry == (Registry *)NULL) {
388 _registry =
new Registry;
398 do_register(
Thread *current_thread) {
399 if (gobj_cat.is_debug()) {
401 <<
"GeomMunger::do_register(): " << (
void *)
this <<
"\n";
403 nassertv(!_is_registered);
404 nassertv(_formats_by_animation.empty());
409 CacheEntry *entry =
new CacheEntry;
410 entry->_munger =
this;
411 entry->record(current_thread);
413 _is_registered =
true;
423 if (gobj_cat.is_debug()) {
425 <<
"GeomMunger::do_unregister(): " << (
void *)
this <<
"\n";
427 nassertv(_is_registered);
428 _is_registered =
false;
431 _formats_by_animation.clear();
439 void GeomMunger::CacheEntry::
440 output(ostream &out)
const {
441 out <<
"munger " << _munger;
449 GeomMunger::Registry::
470 if (munger->is_registered()) {
481 Mungers::iterator mi = _mungers.insert(munger).first;
483 if (!new_munger->is_registered()) {
484 new_munger->_registered_key = mi;
485 new_munger->do_register(current_thread);
498 void GeomMunger::Registry::
503 nassertv(munger->_registered_key != _mungers.end());
504 _mungers.erase(munger->_registered_key);
505 munger->_registered_key = _mungers.end();
506 munger->do_unregister();
515 void GeomMunger::Registry::
519 Mungers::iterator mi = _mungers.begin();
520 while (mi != _mungers.end()) {
522 Mungers::iterator mnext = mi;
525 if (munger->
get_gsg() == gsg) {
526 nassertv(mi == munger->_registered_key);
528 munger->_registered_key = _mungers.end();
529 munger->do_unregister();
void release() const
Releases the lightMutex.
void acquire() const
Grabs the lightMutex if it is available.
bool request_resident() const
Returns true if all the primitive arrays are currently resident in memory.
This object describes how the vertex animation, if any, represented in a GeomVertexData is encoded...
void remove_data(const GeomVertexData *data)
Removes a prepared GeomVertexData from the cache.
bool request_resident() const
Returns true if the vertex data is currently resident in memory.
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
UpdateSeq get_modified(Thread *current_thread=Thread::get_current_thread()) const
Returns a sequence number which is guaranteed to change at least every time any of the primitives in ...
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
A lightweight class that represents a single element that may be timed and/or counted via stats...
Similar to MutexHolder, but for a light mutex.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
UpdateSeq get_modified(Thread *current_thread=Thread::get_current_thread()) const
Returns a sequence number which is guaranteed to change at least every time the vertex data is modifi...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
Similar to MutexHolder, but for a light reentrant mutex.
bool is_registered() const
Returns true if this munger has been registered, false if it has not.
bool munge_geom(CPT(Geom)&geom, CPT(GeomVertexData)&data, bool force, Thread *current_thread)
Applies the indicated munger to the geom and its data, and returns a (possibly different) geom and da...
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
A thread; that is, a lightweight process.
TypeHandle is the identifier used to differentiate C++ class types.
GraphicsStateGuardianBase * get_gsg() const
Returns a pointer to the GSG that created this munger.