瀏覽代碼

oops, broke bam loading

David Rose 20 年之前
父節點
當前提交
97cf47b0da

+ 1 - 1
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();

+ 26 - 0
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 &params) {
 
   parse_params(params, scan, manager);
   object->fillin(scan, manager);
+  manager->register_finalize(object);
 
   return object;
 }

+ 2 - 0
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 &params);
   void fillin(DatagramIterator &scan, BamReader *manager);

+ 38 - 0
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

+ 111 - 0
panda/src/gobj/qpgeomVertexData.cxx

@@ -107,6 +107,7 @@ operator = (const qpGeomVertexData &copy) {
   _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 &copy) {
 ////////////////////////////////////////////////////////////////////
 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

+ 23 - 0
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<PT(CacheEntry), IndirectLess<CacheEntry> > 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<CData> _cycler;
@@ -263,6 +284,8 @@ public:
 
 private:
   static TypeHandle _type_handle;
+
+  friend class CacheEntry;
 };
 
 INLINE ostream &operator << (ostream &out, const qpGeomVertexData &obj);