From b1994cc60d2b15cac4527ba2a6b0e7c9b44c844d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 29 Jul 2006 16:47:28 +0000 Subject: [PATCH] Fixed multi-threaded/multi-pipe crash when primitive stats where output in osgProducer::Viewer's stats. --- include/osgProducer/OsgSceneHandler | 25 ++++-- include/osgProducer/ViewerEventHandler | 3 - include/osgUtil/Statistics | 40 ++++++++- src/osgProducer/OsgSceneHandler.cpp | 21 ++++- src/osgProducer/ViewerEventHandler.cpp | 81 ++----------------- .../osgProducer/OsgSceneHandler.cpp | 5 ++ src/osgWrappers/osgUtil/Statistics.cpp | 7 +- 7 files changed, 90 insertions(+), 92 deletions(-) diff --git a/include/osgProducer/OsgSceneHandler b/include/osgProducer/OsgSceneHandler index df1430f8e..78ca03548 100644 --- a/include/osgProducer/OsgSceneHandler +++ b/include/osgProducer/OsgSceneHandler @@ -16,6 +16,7 @@ #include #include +#include #include @@ -104,6 +105,11 @@ class OSGPRODUCER_EXPORT OsgSceneHandler : public Producer::Camera::SceneHandler Callback* getDrawCallback() { return _drawCallback.get(); } const Callback* getDrawCallback() const { return _drawCallback.get(); } + void setCollectStats(bool collectStats) { _collectStats = collectStats; } + bool getCollectStats() const { return _collectStats; } + + bool getStats(osgUtil::Statistics& primStats); + void setContextID( int id ); void setFlushOfAllDeletedGLObjectsOnNextFrame(bool flag) { _flushOfAllDeletedGLObjectsOnNextFrame = flag; } @@ -119,17 +125,22 @@ class OSGPRODUCER_EXPORT OsgSceneHandler : public Producer::Camera::SceneHandler virtual ~OsgSceneHandler() {} + OpenThreads::Mutex _cullMutex; + osg::ref_ptr _sceneView; - osg::ref_ptr _clearCallback; - osg::ref_ptr _cullCallback; - osg::ref_ptr _drawCallback; + osg::ref_ptr _clearCallback; + osg::ref_ptr _cullCallback; + osg::ref_ptr _drawCallback; - osg::Timer_t _frameStartTick; - osg::Timer_t _previousFrameStartTick; + osg::Timer_t _frameStartTick; + osg::Timer_t _previousFrameStartTick; - bool _flushOfAllDeletedGLObjectsOnNextFrame; - bool _cleanUpOnNextFrame; + bool _flushOfAllDeletedGLObjectsOnNextFrame; + bool _cleanUpOnNextFrame; + + bool _collectStats; + osgUtil::Statistics _stats; }; } diff --git a/include/osgProducer/ViewerEventHandler b/include/osgProducer/ViewerEventHandler index 559ae60a3..f081f9847 100644 --- a/include/osgProducer/ViewerEventHandler +++ b/include/osgProducer/ViewerEventHandler @@ -72,9 +72,6 @@ class OSGPRODUCER_EXPORT ViewerEventHandler : public osgGA::GUIEventHandler bool _firstTimeTogglingFullScreen; - class CameraBarrierCallback; - CameraBarrierCallback* _cameraBarrierCallback; - class StatsAndHelpDrawCallback; StatsAndHelpDrawCallback* _statsAndHelpDrawCallback; diff --git a/include/osgUtil/Statistics b/include/osgUtil/Statistics index 8a1f30e07..666c8ea15 100644 --- a/include/osgUtil/Statistics +++ b/include/osgUtil/Statistics @@ -56,7 +56,7 @@ class Statistics : public osg::PrimitiveFunctor reset(); }; - enum statsType + enum StatsType { STAT_NONE, // default STAT_FRAMERATE, @@ -88,7 +88,7 @@ class Statistics : public osg::PrimitiveFunctor _number_of_vertexes=0; } - void setType(statsType t) {stattype=t;} + void setType(StatsType t) {stattype=t;} virtual void setVertexArray(unsigned int count,const osg::Vec3*) { _vertexCount += count; } virtual void setVertexArray(unsigned int count,const osg::Vec2*) { _vertexCount += count; } @@ -160,7 +160,39 @@ class Statistics : public osg::PrimitiveFunctor void setDepth(int d) { depth=d; } void addBins(int np) { nbins+= np; } - void setBinNo(int n) { _binNo=n;} + void setBinNo(int n) { _binNo=n;} + + void add(const Statistics& stats) + { + numDrawables += stats.numDrawables; + nummat += stats.nummat; + depth += stats.depth; + nlights += stats.nlights; + nbins += stats.nbins; + nimpostor += stats.nimpostor; + + _vertexCount += stats._vertexCount; + // _primitiveCount += stats._primitiveCount; + for(PrimitiveValueMap::const_iterator pitr = stats._primitiveCount.begin(); + pitr != stats._primitiveCount.end(); + ++pitr) + { + _primitiveCount[pitr->first].first += pitr->second.first; + _primitiveCount[pitr->first].second += pitr->second.second; + } + + _currentPrimitiveFunctorMode += stats._currentPrimitiveFunctorMode; + + for(PrimitiveCountMap::const_iterator citr = stats._primitives_count.begin(); + citr != stats._primitives_count.end(); + ++citr) + { + _primitives_count[citr->first] += citr->second; + } + + _total_primitives_count += stats._total_primitives_count; + _number_of_vertexes += stats._number_of_vertexes; + } public: @@ -171,7 +203,7 @@ class Statistics : public osg::PrimitiveFunctor int nlights; int depth; // depth into bins - eg 1.1,1.2,1.3 etc int _binNo; - statsType stattype; + StatsType stattype; int nimpostor; // number of impostors rendered unsigned int _vertexCount; diff --git a/src/osgProducer/OsgSceneHandler.cpp b/src/osgProducer/OsgSceneHandler.cpp index 6ae72d8cc..f0b8a19d1 100644 --- a/src/osgProducer/OsgSceneHandler.cpp +++ b/src/osgProducer/OsgSceneHandler.cpp @@ -21,7 +21,8 @@ using namespace osgUtil; using namespace osgProducer; OsgSceneHandler::OsgSceneHandler( osg::DisplaySettings *ds) : - _sceneView(new osgUtil::SceneView(ds)) + _sceneView(new osgUtil::SceneView(ds)), + _collectStats(false) { _frameStartTick = 0; _previousFrameStartTick = 0; @@ -59,6 +60,7 @@ void OsgSceneHandler::clearImplementation(Producer::Camera& /*camera*/) void OsgSceneHandler::cullImplementation(Producer::Camera &cam) { + OpenThreads::ScopedLock lock(_cullMutex); _sceneView->getProjectionMatrix().set(cam.getProjectionMatrix()); _sceneView->getViewMatrix().set(cam.getPositionAndAttitudeMatrix()); @@ -74,6 +76,23 @@ void OsgSceneHandler::cullImplementation(Producer::Camera &cam) _sceneView->setClearColor(clear_color); _sceneView->cull(); + + if (_collectStats) + { + _stats.reset(); + _sceneView->getStats(_stats); + } +} + +bool OsgSceneHandler::getStats(Statistics& primStats) +{ + if (!_collectStats) return false; + + OpenThreads::ScopedLock lock(_cullMutex); + + primStats.add(_stats); + + return true; } void OsgSceneHandler::drawImplementation(Producer::Camera &) diff --git a/src/osgProducer/ViewerEventHandler.cpp b/src/osgProducer/ViewerEventHandler.cpp index cf1658913..eacbf9a04 100644 --- a/src/osgProducer/ViewerEventHandler.cpp +++ b/src/osgProducer/ViewerEventHandler.cpp @@ -14,55 +14,6 @@ using namespace osgProducer; -class ViewerEventHandler::CameraBarrierCallback : public Producer::Camera::Callback, public OpenThreads::Barrier -{ -public: - CameraBarrierCallback(unsigned int numThreads): - OpenThreads::Barrier(numThreads), - _doBlock(false) {} - - virtual ~CameraBarrierCallback() - { - release(); - } - - void setDoBlock(bool block) - { - OpenThreads::ScopedLock lock(_mutex); - if (_doBlock != block) - { - if (_doBlock) release(); - - _doBlock = block; - - osg::notify(osg::NOTICE)<<"setDoBlock("< lock(_mutex); - doBlock = _doBlock; - } - - if (doBlock) - { - osg::notify(osg::NOTICE)<<"Entering block()"<getOsgCameraGroup()->getSceneHandlerList().end(); ++shitr) { - (*shitr)->getSceneView()->getStats(stats); + (*shitr)->getStats(stats); } unsigned int primitives = 0; @@ -918,19 +869,6 @@ ViewerEventHandler::ViewerEventHandler(OsgCameraGroup* cg): { Producer::CameraConfig* cfg = _cg->getCameraConfig(); - _cameraBarrierCallback = 0; -#if 0 - if (cfg->getNumberOfCameras()>1) - { - // use a barrier to make that stats only runs once all the threads have done their drawing. - _cameraBarrierCallback = new CameraBarrierCallback(cfg->getNumberOfCameras()); - for(unsigned int i=0;igetNumberOfCameras();++i) - { - cfg->getCamera(i)->addPostDrawCallback(_cameraBarrierCallback); - } - } -#endif - Producer::Camera *cam = cfg->getCamera(0); _statsAndHelpDrawCallback = new StatsAndHelpDrawCallback(this,0); @@ -987,18 +925,13 @@ void ViewerEventHandler::setWriteImageFileName(const std::string& filename) void ViewerEventHandler::setFrameStatsMode(FrameStatsMode mode) { _frameStatsMode = mode; - if (_frameStatsMode==NO_STATS) + _cg->setInstrumentationMode(_frameStatsMode!=NO_STATS); + + for(osgProducer::OsgCameraGroup::SceneHandlerList::iterator shitr = _cg->getSceneHandlerList().begin(); + shitr != _cg->getSceneHandlerList().end(); + ++shitr) { - _cg->setInstrumentationMode(false); - } - else - { - _cg->setInstrumentationMode(true); - } - - if (_cameraBarrierCallback) - { - _cameraBarrierCallback->setDoBlock(_frameStatsMode>=SCENE_STATS); + (*shitr)->setCollectStats(_frameStatsMode==SCENE_STATS); } } diff --git a/src/osgWrappers/osgProducer/OsgSceneHandler.cpp b/src/osgWrappers/osgProducer/OsgSceneHandler.cpp index 3954742dd..74ae9672b 100644 --- a/src/osgWrappers/osgProducer/OsgSceneHandler.cpp +++ b/src/osgWrappers/osgProducer/OsgSceneHandler.cpp @@ -12,6 +12,7 @@ #include #include #include +#include // Must undefine IN and OUT macros defined in Windows headers #ifdef IN @@ -42,6 +43,9 @@ BEGIN_OBJECT_REFLECTOR(osgProducer::OsgSceneHandler) I_Method1(void, setDrawCallback, IN, osgProducer::OsgSceneHandler::Callback *, callback); I_Method0(osgProducer::OsgSceneHandler::Callback *, getDrawCallback); I_Method0(const osgProducer::OsgSceneHandler::Callback *, getDrawCallback); + I_Method1(void, setCollectStats, IN, bool, collectStats); + I_Method0(bool, getCollectStats); + I_Method1(bool, getStats, IN, osgUtil::Statistics &, primStats); I_Method1(void, setContextID, IN, int, id); I_Method1(void, setFlushOfAllDeletedGLObjectsOnNextFrame, IN, bool, flag); I_Method0(bool, getFlushOfAllDeletedGLObjectsOnNextFrame); @@ -49,6 +53,7 @@ BEGIN_OBJECT_REFLECTOR(osgProducer::OsgSceneHandler) I_Method0(bool, getCleanUpOnNextFrame); I_Property(bool, CleanUpOnNextFrame); I_Property(osgProducer::OsgSceneHandler::Callback *, ClearCallback); + I_Property(bool, CollectStats); I_WriteOnlyProperty(int, ContextID); I_Property(osgProducer::OsgSceneHandler::Callback *, CullCallback); I_Property(osgProducer::OsgSceneHandler::Callback *, DrawCallback); diff --git a/src/osgWrappers/osgUtil/Statistics.cpp b/src/osgWrappers/osgUtil/Statistics.cpp index 4a37a9932..23f83ed0c 100644 --- a/src/osgWrappers/osgUtil/Statistics.cpp +++ b/src/osgWrappers/osgUtil/Statistics.cpp @@ -34,7 +34,7 @@ TYPE_NAME_ALIAS(std::map< GLenum COMMA osgUtil::Statistics::PrimitivePair >, os TYPE_NAME_ALIAS(std::map< GLenum COMMA unsigned int >, osgUtil::Statistics::PrimitiveCountMap); -BEGIN_ENUM_REFLECTOR(osgUtil::Statistics::statsType) +BEGIN_ENUM_REFLECTOR(osgUtil::Statistics::StatsType) I_EnumLabel(osgUtil::Statistics::STAT_NONE); I_EnumLabel(osgUtil::Statistics::STAT_FRAMERATE); I_EnumLabel(osgUtil::Statistics::STAT_GRAPHS); @@ -49,7 +49,7 @@ BEGIN_OBJECT_REFLECTOR(osgUtil::Statistics) I_BaseType(osg::PrimitiveFunctor); I_Constructor0(); I_Method0(void, reset); - I_Method1(void, setType, IN, osgUtil::Statistics::statsType, t); + I_Method1(void, setType, IN, osgUtil::Statistics::StatsType, t); I_Method2(void, setVertexArray, IN, unsigned int, count, IN, const osg::Vec3 *, x); I_Method2(void, setVertexArray, IN, unsigned int, count, IN, const osg::Vec2 *, x); I_Method2(void, setVertexArray, IN, unsigned int, count, IN, const osg::Vec4 *, x); @@ -74,12 +74,13 @@ BEGIN_OBJECT_REFLECTOR(osgUtil::Statistics) I_Method1(void, setDepth, IN, int, d); I_Method1(void, addBins, IN, int, np); I_Method1(void, setBinNo, IN, int, n); + I_Method1(void, add, IN, const osgUtil::Statistics &, stats); I_Method0(osgUtil::Statistics::PrimitiveCountMap::iterator, GetPrimitivesBegin); I_Method0(osgUtil::Statistics::PrimitiveCountMap::iterator, GetPrimitivesEnd); I_WriteOnlyProperty(int, BinNo); I_ReadOnlyProperty(int, Bins); I_WriteOnlyProperty(int, Depth); - I_WriteOnlyProperty(osgUtil::Statistics::statsType, Type); + I_WriteOnlyProperty(osgUtil::Statistics::StatsType, Type); END_REFLECTOR TYPE_NAME_ALIAS(std::set< osg::Node * >, osgUtil::StatsVisitor::NodeSet);