From 24dea4e56aec68a8f6449285cd6d812d8785f1a4 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 8 Oct 2008 01:12:17 +0000 Subject: [PATCH] more fixes to RenderAttrib problem --- panda/src/pgraph/renderAttrib.cxx | 3 ++- panda/src/pgraph/textureAttrib.I | 5 ++++- panda/src/pgraph/textureAttrib.cxx | 32 +++++++++++++++++++++--------- panda/src/pgraph/textureAttrib.h | 1 + 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/panda/src/pgraph/renderAttrib.cxx b/panda/src/pgraph/renderAttrib.cxx index 2148633bb2..7227957df8 100644 --- a/panda/src/pgraph/renderAttrib.cxx +++ b/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; diff --git a/panda/src/pgraph/textureAttrib.I b/panda/src/pgraph/textureAttrib.I index 6b0c7937dc..8e3e997f0d 100644 --- a/panda/src/pgraph/textureAttrib.I +++ b/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 ©) : _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()) { } diff --git a/panda/src/pgraph/textureAttrib.cxx b/panda/src/pgraph/textureAttrib.cxx index 10fa07ff3f..bc945bd65d 100644 --- a/panda/src/pgraph/textureAttrib.cxx +++ b/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(); } diff --git a/panda/src/pgraph/textureAttrib.h b/panda/src/pgraph/textureAttrib.h index 068a16fa7a..68a048ec82 100644 --- a/panda/src/pgraph/textureAttrib.h +++ b/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;