From 97cf47b0da3090fbb100c62c21dfb1eb5137e337 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 18 Apr 2005 22:36:55 +0000 Subject: [PATCH] oops, broke bam loading --- panda/src/gobj/qpgeom.cxx | 2 +- panda/src/gobj/qpgeomVertexArrayData.cxx | 26 ++++++ panda/src/gobj/qpgeomVertexArrayData.h | 2 + panda/src/gobj/qpgeomVertexData.I | 38 ++++++++ panda/src/gobj/qpgeomVertexData.cxx | 111 +++++++++++++++++++++++ panda/src/gobj/qpgeomVertexData.h | 23 +++++ 6 files changed, 201 insertions(+), 1 deletion(-) diff --git a/panda/src/gobj/qpgeom.cxx b/panda/src/gobj/qpgeom.cxx index 25815df40e..a5306f523e 100644 --- a/panda/src/gobj/qpgeom.cxx +++ b/panda/src/gobj/qpgeom.cxx @@ -991,7 +991,7 @@ fillin(DatagramIterator &scan, BamReader *manager) { } _primitive_type = (PrimitiveType)scan.get_uint8(); - _shade_model = (ShadeModel)scan.get_uint16(); + _shade_model = (ShadeModel)scan.get_uint8(); _geom_rendering = scan.get_uint16(); _got_usage_hint = false; _modified = qpGeom::get_next_modified(); diff --git a/panda/src/gobj/qpgeomVertexArrayData.cxx b/panda/src/gobj/qpgeomVertexArrayData.cxx index 5331ac222f..a537a03141 100644 --- a/panda/src/gobj/qpgeomVertexArrayData.cxx +++ b/panda/src/gobj/qpgeomVertexArrayData.cxx @@ -414,6 +414,31 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { return pi; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexArrayData::finalize +// Access: Public, Virtual +// Description: Called by the BamReader to perform any final actions +// needed for setting up the object after all objects +// have been read and all pointers have been completed. +//////////////////////////////////////////////////////////////////// +void qpGeomVertexArrayData:: +finalize(BamReader *manager) { + // Now we need to register the format that we have read from the bam + // file (since it doesn't come out of the bam file automatically + // registered). This may change the format's pointer, which we + // should then update our own data to reflect. But since this may + // cause the unregistered object to destruct, we have to also tell + // the BamReader to return the new object from now on. + + CDWriter cdata(_cycler); + + CPT(qpGeomVertexArrayFormat) new_array_format = + qpGeomVertexArrayFormat::register_format(_array_format); + + manager->change_pointer(_array_format, new_array_format); + _array_format = new_array_format; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexArrayData::make_from_bam // Access: Protected, Static @@ -430,6 +455,7 @@ make_from_bam(const FactoryParams ¶ms) { parse_params(params, scan, manager); object->fillin(scan, manager); + manager->register_finalize(object); return object; } diff --git a/panda/src/gobj/qpgeomVertexArrayData.h b/panda/src/gobj/qpgeomVertexArrayData.h index ac2ee2ca4f..15b50550f2 100644 --- a/panda/src/gobj/qpgeomVertexArrayData.h +++ b/panda/src/gobj/qpgeomVertexArrayData.h @@ -135,6 +135,8 @@ public: static PTA_uchar read_raw_data(DatagramIterator &source); virtual int complete_pointers(TypedWritable **plist, BamReader *manager); + virtual void finalize(BamReader *manager); + protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); void fillin(DatagramIterator &scan, BamReader *manager); diff --git a/panda/src/gobj/qpgeomVertexData.I b/panda/src/gobj/qpgeomVertexData.I index ccfaf724a8..0fdd3b999a 100644 --- a/panda/src/gobj/qpgeomVertexData.I +++ b/panda/src/gobj/qpgeomVertexData.I @@ -414,6 +414,44 @@ add_transform(TransformPalette *palette, const VertexTransform *transform, return (*(result.first)).second; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexData::CacheEntry::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexData::CacheEntry:: +CacheEntry(const qpGeomVertexFormat *modifier) : + _source(NULL), + _modifier(modifier), + _result(NULL) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexData::CacheEntry::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexData::CacheEntry:: +CacheEntry(qpGeomVertexData *source, + const qpGeomVertexFormat *modifier, + const qpGeomVertexData *result) : + _source(source), + _modifier(modifier), + _result(result) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexData::CacheEntry::operator < +// Access: Public +// Description: Provides a unique ordering within the set. +//////////////////////////////////////////////////////////////////// +INLINE bool qpGeomVertexData::CacheEntry:: +operator < (const CacheEntry &other) const { + return _modifier < other._modifier; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexData::CData::Constructor // Access: Public diff --git a/panda/src/gobj/qpgeomVertexData.cxx b/panda/src/gobj/qpgeomVertexData.cxx index 8478573f76..030cde6401 100644 --- a/panda/src/gobj/qpgeomVertexData.cxx +++ b/panda/src/gobj/qpgeomVertexData.cxx @@ -107,6 +107,7 @@ operator = (const qpGeomVertexData ©) { _cull_char_pcollector = copy._cull_char_pcollector; CDWriter cdata(_cycler); + clear_cache(); cdata->_modified = qpGeom::get_next_modified(); cdata->_animated_vertices_modified = UpdateSeq(); } @@ -118,6 +119,23 @@ operator = (const qpGeomVertexData ©) { //////////////////////////////////////////////////////////////////// qpGeomVertexData:: ~qpGeomVertexData() { + // When we destruct, we should ensure that all of our cached + // entries, across all pipeline stages, are properly removed from + // the cache manager. + int num_stages = _cycler.get_num_stages(); + for (int i = 0; i < num_stages; i++) { + if (_cycler.is_stage_unique(i)) { + CData *cdata = _cycler.write_stage(i); + for (Cache::iterator ci = cdata->_cache.begin(); + ci != cdata->_cache.end(); + ++ci) { + CacheEntry *entry = (*ci); + entry->erase(); + } + cdata->_cache.clear(); + _cycler.release_write_stage(i, cdata); + } + } } //////////////////////////////////////////////////////////////////// @@ -141,6 +159,7 @@ set_usage_hint(qpGeomVertexData::UsageHint usage_hint) { } (*ai)->set_usage_hint(usage_hint); } + clear_cache(); cdata->_modified = qpGeom::get_next_modified(); cdata->_animated_vertices_modified = UpdateSeq(); } @@ -187,6 +206,7 @@ clear_rows() { } (*ai)->clear_rows(); } + clear_cache(); cdata->_modified = qpGeom::get_next_modified(); cdata->_animated_vertices.clear(); } @@ -212,6 +232,7 @@ modify_array(int i) { if (cdata->_arrays[i]->get_ref_count() > 1) { cdata->_arrays[i] = new qpGeomVertexArrayData(*cdata->_arrays[i]); } + clear_cache(); cdata->_modified = qpGeom::get_next_modified(); cdata->_animated_vertices_modified = UpdateSeq(); @@ -231,6 +252,7 @@ set_array(int i, const qpGeomVertexArrayData *array) { CDWriter cdata(_cycler); nassertv(i >= 0 && i < (int)cdata->_arrays.size()); cdata->_arrays[i] = (qpGeomVertexArrayData *)array; + clear_cache(); cdata->_modified = qpGeom::get_next_modified(); cdata->_animated_vertices_modified = UpdateSeq(); } @@ -250,6 +272,7 @@ set_transform_palette(const TransformPalette *palette) { CDWriter cdata(_cycler); cdata->_transform_palette = (TransformPalette *)palette; + clear_cache(); cdata->_modified = qpGeom::get_next_modified(); cdata->_animated_vertices_modified = UpdateSeq(); } @@ -272,6 +295,7 @@ modify_transform_blend_palette() { if (cdata->_transform_blend_palette->get_ref_count() > 1) { cdata->_transform_blend_palette = new TransformBlendPalette(*cdata->_transform_blend_palette); } + clear_cache(); cdata->_modified = qpGeom::get_next_modified(); cdata->_animated_vertices_modified = UpdateSeq(); @@ -291,6 +315,7 @@ void qpGeomVertexData:: set_transform_blend_palette(const TransformBlendPalette *palette) { CDWriter cdata(_cycler); cdata->_transform_blend_palette = (TransformBlendPalette *)palette; + clear_cache(); cdata->_modified = qpGeom::get_next_modified(); cdata->_animated_vertices_modified = UpdateSeq(); } @@ -312,6 +337,7 @@ set_slider_table(const SliderTable *table) { CDWriter cdata(_cycler); cdata->_slider_table = (SliderTable *)table; + clear_cache(); cdata->_modified = qpGeom::get_next_modified(); cdata->_animated_vertices_modified = UpdateSeq(); } @@ -550,6 +576,22 @@ convert_to(const qpGeomVertexFormat *new_format) const { return this; } + // Look up the new format in our cache--maybe we've recently applied + // it. + { + CDReader cdata(_cycler); + CacheEntry temp_entry(new_format); + temp_entry.local_object(); + Cache::const_iterator ci = cdata->_cache.find(&temp_entry); + if (ci != cdata->_cache.end()) { + CacheEntry *entry = (*ci); + // Record a cache hit, so this element will stay in the cache a + // while longer. + entry->refresh(); + return entry->_result; + } + } + // Okay, convert the data to the new format. if (gobj_cat.is_debug()) { gobj_cat.debug() @@ -564,6 +606,23 @@ convert_to(const qpGeomVertexFormat *new_format) const { new_data->set_slider_table(get_slider_table()); new_data->copy_from(*this, false); + + { + // Record the new result in the cache. + CacheEntry *entry; + { + CDWriter cdata(((qpGeomVertexData *)this)->_cycler); + entry = new CacheEntry((qpGeomVertexData *)this, new_format, new_data); + bool inserted = cdata->_cache.insert(entry).second; + nassertr(inserted, new_data); + } + + // And tell the cache manager about the new entry. (It might + // immediately request a delete from the cache of the thing we + // just added.) + entry->record(); + } + return new_data; } @@ -834,6 +893,26 @@ write(ostream &out, int indent_level) const { } } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexData::clear_cache +// Access: Published +// Description: Removes all of the previously-cached results of +// convert_to(). +//////////////////////////////////////////////////////////////////// +void qpGeomVertexData:: +clear_cache() { + // Probably we shouldn't do anything at all here unless we are + // running in pipeline stage 0. + CData *cdata = CDWriter(_cycler); + for (Cache::iterator ci = cdata->_cache.begin(); + ci != cdata->_cache.end(); + ++ci) { + CacheEntry *entry = (*ci); + entry->erase(); + } + cdata->_cache.clear(); +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexData::get_array_info // Access: Public @@ -1147,6 +1226,7 @@ do_set_num_rows(int n, qpGeomVertexData::CDWriter &cdata) { } if (any_changed) { + clear_cache(); cdata->_modified = qpGeom::get_next_modified(); cdata->_animated_vertices.clear(); } @@ -1457,6 +1537,37 @@ fillin(DatagramIterator &scan, BamReader *manager) { manager->read_cdata(scan, _cycler); } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexData::CacheEntry::evict_callback +// Access: Public, Virtual +// Description: Called when the entry is evicted from the cache, this +// should clean up the owning object appropriately. +//////////////////////////////////////////////////////////////////// +void qpGeomVertexData::CacheEntry:: +evict_callback() { + // We have to operate on stage 0 of the pipeline, since that's where + // the cache really counts. Because of the multistage pipeline, we + // might not actually have a cache entry there (it might have been + // added to stage 1 instead). No big deal if we don't. + CData *cdata = _source->_cycler.write_stage(0); + Cache::iterator ci = cdata->_cache.find(this); + if (ci != cdata->_cache.end()) { + cdata->_cache.erase(ci); + } + _source->_cycler.release_write_stage(0, cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexData::CacheEntry::output +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomVertexData::CacheEntry:: +output(ostream &out) const { + out << "vertex data " << (void *)_source << " to " + << *_modifier; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexData::CData::make_copy // Access: Public, Virtual diff --git a/panda/src/gobj/qpgeomVertexData.h b/panda/src/gobj/qpgeomVertexData.h index dd7a081478..4a5fdb1739 100644 --- a/panda/src/gobj/qpgeomVertexData.h +++ b/panda/src/gobj/qpgeomVertexData.h @@ -25,6 +25,7 @@ #include "qpgeomVertexColumn.h" #include "qpgeomVertexArrayData.h" #include "qpgeomEnums.h" +#include "qpgeomCacheEntry.h" #include "transformPalette.h" #include "transformBlendPalette.h" #include "sliderTable.h" @@ -140,6 +141,8 @@ PUBLISHED: void output(ostream &out) const; void write(ostream &out, int indent_level = 0) const; + void clear_cache(); + public: INLINE CPT(qpGeomVertexData) animate_vertices_cull() const; @@ -198,6 +201,23 @@ private: typedef pvector< PT(qpGeomVertexArrayData) > Arrays; + class CacheEntry : public qpGeomCacheEntry { + public: + INLINE CacheEntry(const qpGeomVertexFormat *modifier); + INLINE CacheEntry(qpGeomVertexData *source, + const qpGeomVertexFormat *modifier, + const qpGeomVertexData *result); + INLINE bool operator < (const CacheEntry &other) const; + + virtual void evict_callback(); + virtual void output(ostream &out) const; + + qpGeomVertexData *_source; + CPT(qpGeomVertexFormat) _modifier; + CPT(qpGeomVertexData) _result; + }; + typedef pset > Cache; + // This is the data that must be cycled between pipeline stages. class EXPCL_PANDA CData : public CycleData { public: @@ -216,6 +236,7 @@ private: PT(qpGeomVertexData) _animated_vertices; UpdateSeq _animated_vertices_modified; UpdateSeq _modified; + Cache _cache; }; PipelineCycler _cycler; @@ -263,6 +284,8 @@ public: private: static TypeHandle _type_handle; + + friend class CacheEntry; }; INLINE ostream &operator << (ostream &out, const qpGeomVertexData &obj);