From 6cfabe252d3789f72377f07431b704f71df9c6c9 Mon Sep 17 00:00:00 2001 From: elsid Date: Thu, 2 Sep 2021 01:18:55 +0200 Subject: [PATCH 1/4] Remove redundant ShadowsBinAdder --- components/sceneutil/mwshadowtechnique.cpp | 2 +- components/sceneutil/shadowsbin.hpp | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index 024123b3e1..60f048b147 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -282,7 +282,7 @@ void VDSMCameraCullCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) static osg::ref_ptr ss; if (!ss) { - ShadowsBinAdder adder("ShadowsBin", _vdsm->getCastingPrograms()); + ShadowsBin::addPrototype("ShadowsBin", _vdsm->getCastingPrograms()); ss = new osg::StateSet; ss->setRenderBinDetails(osg::StateSet::OPAQUE_BIN, "ShadowsBin", osg::StateSet::OVERRIDE_PROTECTED_RENDERBIN_DETAILS); } diff --git a/components/sceneutil/shadowsbin.hpp b/components/sceneutil/shadowsbin.hpp index 1c63caf4bb..8775dc3139 100644 --- a/components/sceneutil/shadowsbin.hpp +++ b/components/sceneutil/shadowsbin.hpp @@ -67,13 +67,6 @@ namespace SceneUtil static void addPrototype(const std::string& name, const std::array, GL_ALWAYS - GL_NEVER + 1>& castingPrograms); }; - - class ShadowsBinAdder - { - public: - ShadowsBinAdder(const std::string& name, const std::array, GL_ALWAYS - GL_NEVER + 1>& castingPrograms){ ShadowsBin::addPrototype(name, castingPrograms); } - }; - } #endif From 9d1b7c4a303bf5d6ba29f16cfdb15f761dddcbe7 Mon Sep 17 00:00:00 2001 From: elsid Date: Thu, 2 Sep 2021 01:12:47 +0200 Subject: [PATCH 2/4] Use type alias to avoid long type names and length redefinition for array --- components/sceneutil/shadowsbin.cpp | 4 ++-- components/sceneutil/shadowsbin.hpp | 23 ++++++++++++++--------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/components/sceneutil/shadowsbin.cpp b/components/sceneutil/shadowsbin.cpp index af62b581c9..a6275a60e2 100644 --- a/components/sceneutil/shadowsbin.cpp +++ b/components/sceneutil/shadowsbin.cpp @@ -42,7 +42,7 @@ namespace namespace SceneUtil { -std::array, GL_ALWAYS - GL_NEVER + 1> ShadowsBin::sCastingPrograms = { +ShadowsBin::CastingPrograms ShadowsBin::sCastingPrograms = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; @@ -150,7 +150,7 @@ StateGraph* ShadowsBin::cullStateGraph(StateGraph* sg, StateGraph* root, std::un return sg; } -void ShadowsBin::addPrototype(const std::string & name, const std::array, GL_ALWAYS - GL_NEVER + 1>& castingPrograms) +void ShadowsBin::addPrototype(const std::string & name, const CastingPrograms& castingPrograms) { sCastingPrograms = castingPrograms; osg::ref_ptr bin(new ShadowsBin); diff --git a/components/sceneutil/shadowsbin.hpp b/components/sceneutil/shadowsbin.hpp index 8775dc3139..67343c67f5 100644 --- a/components/sceneutil/shadowsbin.hpp +++ b/components/sceneutil/shadowsbin.hpp @@ -12,18 +12,15 @@ namespace osg namespace SceneUtil { - /// renderbin which culls redundant state for shadow map rendering class ShadowsBin : public osgUtil::RenderBin { - private: - static std::array, GL_ALWAYS - GL_NEVER + 1> sCastingPrograms; - - osg::ref_ptr mNoTestStateSet; - osg::ref_ptr mShaderAlphaTestStateSet; - - std::array, GL_ALWAYS - GL_NEVER + 1> mAlphaFuncShaders; public: + template + using Array = std::array; + + using CastingPrograms = Array>; + META_Object(SceneUtil, ShadowsBin) ShadowsBin(); ShadowsBin(const ShadowsBin& rhs, const osg::CopyOp& copyop) @@ -65,7 +62,15 @@ namespace SceneUtil osgUtil::StateGraph* cullStateGraph(osgUtil::StateGraph* sg, osgUtil::StateGraph* root, std::unordered_set& uninteresting, bool cullFaceOverridden); - static void addPrototype(const std::string& name, const std::array, GL_ALWAYS - GL_NEVER + 1>& castingPrograms); + static void addPrototype(const std::string& name, const CastingPrograms& castingPrograms); + + private: + static CastingPrograms sCastingPrograms; + + osg::ref_ptr mNoTestStateSet; + osg::ref_ptr mShaderAlphaTestStateSet; + + Array> mAlphaFuncShaders; }; } From 590a340e6e436ae25abeca773ca5ac1895bdfe0e Mon Sep 17 00:00:00 2001 From: elsid Date: Thu, 2 Sep 2021 21:31:11 +0200 Subject: [PATCH 3/4] Remove redundant ShadowsBin::sCastingPrograms This variable is only used in ShadowsBin constructor and it's initialized each time before constructor call so required value can be just passed into ShadowsBin ctor. Make ShadowsBin default constructor private because it is required by osg even it's not actually called. --- components/sceneutil/shadowsbin.cpp | 13 ++++--------- components/sceneutil/shadowsbin.hpp | 4 ++-- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/components/sceneutil/shadowsbin.cpp b/components/sceneutil/shadowsbin.cpp index a6275a60e2..21f25dc4ad 100644 --- a/components/sceneutil/shadowsbin.cpp +++ b/components/sceneutil/shadowsbin.cpp @@ -42,11 +42,7 @@ namespace namespace SceneUtil { -ShadowsBin::CastingPrograms ShadowsBin::sCastingPrograms = { - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr -}; - -ShadowsBin::ShadowsBin() +ShadowsBin::ShadowsBin(const CastingPrograms& castingPrograms) { mNoTestStateSet = new osg::StateSet; mNoTestStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", false)); @@ -57,10 +53,10 @@ ShadowsBin::ShadowsBin() mShaderAlphaTestStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", true)); mShaderAlphaTestStateSet->setMode(GL_BLEND, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED | osg::StateAttribute::OVERRIDE); - for (size_t i = 0; i < sCastingPrograms.size(); ++i) + for (size_t i = 0; i < castingPrograms.size(); ++i) { mAlphaFuncShaders[i] = new osg::StateSet; - mAlphaFuncShaders[i]->setAttribute(sCastingPrograms[i], osg::StateAttribute::ON | osg::StateAttribute::PROTECTED | osg::StateAttribute::OVERRIDE); + mAlphaFuncShaders[i]->setAttribute(castingPrograms[i], osg::StateAttribute::ON | osg::StateAttribute::PROTECTED | osg::StateAttribute::OVERRIDE); } } @@ -152,8 +148,7 @@ StateGraph* ShadowsBin::cullStateGraph(StateGraph* sg, StateGraph* root, std::un void ShadowsBin::addPrototype(const std::string & name, const CastingPrograms& castingPrograms) { - sCastingPrograms = castingPrograms; - osg::ref_ptr bin(new ShadowsBin); + osg::ref_ptr bin(new ShadowsBin(castingPrograms)); osgUtil::RenderBin::addRenderBinPrototype(name, bin); } diff --git a/components/sceneutil/shadowsbin.hpp b/components/sceneutil/shadowsbin.hpp index 67343c67f5..4b0d8cc544 100644 --- a/components/sceneutil/shadowsbin.hpp +++ b/components/sceneutil/shadowsbin.hpp @@ -22,7 +22,7 @@ namespace SceneUtil using CastingPrograms = Array>; META_Object(SceneUtil, ShadowsBin) - ShadowsBin(); + ShadowsBin(const CastingPrograms& castingPrograms); ShadowsBin(const ShadowsBin& rhs, const osg::CopyOp& copyop) : osgUtil::RenderBin(rhs, copyop) , mNoTestStateSet(rhs.mNoTestStateSet) @@ -65,7 +65,7 @@ namespace SceneUtil static void addPrototype(const std::string& name, const CastingPrograms& castingPrograms); private: - static CastingPrograms sCastingPrograms; + ShadowsBin() {} osg::ref_ptr mNoTestStateSet; osg::ref_ptr mShaderAlphaTestStateSet; From 562590720b4ebc1a758091b36d2be5d94c8edbb3 Mon Sep 17 00:00:00 2001 From: elsid Date: Thu, 2 Sep 2021 22:01:20 +0200 Subject: [PATCH 4/4] Remove ShadowsBin prototype on MWShadowTechnique destruction To prevent crash: ==7733==ERROR: AddressSanitizer: heap-use-after-free on address 0x6040000ca1b0 at pc 0x55fcfa8d1ee3 bp 0x7ffd1c464e00 sp 0x7ffd1c464df0 READ of size 4 at 0x6040000ca1b0 thread T0 #0 0x55fcfa8d1ee2 in std::less::operator()(unsigned int const&, unsigned int const&) const /usr/include/c++/11.1.0/bits/stl_function.h:386 #1 0x55fcfa8d1ee2 in std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_lower_bound(std::_Rb_tree_node > >*, std::_Rb_tree_node_base*, unsigned int const&) /usr/include/c++/11.1.0/bits/stl_tree.h:1903 #2 0x55fcfa8ca76e in std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::lower_bound(unsigned int const&) /usr/include/c++/11.1.0/bits/stl_tree.h:1270 #3 0x55fcfa8ca76e in std::map, std::less, std::allocator > > >::lower_bound(unsigned int const&) /usr/include/c++/11.1.0/bits/stl_map.h:1259 #4 0x55fcfa8ca76e in std::map, std::less, std::allocator > > >::operator[](unsigned int const&) /usr/include/c++/11.1.0/bits/stl_map.h:497 #5 0x55fcfa8ca76e in osg::getOrCreateContextData(unsigned int) /home/elsid/dev/OpenSceneGraph/src/osg/ContextData.cpp:142 #6 0x55fcfab6848a in GLShaderManager* osg::get(unsigned int) /home/elsid/dev/OpenSceneGraph/include/osg/ContextData:154 #7 0x55fcfab6848a in osg::Shader::PerContextShader::~PerContextShader() /home/elsid/dev/OpenSceneGraph/src/osg/Shader.cpp:540 #8 0x55fcfab68dc6 in osg::Shader::PerContextShader::~PerContextShader() /home/elsid/dev/OpenSceneGraph/src/osg/Shader.cpp:541 #9 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292 #10 0x55fcfab6d0ce in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/include/osg/Referenced:201 #11 0x55fcfab6d0ce in osg::ref_ptr::~ref_ptr() /home/elsid/dev/OpenSceneGraph/include/osg/ref_ptr:44 #12 0x55fcfab6d0ce in void std::_Destroy >(osg::ref_ptr*) /usr/include/c++/11.1.0/bits/stl_construct.h:140 #13 0x55fcfab6d0ce in void std::_Destroy_aux::__destroy*>(osg::ref_ptr*, osg::ref_ptr*) /usr/include/c++/11.1.0/bits/stl_construct.h:152 #14 0x55fcfab6d0ce in void std::_Destroy*>(osg::ref_ptr*, osg::ref_ptr*) /usr/include/c++/11.1.0/bits/stl_construct.h:185 #15 0x55fcfab6d0ce in void std::_Destroy*, osg::ref_ptr >(osg::ref_ptr*, osg::ref_ptr*, std::allocator >&) /usr/include/c++/11.1.0/bits/alloc_traits.h:746 #16 0x55fcfab6d0ce in std::vector, std::allocator > >::~vector() /usr/include/c++/11.1.0/bits/stl_vector.h:680 #17 0x55fcfab6d0ce in osg::Shader::ShaderObjects::~ShaderObjects() /home/elsid/dev/OpenSceneGraph/include/osg/Shader:264 #18 0x55fcfab6d0ce in osg::Shader::ShaderObjects::~ShaderObjects() /home/elsid/dev/OpenSceneGraph/include/osg/Shader:264 #19 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292 #20 0x55fcfab6c532 in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/include/osg/Referenced:201 #21 0x55fcfab6c532 in osg::ref_ptr::~ref_ptr() /home/elsid/dev/OpenSceneGraph/include/osg/ref_ptr:44 #22 0x55fcfab6c532 in void std::_Destroy >(osg::ref_ptr*) /usr/include/c++/11.1.0/bits/stl_construct.h:140 #23 0x55fcfab6c532 in void std::_Destroy_aux::__destroy*>(osg::ref_ptr*, osg::ref_ptr*) /usr/include/c++/11.1.0/bits/stl_construct.h:152 #24 0x55fcfab6c532 in void std::_Destroy*>(osg::ref_ptr*, osg::ref_ptr*) /usr/include/c++/11.1.0/bits/stl_construct.h:185 #25 0x55fcfab6c532 in void std::_Destroy*, osg::ref_ptr >(osg::ref_ptr*, osg::ref_ptr*, std::allocator >&) /usr/include/c++/11.1.0/bits/alloc_traits.h:746 #26 0x55fcfab6c532 in std::vector, std::allocator > >::~vector() /usr/include/c++/11.1.0/bits/stl_vector.h:680 #27 0x55fcfab6c532 in osg::buffered_value >::~buffered_value() /home/elsid/dev/OpenSceneGraph/include/osg/buffered_value:26 #28 0x55fcfab6c532 in osg::Shader::~Shader() /home/elsid/dev/OpenSceneGraph/src/osg/Shader.cpp:271 #29 0x55fcfab6c80a in osg::Shader::~Shader() /home/elsid/dev/OpenSceneGraph/src/osg/Shader.cpp:271 #30 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292 #31 0x55fcfab185bd in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/include/osg/Referenced:201 #32 0x55fcfab185bd in osg::ref_ptr::~ref_ptr() /home/elsid/dev/OpenSceneGraph/include/osg/ref_ptr:44 #33 0x55fcfab185bd in void std::_Destroy >(osg::ref_ptr*) /usr/include/c++/11.1.0/bits/stl_construct.h:140 #34 0x55fcfab185bd in void std::_Destroy_aux::__destroy*>(osg::ref_ptr*, osg::ref_ptr*) /usr/include/c++/11.1.0/bits/stl_construct.h:152 #35 0x55fcfab185bd in void std::_Destroy*>(osg::ref_ptr*, osg::ref_ptr*) /usr/include/c++/11.1.0/bits/stl_construct.h:185 #36 0x55fcfab185bd in void std::_Destroy*, osg::ref_ptr >(osg::ref_ptr*, osg::ref_ptr*, std::allocator >&) /usr/include/c++/11.1.0/bits/alloc_traits.h:746 #37 0x55fcfab185bd in std::vector, std::allocator > >::~vector() /usr/include/c++/11.1.0/bits/stl_vector.h:680 #38 0x55fcfab185bd in osg::Program::~Program() /home/elsid/dev/OpenSceneGraph/src/osg/Program.cpp:147 #39 0x55fcfab18ae0 in osg::Program::~Program() /home/elsid/dev/OpenSceneGraph/src/osg/Program.cpp:147 #40 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292 #41 0x55fcf8582cfa in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/build/gcc/asan/install/include/osg/Referenced:201 #42 0x55fcf8582cfa in osg::ref_ptr::~ref_ptr() /home/elsid/dev/OpenSceneGraph/build/gcc/asan/install/include/osg/ref_ptr:44 #43 0x55fcf8582cfa in std::pair, unsigned int>::~pair() /usr/include/c++/11.1.0/bits/stl_pair.h:211 #44 0x55fcf8582cfa in std::pair const, std::pair, unsigned int> >::~pair() /usr/include/c++/11.1.0/bits/stl_pair.h:211 #45 0x55fcf8582cfa in void __gnu_cxx::new_allocator const, std::pair, unsigned int> > > >::destroy const, std::pair, unsigned int> > >(std::pair const, std::pair, unsigned int> >*) /usr/include/c++/11.1.0/ext/new_allocator.h:162 #46 0x55fcf8582cfa in void std::allocator_traits const, std::pair, unsigned int> > > > >::destroy const, std::pair, unsigned int> > >(std::allocator const, std::pair, unsigned int> > > >&, std::pair const, std::pair, unsigned int> >*) /usr/include/c++/11.1.0/bits/alloc_traits.h:531 #47 0x55fcf8582cfa in std::_Rb_tree, std::pair const, std::pair, unsigned int> >, std::_Select1st const, std::pair, unsigned int> > >, std::less >, std::allocator const, std::pair, unsigned int> > > >::_M_destroy_node(std::_Rb_tree_node const, std::pair, unsigned int> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:623 #48 0x55fcf8582cfa in std::_Rb_tree, std::pair const, std::pair, unsigned int> >, std::_Select1st const, std::pair, unsigned int> > >, std::less >, std::allocator const, std::pair, unsigned int> > > >::_M_drop_node(std::_Rb_tree_node const, std::pair, unsigned int> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:631 #49 0x55fcf8582cfa in std::_Rb_tree, std::pair const, std::pair, unsigned int> >, std::_Select1st const, std::pair, unsigned int> > >, std::less >, std::allocator const, std::pair, unsigned int> > > >::_M_erase(std::_Rb_tree_node const, std::pair, unsigned int> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:1889 #50 0x55fcfac1f281 in std::_Rb_tree, std::pair const, std::pair, unsigned int> >, std::_Select1st const, std::pair, unsigned int> > >, std::less >, std::allocator const, std::pair, unsigned int> > > >::clear() /usr/include/c++/11.1.0/bits/stl_tree.h:1254 #51 0x55fcfac1f281 in std::map, std::pair, unsigned int>, std::less >, std::allocator const, std::pair, unsigned int> > > >::clear() /usr/include/c++/11.1.0/bits/stl_map.h:1134 #52 0x55fcfac1f281 in osg::StateSet::clear() /home/elsid/dev/OpenSceneGraph/src/osg/StateSet.cpp:738 #53 0x55fcfac2079e in osg::StateSet::~StateSet() /home/elsid/dev/OpenSceneGraph/src/osg/StateSet.cpp:285 #54 0x55fcfac20d3e in osg::StateSet::~StateSet() /home/elsid/dev/OpenSceneGraph/src/osg/StateSet.cpp:286 #55 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292 #56 0x55fcfb20dcac in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/build/gcc/asan/install/include/osg/Referenced:201 #57 0x55fcfb20dcac in osg::ref_ptr::~ref_ptr() /home/elsid/dev/OpenSceneGraph/build/gcc/asan/install/include/osg/ref_ptr:44 #58 0x55fcfb20dcac in std::array, 8ul>::~array() /usr/include/c++/11.1.0/array:95 #59 0x55fcfb20dcac in SceneUtil::ShadowsBin::~ShadowsBin() /home/elsid/dev/openmw/components/sceneutil/shadowsbin.hpp:16 #60 0x55fcfb20dcac in SceneUtil::ShadowsBin::~ShadowsBin() /home/elsid/dev/openmw/components/sceneutil/shadowsbin.hpp:16 #61 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292 #62 0x55fcfa6cc17f in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/include/osg/Referenced:201 #63 0x55fcfa6cc17f in osg::ref_ptr::~ref_ptr() /home/elsid/dev/OpenSceneGraph/include/osg/ref_ptr:44 #64 0x55fcfa6cc17f in std::pair, std::allocator > const, osg::ref_ptr >::~pair() /usr/include/c++/11.1.0/bits/stl_pair.h:211 #65 0x55fcfa6cc17f in void __gnu_cxx::new_allocator, std::allocator > const, osg::ref_ptr > > >::destroy, std::allocator > const, osg::ref_ptr > >(std::pair, std::allocator > const, osg::ref_ptr >*) /usr/include/c++/11.1.0/ext/new_allocator.h:162 #66 0x55fcfa6cc17f in void std::allocator_traits, std::allocator > const, osg::ref_ptr > > > >::destroy, std::allocator > const, osg::ref_ptr > >(std::allocator, std::allocator > const, osg::ref_ptr > > >&, std::pair, std::allocator > const, osg::ref_ptr >*) /usr/include/c++/11.1.0/bits/alloc_traits.h:531 #67 0x55fcfa6cc17f in std::_Rb_tree, std::allocator >, std::pair, std::allocator > const, osg::ref_ptr >, std::_Select1st, std::allocator > const, osg::ref_ptr > >, std::less, std::allocator > >, std::allocator, std::allocator > const, osg::ref_ptr > > >::_M_destroy_node(std::_Rb_tree_node, std::allocator > const, osg::ref_ptr > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:623 #68 0x55fcfa6cc17f in std::_Rb_tree, std::allocator >, std::pair, std::allocator > const, osg::ref_ptr >, std::_Select1st, std::allocator > const, osg::ref_ptr > >, std::less, std::allocator > >, std::allocator, std::allocator > const, osg::ref_ptr > > >::_M_drop_node(std::_Rb_tree_node, std::allocator > const, osg::ref_ptr > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:631 #69 0x55fcfa6cc17f in std::_Rb_tree, std::allocator >, std::pair, std::allocator > const, osg::ref_ptr >, std::_Select1st, std::allocator > const, osg::ref_ptr > >, std::less, std::allocator > >, std::allocator, std::allocator > const, osg::ref_ptr > > >::_M_erase(std::_Rb_tree_node, std::allocator > const, osg::ref_ptr > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:1889 #70 0x55fcfa6cc122 in std::_Rb_tree, std::allocator >, std::pair, std::allocator > const, osg::ref_ptr >, std::_Select1st, std::allocator > const, osg::ref_ptr > >, std::less, std::allocator > >, std::allocator, std::allocator > const, osg::ref_ptr > > >::_M_erase(std::_Rb_tree_node, std::allocator > const, osg::ref_ptr > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:1887 #71 0x55fcfa6cc122 in std::_Rb_tree, std::allocator >, std::pair, std::allocator > const, osg::ref_ptr >, std::_Select1st, std::allocator > const, osg::ref_ptr > >, std::less, std::allocator > >, std::allocator, std::allocator > const, osg::ref_ptr > > >::_M_erase(std::_Rb_tree_node, std::allocator > const, osg::ref_ptr > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:1887 #72 0x55fcfa6cc245 in std::_Rb_tree, std::allocator >, std::pair, std::allocator > const, osg::ref_ptr >, std::_Select1st, std::allocator > const, osg::ref_ptr > >, std::less, std::allocator > >, std::allocator, std::allocator > const, osg::ref_ptr > > >::~_Rb_tree() /usr/include/c++/11.1.0/bits/stl_tree.h:984 #73 0x55fcfa6cc245 in std::map, std::allocator >, osg::ref_ptr, std::less, std::allocator > >, std::allocator, std::allocator > const, osg::ref_ptr > > >::~map() /usr/include/c++/11.1.0/bits/stl_map.h:302 #74 0x55fcfa6cc245 in RenderBinPrototypeList::~RenderBinPrototypeList() /home/elsid/dev/OpenSceneGraph/src/osgUtil/RenderBin.cpp:48 #75 0x55fcfa6cc245 in RenderBinPrototypeList::~RenderBinPrototypeList() /home/elsid/dev/OpenSceneGraph/src/osgUtil/RenderBin.cpp:48 #76 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292 #77 0x55fcfa6cbcc1 in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/include/osg/Referenced:201 #78 0x55fcfa6cbcc1 in osg::ref_ptr::~ref_ptr() /home/elsid/dev/OpenSceneGraph/include/osg/ref_ptr:44 #79 0x7f3977bd04a6 in __run_exit_handlers (/usr/lib/libc.so.6+0x3f4a6) #80 0x7f3977bd064d in exit (/usr/lib/libc.so.6+0x3f64d) #81 0x7f3977bb8b2b in __libc_start_main (/usr/lib/libc.so.6+0x27b2b) #82 0x55fcf81ea12d in _start (/home/elsid/dev/openmw/build/gcc/asan/openmw+0xa4412d) 0x6040000ca1b0 is located 32 bytes inside of 48-byte region [0x6040000ca190,0x6040000ca1c0) freed by thread T0 here: #0 0x7f397a633d69 in operator delete(void*, unsigned long) /build/gcc/src/gcc/libsanitizer/asan/asan_new_delete.cpp:172 #1 0x55fcfa8d1824 in __gnu_cxx::new_allocator > > >::deallocate(std::_Rb_tree_node > >*, unsigned long) /usr/include/c++/11.1.0/ext/new_allocator.h:139 #2 0x55fcfa8d1824 in std::allocator_traits > > > >::deallocate(std::allocator > > >&, std::_Rb_tree_node > >*, unsigned long) /usr/include/c++/11.1.0/bits/alloc_traits.h:492 #3 0x55fcfa8d1824 in std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_put_node(std::_Rb_tree_node > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:565 #4 0x55fcfa8d1824 in std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_drop_node(std::_Rb_tree_node > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:632 #5 0x55fcfa8d1824 in std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_erase(std::_Rb_tree_node > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:1889 #6 0x55fcfa8d18da in std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::~_Rb_tree() /usr/include/c++/11.1.0/bits/stl_tree.h:984 #7 0x55fcfa8d18da in std::map, std::less, std::allocator > > >::~map() /usr/include/c++/11.1.0/bits/stl_map.h:302 #8 0x7f3977bd04a6 in __run_exit_handlers (/usr/lib/libc.so.6+0x3f4a6) previously allocated by thread T0 here: #0 0x7f397a632ca1 in operator new(unsigned long) /build/gcc/src/gcc/libsanitizer/asan/asan_new_delete.cpp:99 #1 0x55fcfa8d3aa1 in __gnu_cxx::new_allocator > > >::allocate(unsigned long, void const*) /usr/include/c++/11.1.0/ext/new_allocator.h:121 #2 0x55fcfa8d3aa1 in std::allocator_traits > > > >::allocate(std::allocator > > >&, unsigned long) /usr/include/c++/11.1.0/bits/alloc_traits.h:460 #3 0x55fcfa8d3aa1 in std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_get_node() /usr/include/c++/11.1.0/bits/stl_tree.h:561 #4 0x55fcfa8d3aa1 in std::_Rb_tree_node > >* std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_create_node, std::tuple<> >(std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) /usr/include/c++/11.1.0/bits/stl_tree.h:611 #5 0x55fcfa8d3aa1 in std::_Rb_tree_iterator > > std::_Rb_tree >, std::_Select1st > >, std::less, std::allocator > > >::_M_emplace_hint_unique, std::tuple<> >(std::_Rb_tree_const_iterator > >, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) /usr/include/c++/11.1.0/bits/stl_tree.h:2429 #6 0x55fcfa8cfd91 in std::map, std::less, std::allocator > > >::operator[](unsigned int const&) /usr/include/c++/11.1.0/bits/stl_map.h:501 #7 0x55fcfa8cfd91 in osg::ContextData::createNewContextID() /home/elsid/dev/OpenSceneGraph/src/osg/ContextData.cpp:171 #8 0x55fcfa9be218 in osg::GraphicsContext::createNewContextID() /home/elsid/dev/OpenSceneGraph/src/osg/GraphicsContext.cpp:320 #9 0x55fcfb68d1ef in SDLUtil::GraphicsWindowSDL2::GraphicsWindowSDL2(osg::GraphicsContext::Traits*) /home/elsid/dev/openmw/components/sdlutil/sdlgraphicswindow.cpp:39 #10 0x55fcfa17f93a in OMW::Engine::createWindow(Settings::Manager&) /home/elsid/dev/openmw/apps/openmw/engine.cpp:611 #11 0x55fcfa18398f in OMW::Engine::prepareEngine(Settings::Manager&) /home/elsid/dev/openmw/apps/openmw/engine.cpp:679 #12 0x55fcfa18c4f2 in OMW::Engine::go() /home/elsid/dev/openmw/apps/openmw/engine.cpp:949 #13 0x55fcfa13c9ff in runApplication(int, char**) /home/elsid/dev/openmw/apps/openmw/main.cpp:316 #14 0x55fcfb49f562 in wrapApplication(int (*)(int, char**), int, char**, std::__cxx11::basic_string, std::allocator > const&) /home/elsid/dev/openmw/components/debug/debugging.cpp:205 #15 0x55fcfa133114 in main /home/elsid/dev/openmw/apps/openmw/main.cpp:328 #16 0x7f3977bb8b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24) SUMMARY: AddressSanitizer: heap-use-after-free /usr/include/c++/11.1.0/bits/stl_function.h:386 in std::less::operator()(unsigned int const&, unsigned int const&) const Shadow bytes around the buggy address: 0x0c08800113e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c08800113f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0880011400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0880011410: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0880011420: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x0c0880011430: fa fa fd fd fd fd[fd]fd fa fa fa fa fa fa fa fa 0x0c0880011440: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0880011450: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0880011460: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0880011470: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0880011480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==7733==ABORTING --- components/sceneutil/mwshadowtechnique.cpp | 26 +++++++++++++++------- components/sceneutil/mwshadowtechnique.hpp | 8 +++++-- components/sceneutil/shadowsbin.cpp | 6 ----- components/sceneutil/shadowsbin.hpp | 2 -- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index 60f048b147..770917eda7 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -279,14 +279,7 @@ void VDSMCameraCullCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) } #endif // bin has to go inside camera cull or the rendertexture stage will override it - static osg::ref_ptr ss; - if (!ss) - { - ShadowsBin::addPrototype("ShadowsBin", _vdsm->getCastingPrograms()); - ss = new osg::StateSet; - ss->setRenderBinDetails(osg::StateSet::OPAQUE_BIN, "ShadowsBin", osg::StateSet::OVERRIDE_PROTECTED_RENDERBIN_DETAILS); - } - cv->pushStateSet(ss); + cv->pushStateSet(_vdsm->getOrCreateShadowsBinStateSet()); if (_vdsm->getShadowedScene()) { _vdsm->getShadowedScene()->osg::Group::traverse(*nv); @@ -811,6 +804,8 @@ MWShadowTechnique::MWShadowTechnique(const MWShadowTechnique& vdsm, const osg::C MWShadowTechnique::~MWShadowTechnique() { + if (_shadowsBin != nullptr) + osgUtil::RenderBin::removeRenderBinPrototype(_shadowsBin); } @@ -3282,3 +3277,18 @@ void SceneUtil::MWShadowTechnique::DebugHUD::addAnotherShadowMap() for(auto& uniformVector : mFrustumUniforms) uniformVector.push_back(new osg::Uniform(osg::Uniform::FLOAT_MAT4, "transform")); } + +osg::ref_ptr SceneUtil::MWShadowTechnique::getOrCreateShadowsBinStateSet() +{ + if (_shadowsBinStateSet == nullptr) + { + if (_shadowsBin == nullptr) + { + _shadowsBin = new ShadowsBin(_castingPrograms); + osgUtil::RenderBin::addRenderBinPrototype(_shadowsBinName, _shadowsBin); + } + _shadowsBinStateSet = new osg::StateSet; + _shadowsBinStateSet->setRenderBinDetails(osg::StateSet::OPAQUE_BIN, _shadowsBinName, osg::StateSet::OVERRIDE_PROTECTED_RENDERBIN_DETAILS); + } + return _shadowsBinStateSet; +} diff --git a/components/sceneutil/mwshadowtechnique.hpp b/components/sceneutil/mwshadowtechnique.hpp index 3f6c0fb765..574d054204 100644 --- a/components/sceneutil/mwshadowtechnique.hpp +++ b/components/sceneutil/mwshadowtechnique.hpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -215,8 +216,6 @@ namespace SceneUtil { virtual void createShaders(); - virtual std::array, GL_ALWAYS - GL_NEVER + 1> getCastingPrograms() const { return _castingPrograms; } - virtual bool selectActiveLights(osgUtil::CullVisitor* cv, ViewDependentData* vdd) const; virtual osg::Polytope computeLightViewFrustumPolytope(Frustum& frustum, LightData& positionedLight); @@ -237,6 +236,8 @@ namespace SceneUtil { void setWorldMask(unsigned int worldMask) { _worldMask = worldMask; } + osg::ref_ptr getOrCreateShadowsBinStateSet(); + protected: virtual ~MWShadowTechnique(); @@ -297,6 +298,9 @@ namespace SceneUtil { osg::ref_ptr _debugHud; std::array, GL_ALWAYS - GL_NEVER + 1> _castingPrograms; + const std::string _shadowsBinName = "ShadowsBin_" + std::to_string(reinterpret_cast(this)); + osg::ref_ptr _shadowsBin; + osg::ref_ptr _shadowsBinStateSet; }; } diff --git a/components/sceneutil/shadowsbin.cpp b/components/sceneutil/shadowsbin.cpp index 21f25dc4ad..3e933cbb98 100644 --- a/components/sceneutil/shadowsbin.cpp +++ b/components/sceneutil/shadowsbin.cpp @@ -146,12 +146,6 @@ StateGraph* ShadowsBin::cullStateGraph(StateGraph* sg, StateGraph* root, std::un return sg; } -void ShadowsBin::addPrototype(const std::string & name, const CastingPrograms& castingPrograms) -{ - osg::ref_ptr bin(new ShadowsBin(castingPrograms)); - osgUtil::RenderBin::addRenderBinPrototype(name, bin); -} - inline bool ShadowsBin::State::needTexture() const { return mAlphaBlend || (mAlphaFunc && mAlphaFunc->getFunction() != GL_ALWAYS); diff --git a/components/sceneutil/shadowsbin.hpp b/components/sceneutil/shadowsbin.hpp index 4b0d8cc544..2c838d509e 100644 --- a/components/sceneutil/shadowsbin.hpp +++ b/components/sceneutil/shadowsbin.hpp @@ -62,8 +62,6 @@ namespace SceneUtil osgUtil::StateGraph* cullStateGraph(osgUtil::StateGraph* sg, osgUtil::StateGraph* root, std::unordered_set& uninteresting, bool cullFaceOverridden); - static void addPrototype(const std::string& name, const CastingPrograms& castingPrograms); - private: ShadowsBin() {}