Hi Robert,
I've had a bit of time to look at this again today. Here's another
interesting find: adding views at startup works fine. I can add over 30
of them (I couldn't get to 40, the program crashes, I presume because of
exhaustion of OpenGL resources or something).
Here's a modified osgviewer.cpp which demonstrates this.
<program> --create 20
The default is to create a single view. Starting it up with a single
view and then pressing 'a' at run time will make the program block after
4 to 6 views for me. So there's something there.
I also tested adding views after viewer.realize() but before
viewer.run(), and this seems to work too. You can specify when to create
the views (default is beforeRealize):
<program> --create 20 --beforeRealize
or
<program> --create 20 --afterRealize
Both work for me.
So there's something going on while the viewer is running that causes
the deadlock to occur if we add views at runtime. Adding them at any
time before viewer.run() seems to work fine.
As an aside, I've updated my graphics driver from 178.xx to 180.xx last
Friday, but noticed no difference in this behavior.
It would be worth looking at exactly when the problem occurs - is it
on the stopThreading, the addView, or the startThreading or
thereafter?
The deadlock definitely happens after the view has been added (after
stopThreading, addView, startThreading). It looks to me that it happens
on the first frame after adding the view.
I'd really like to get to the bottom of this. When did you say you were
going to be building your new machine? In the mean time, any chance you
can find some time in your schedule to track down some other machine
that would reproduce this? (JP's and Don's posts seem to indicate it can
be reproduced on Linux on some machines...)
Thanks in advance,
J-S
--
______________________________________________________
Jean-Sebastien Guay [EMAIL PROTECTED]
http://www.cm-labs.com/
http://whitestar02.webhop.org/
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This application is open source and may be redistributed and/or modified
* freely and without restriction, both in commericial and non commericial
applications,
* as long as this copyright notice is maintained.
*
* This application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osg/CoordinateSystemNode>
#include <osg/Switch>
#include <osgText/Text>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <iostream>
// Forward declaration
void addView(osgViewer::CompositeViewer* viewer, osg::Node* sceneRoot);
class AddViewHandler : public osgGA::GUIEventHandler
{
public:
AddViewHandler(osgViewer::CompositeViewer* viewer, osg::Node* sceneRoot)
: _viewer(viewer), _sceneRoot(sceneRoot) {}
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN &&
ea.getKey()== 'a')
{
addView(_viewer.get(), _sceneRoot);
return true;
}
return false;
}
protected:
osg::observer_ptr<osgViewer::CompositeViewer> _viewer;
osg::ref_ptr<osg::Node> _sceneRoot;
};
void addEventHandlers(osgViewer::View* view, osgViewer::CompositeViewer*
viewer, osg::Node* sceneRoot)
{
// set up the camera manipulators.
view->setCameraManipulator( new osgGA::TrackballManipulator() );
// add the state manipulator
view->addEventHandler( new
osgGA::StateSetManipulator(view->getCamera()->getOrCreateStateSet()) );
// add the thread model handler
view->addEventHandler(new osgViewer::ThreadingHandler);
// add the window size toggle handler
view->addEventHandler(new osgViewer::WindowSizeHandler);
// add the stats handler
view->addEventHandler(new osgViewer::StatsHandler);
// add the record camera path handler
view->addEventHandler(new osgViewer::RecordCameraPathHandler);
// add the LOD Scale handler
view->addEventHandler(new osgViewer::LODScaleHandler);
// add the screen capture handler
view->addEventHandler(new osgViewer::ScreenCaptureHandler);
view->addEventHandler(new AddViewHandler(viewer, sceneRoot));
}
void addView(osgViewer::CompositeViewer* viewer, osg::Node* sceneRoot)
{
osgViewer::View* view = new osgViewer::View;
view->setUpViewInWindow(50, 50, 800, 600);
view->getCamera()->getGraphicsContext()->realize();
view->setSceneData(sceneRoot);
addEventHandlers(view, viewer, sceneRoot);
bool threadsWereRunning = viewer->areThreadsRunning();
if (threadsWereRunning) viewer->stopThreading();
viewer->addView(view);
osg::notify(osg::NOTICE)<<"osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts()="<<
osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts()<<std::endl;
view->getSceneData()->setThreadSafeRefUnref(true);
view->getSceneData()->resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts());
if (threadsWereRunning) viewer->startThreading();
}
int main(int argc, char** argv)
{
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc,argv);
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+"
is the standard OpenSceneGraph example which loads and visualises 3d models.");
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+"
[options] filename ...");
arguments.getApplicationUsage()->addCommandLineOption("--image
<filename>","Load an image and render it on a quad");
arguments.getApplicationUsage()->addCommandLineOption("--dem
<filename>","Load an image/DEM and render it on a HeightField");
arguments.getApplicationUsage()->addCommandLineOption("--login <url>
<username> <password>","Provide authentication information for http file
access.");
osgViewer::CompositeViewer viewer(arguments);
unsigned int helpType = 0;
if ((helpType = arguments.readHelpType()))
{
arguments.getApplicationUsage()->write(std::cout, helpType);
return 1;
}
// report any errors if they have occurred when parsing the program
arguments.
if (arguments.errors())
{
arguments.writeErrorMessages(std::cout);
return 1;
}
if (arguments.argc()<=1)
{
arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
return 1;
}
std::string url, username, password;
while(arguments.read("--login",url, username, password))
{
if (!osgDB::Registry::instance()->getAuthenticationMap())
{
osgDB::Registry::instance()->setAuthenticationMap(new
osgDB::AuthenticationMap);
osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails(
url,
new osgDB::AuthenticationDetails(username, password)
);
}
}
unsigned int createViews = 1;
while (arguments.read("--create", createViews));
bool beforeRealize = true;
while (arguments.read("--beforeRealize")) beforeRealize = true;
while (arguments.read("--afterRealize")) beforeRealize = false;
// load the data
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
if (!loadedModel)
{
std::cout << arguments.getApplicationName() <<": No data loaded" <<
std::endl;
return 1;
}
// any option left unread are converted into errors to write out later.
arguments.reportRemainingOptionsAsUnrecognized();
// report any errors if they have occurred when parsing the program
arguments.
if (arguments.errors())
{
arguments.writeErrorMessages(std::cout);
return 1;
}
if (beforeRealize)
{
// Create n views at startup, before viewer.realize()
for (unsigned int i = 0; i < createViews; i++)
{
addView(&viewer, loadedModel.get());
}
}
viewer.realize();
if (!beforeRealize)
{
// Create n views at startup, after viewer.realize()
for (unsigned int i = 0; i < createViews; i++)
{
addView(&viewer, loadedModel.get());
}
// Need to set done to false and re-call realize().
viewer.setDone(false);
viewer.realize();
}
return viewer.run();
}
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org