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

Reply via email to