From d1ab940e938f17e6ea7f9b5909906a5c03a78e2d Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 29 Jun 2020 11:30:07 +0200 Subject: [PATCH] pgraph: Fix texture replacement creating unique TextureAttrib This needs a more thorough fix (probably on master), but the implicit sort is incrementing every time, and it is being included in the hash/compare, so every time the same texture is replaced on the same TextureAttrib, it will be a unique TextureAttrib, causing garbage to accumulate and the state system to be generally less effective. --- panda/src/pgraph/textureAttrib.cxx | 38 ++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/panda/src/pgraph/textureAttrib.cxx b/panda/src/pgraph/textureAttrib.cxx index 0184f1825c..d08344fc4d 100644 --- a/panda/src/pgraph/textureAttrib.cxx +++ b/panda/src/pgraph/textureAttrib.cxx @@ -109,12 +109,18 @@ add_on_stage(TextureStage *stage, Texture *tex, int override) const { nassertr(tex != nullptr, this); TextureAttrib *attrib = new TextureAttrib(*this); - Stages::iterator si = attrib->_on_stages.insert(StageNode(stage)).first; - (*si)._override = override; - (*si)._texture = tex; - (*si)._implicit_sort = attrib->_next_implicit_sort; - (*si)._has_sampler = false; - ++(attrib->_next_implicit_sort); + auto result = attrib->_on_stages.insert(StageNode(stage)); + StageNode &sn = *result.first; + sn._override = override; + sn._texture = tex; + sn._has_sampler = false; + + // Only bump this if it doesn't already have the highest implicit sort. + // This prevents replacing a texture from creating a unique TextureAttrib. + if (result.second || sn._implicit_sort + 1 != attrib->_next_implicit_sort) { + sn._implicit_sort = attrib->_next_implicit_sort; + ++(attrib->_next_implicit_sort); + } return return_new(attrib); } @@ -128,13 +134,19 @@ add_on_stage(TextureStage *stage, Texture *tex, const SamplerState &sampler, int nassertr(tex != nullptr, this); TextureAttrib *attrib = new TextureAttrib(*this); - Stages::iterator si = attrib->_on_stages.insert(StageNode(stage)).first; - (*si)._override = override; - (*si)._texture = tex; - (*si)._sampler = sampler; - (*si)._implicit_sort = attrib->_next_implicit_sort; - (*si)._has_sampler = true; - ++(attrib->_next_implicit_sort); + auto result = attrib->_on_stages.insert(StageNode(stage)); + StageNode &sn = *result.first; + sn._override = override; + sn._texture = tex; + sn._sampler = sampler; + sn._has_sampler = true; + + // Only bump this if it doesn't already have the highest implicit sort. + // This prevents replacing a texture from creating a unique TextureAttrib. + if (result.second || sn._implicit_sort + 1 != attrib->_next_implicit_sort) { + sn._implicit_sort = attrib->_next_implicit_sort; + ++(attrib->_next_implicit_sort); + } return return_new(attrib); }