Fixed threading crash in osgFX that occurred when an osgFX node is added to the scene being rendered in multiple threaded windows.

This commit is contained in:
Robert Osfield 2018-04-04 15:09:43 +01:00
parent 74e74d76d9
commit 9168b6e5de
2 changed files with 21 additions and 8 deletions

View File

@ -123,28 +123,32 @@ namespace osgFX
private:
typedef std::vector<osg::ref_ptr<osg::StateSet> > Pass_list;
Pass_list _passes;
OpenThreads::Mutex _mutex;
OpenThreads::Atomic _passesDefined;
Pass_list _passes;
};
// INLINE METHODS
inline int Technique::getNumPasses() const
{
return static_cast<int>(_passes.size());
return _passesDefined!=0 ? static_cast<int>(_passes.size()) : 0;
}
inline osg::StateSet* Technique::getPassStateSet(int i)
{
return _passes[i].get();
return _passesDefined!=0 ? _passes[i].get() : 0;
}
inline const osg::StateSet* Technique::getPassStateSet(int i) const
{
return _passes[i].get();
return _passesDefined!=0 ? _passes[i].get() : 0;
}
inline void Technique::dirtyPasses()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock( _mutex);
_passesDefined.exchange(0);
_passes.clear();
}

View File

@ -8,7 +8,8 @@
using namespace osgFX;
Technique::Technique()
: osg::Referenced()
: osg::Referenced(),
_passesDefined(0)
{
}
@ -37,8 +38,16 @@ bool Technique::validate(osg::State& state) const
void Technique::traverse_implementation(osg::NodeVisitor& nv, Effect* fx)
{
// define passes if necessary
if (_passes.empty()) {
define_passes();
if (_passesDefined==0)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock( _mutex);
if (_passesDefined==0)
{
define_passes();
_passesDefined.exchange(1);
}
}
// special actions must be taken if the node visitor is actually a CullVisitor
@ -46,7 +55,7 @@ void Technique::traverse_implementation(osg::NodeVisitor& nv, Effect* fx)
if (cv)
{
// traverse all passes
for (int i=0; i<getNumPasses(); ++i)
for (int i=0; i<_passes.size(); ++i)
{
// push the i-th pass' StateSet
cv->pushStateSet(_passes[i].get());