Browse Source

more fixes to RenderAttrib problem

David Rose 17 years ago
parent
commit
24dea4e56a

+ 2 - 1
panda/src/pgraph/renderAttrib.cxx

@@ -301,6 +301,7 @@ return_new(RenderAttrib *attrib) {
     // The attribute was inserted; save the iterator and return the
     // input attribute.
     attrib->_saved_entry = result.first;
+
     return pt_attrib;
   }
 
@@ -444,7 +445,7 @@ release_new() {
         while (si != _attribs->end()) {
           const RenderAttrib *attrib = (*si);
           cerr << "    " << *attrib << " (" << (void *)attrib << ")\n";
-          if (((*sprev)->compare_to(*attrib)) > 0) {
+          if (((*sprev)->compare_to(*attrib)) >= 0) {
             cerr << "*** above out of order!\n";
           }
           sprev = si;

+ 4 - 1
panda/src/pgraph/textureAttrib.I

@@ -24,6 +24,7 @@ TextureAttrib() {
   _next_implicit_sort = 0;
   _off_all_stages = false;
   _sort_seq = UpdateSeq::old();
+  _filtered_seq = UpdateSeq::old();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -36,13 +37,15 @@ TextureAttrib() {
 INLINE TextureAttrib::
 TextureAttrib(const TextureAttrib &copy) :
   _on_stages(copy._on_stages),
+  _on_ptr_stages(copy._on_ptr_stages),
   _on_ff_stages(copy._on_ff_stages),
   _ff_tc_index(copy._ff_tc_index),
   _next_implicit_sort(copy._next_implicit_sort),
   _off_stages(copy._off_stages),
   _off_all_stages(copy._off_all_stages),
   _on_textures(copy._on_textures),
-  _sort_seq(copy._sort_seq)
+  _sort_seq(copy._sort_seq),
+  _filtered_seq(UpdateSeq::old())
 {
 }
 

+ 23 - 9
panda/src/pgraph/textureAttrib.cxx

@@ -145,6 +145,7 @@ add_on_stage(TextureStage *stage, Texture *tex) const {
 
   // In either case, we now need to re-sort the attrib list.
   attrib->_sort_seq = UpdateSeq::old();
+  attrib->_filtered_seq = UpdateSeq::old();
 
   return return_new(attrib);
 }
@@ -173,6 +174,7 @@ remove_on_stage(TextureStage *stage) const {
     }
 
     attrib->_sort_seq = UpdateSeq::old();
+    attrib->_filtered_seq = UpdateSeq::old();
   }
 
   return return_new(attrib);
@@ -204,6 +206,7 @@ add_off_stage(TextureStage *stage) const {
         }
       }
       attrib->_sort_seq = UpdateSeq::old();
+      attrib->_filtered_seq = UpdateSeq::old();
     }
   }
   return return_new(attrib);
@@ -297,9 +300,10 @@ filter_to_max(int max_texture_stages) const {
     return this;
   }
 
-  // Since check_sorted() will clear the _filtered list if we are out
-  // of date, we should call it first.
-  check_sorted();
+  if (_filtered_seq != TextureStage::get_sort_seq()) {
+    ((TextureAttrib *)this)->_filtered.clear();
+    ((TextureAttrib *)this)->_filtered_seq = TextureStage::get_sort_seq();
+  }
 
   Filtered::const_iterator fi;
   fi = _filtered.find(max_texture_stages);
@@ -312,6 +316,8 @@ filter_to_max(int max_texture_stages) const {
   // Harder case: we have to compute it now.  We must choose the n
   // stages with the highest priority in our list of stages.  In the
   // case of equal priority, we prefer the stage with the lower sort.
+  check_sorted();
+
   OnStages priority_stages = _on_stages;
 
   // This sort function uses the STL function object defined above.
@@ -481,6 +487,7 @@ compare_to_impl(const RenderAttrib *other) const {
 
     Texture *tex = (*li).second;
     Texture *other_tex = (*oli).second;
+
     if (tex != other_tex) {
       return tex < other_tex ? -1 : 1;
     }
@@ -504,6 +511,9 @@ compare_to_impl(const RenderAttrib *other) const {
   check_sorted();
   ta->check_sorted();
 
+  nassertr(_on_ptr_stages.size() == _on_stages.size() &&
+           ta->_on_ptr_stages.size() == ta->_on_stages.size(), 0)
+
   OnStages::const_iterator si = _on_ptr_stages.begin();
   OnStages::const_iterator osi = ta->_on_ptr_stages.begin();
 
@@ -517,6 +527,7 @@ compare_to_impl(const RenderAttrib *other) const {
 
     int implicit_sort = (*si)._implicit_sort;
     int other_implicit_sort = (*osi)._implicit_sort;
+
     if (implicit_sort != other_implicit_sort) {
       return implicit_sort < other_implicit_sort ? -1 : 1;
     }
@@ -855,6 +866,7 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
     }
   }
   _sort_seq = UpdateSeq::old();
+  _filtered_seq = UpdateSeq::old();
 
   return pi;
 }
@@ -970,8 +982,6 @@ sort_on_stages() {
   // Now we can sort the on_stages list into render order.
   sort(_on_stages.begin(), _on_stages.end(), CompareTextureStageSort());
 
-  _sort_seq = TextureStage::get_sort_seq();
-
   _on_ff_stages.clear();
   _ff_tc_index.clear();
 
@@ -983,8 +993,12 @@ sort_on_stages() {
       _ff_tc_index.push_back(texcoord_index);
     }
   }
-  
-  // Also clear the _filtered map, so we'll have to recompute those
-  // (in case the priority orders have changed as well).
-  _filtered.clear();
+
+  // We'd like to clear the _filtered map, in case the priority orders
+  // have changed as well, but we can't do that here: too dangerous.
+  // Clearing _filtered might cause TextureAttribs to be deleted, and
+  // hence removed from the map that we might be in the middle of
+  // traversing!
+
+  _sort_seq = TextureStage::get_sort_seq();
 }

+ 1 - 0
panda/src/pgraph/textureAttrib.h

@@ -135,6 +135,7 @@ private:
   Filtered _filtered;
 
   UpdateSeq _sort_seq;
+  UpdateSeq _filtered_seq;
 
   static CPT(RenderAttrib) _empty_attrib;
   static CPT(RenderAttrib) _all_off_attrib;