Hi,

> hm, that looks quite strange. You are saying "longer than normal", what 
> are you doing normally and how is this case where you see the delays 
> different?

Here is a print out of the changelist and the time in sec it takes to call 
getChangeList()->applyAndClear() (measured with QueryPerformanceCounter 
under WindowsXP).  The last sync takes 0.4s, after that the sync time is 
normal again (under 0.01s).  When I run the program again, a "longer" sync 
happens on a different place, it's totally random.

Changed: 233 / AddRefd: 98 / SubRefd: 12 / Created: 57 / Destroyed: 0
Time: 0.00682698
Changed: 217 / AddRefd: 98 / SubRefd: 12 / Created: 57 / Destroyed: 0
Time: 0.00533654
Changed: 281 / AddRefd: 122 / SubRefd: 15 / Created: 70 / Destroyed: 0
Time: 0.0053213
Changed: 281 / AddRefd: 122 / SubRefd: 15 / Created: 70 / Destroyed: 0
Time: 0.0049716
Changed: 401 / AddRefd: 174 / SubRefd: 23 / Created: 96 / Destroyed: 0
Time: 0.4113007


> are you sure it is the synchronization that causes the delay (it should 
> not take that long unless you have huge changelists), or could it be 
> something different (texture upload and display list creation come to 
mind).

How large can a changelist become, before it takes too long to merge? Can 
I assume that applying 100 changed FieldContainer?s takes always an equal 
amount of time?
What is the best way to guarantee a short merge time (say under 0.1s)?


> > I can provide a minimal example if necessary.
> That would be helpful, specifically the long sync times are strange.

The program loads in a second thread all objects referenced in "file.lst" 
(1). In the display function I sync and measure the time (2).


#include <OpenSG/OSGSimpleSceneManager.h>
#include <OpenSG/OSGSimpleTexturedMaterial.h>
#include <OpenSG/OSGGLUTWindow.h>
#include <OpenSG/OSGGLUT.h>

OSG_USING_NAMESPACE

SimpleSceneManager *mgr;
NodePtr scene;
Thread* renderThread;
Thread* creationThread;
Barrier* syncBarrier;
bool syncNeeded;

int setupGLUT( int *argc, char *argv[] );

NodePtr createScenegraph()
{
        NodePtr n = Node::create();
        beginEditCP(n);
        n->setCore(Group::create());
        endEditCP(n);

        return n;
}


// executed by each geometry creation thread
void create(void *args)
{
        osg::FieldContainerPtr pProto = 
osg::Geometry::getClassType().getPrototype();
        osg::GeometryPtr pGeoProto = osg::GeometryPtr::dcast(pProto);

        if(pGeoProto != NullFC)
        {
                pGeoProto->setIgnoreGLForAspect(osg::Thread::getAspect());
        }

        pProto = osg::TextureChunk::getClassType().getPrototype();
        osg::TextureChunkPtr pTexChunkProto = 
osg::TextureChunkPtr::dcast(pProto);

        if(pTexChunkProto != NullFC)
        {
 pTexChunkProto->setIgnoreGLForAspect(osg::Thread::getAspect());
        }

        syncBarrier->enter(2);
        renderThread->getChangeList()->apply();
        syncBarrier->enter(2);

        std::vector<std::string> file_list;
        std::ifstream file;
        file.open("file.lst");
        while (!file.eof())
        {
                std::string line;
                std::getline(file, line);
                file_list.push_back(line);
        }

        unsigned int file_index = 0;

        while (true)
        {
                NodePtr groupNode = scene;

                if (file_index == file_list.size())
                        break;

                // (1)
                // I have a std::vector with filenames and load with 
                // OpenSG loader 1 file in each loop 
                std::string file_name = file_list[file_index];
                NodePtr new_node = 
SceneFileHandler::the().read(file_name.c_str());
                beginEditCP(groupNode);
                groupNode->addChild(new_node);
                endEditCP(groupNode);

                file_index++;

                // ready to sync
                syncNeeded = true;

                // wait for the render thread to sync over changes
                syncBarrier->enter(2);
                syncNeeded = false;
                syncBarrier->enter(2);
        }
}


int main(int argc, char *argv[])
{
#if OSG_MINOR_VERSION > 2
        ChangeList::setReadWriteDefault();
#endif
        osgInit(argc, argv);

        int winid = setupGLUT(&argc, argv);
        GLUTWindowPtr gwin = GLUTWindow::create();

        beginEditCP(gwin);
        gwin->setId(winid);
        endEditCP(gwin);

        gwin->init();

        scene = createScenegraph();

        mgr = new SimpleSceneManager;
        mgr->setWindow(gwin );
        mgr->setRoot (scene);
        mgr->setStatistics(true);
        mgr->showAll();

        syncBarrier = Barrier::get("syncBarrier1");
        renderThread = dynamic_cast<Thread 
*>(ThreadManager::getAppThread());
        syncNeeded = false;

        // start the threads
        creationThread = dynamic_cast<Thread 
*>(ThreadManager::the()->getThread("creationThread"));
        creationThread->runFunction(create, 1, NULL);
 
        // wait for the creation threads to sync over changes
        syncBarrier->enter(2);
        syncBarrier->enter(2);

        // clear changes - they are synced to aspect 1 now
        Thread::getCurrentChangeList()->clearAll();

        beginEditCP(mgr->getCamera());
        mgr->getCamera()->setNear( 0.5 );
        mgr->getCamera()->setFar( 15000 );
        endEditCP(mgr->getCamera());

        glutMainLoop();

        return 0;
}

void display(void)
{
        // check thread for available changes
        if(syncNeeded == true)
        {
                // (2)
                syncBarrier->enter(2);
                creationThread->getChangeList()->applyAndClear();
                syncBarrier->enter(2);
        }

        mgr->redraw();
        renderThread->getChangeList()->clearAll();
}


void reshape(int w, int h)
{
        mgr->resize(w, h);
        glutPostRedisplay();
}

void mouse(int button, int state, int x, int y)
{
        if (state)
                mgr->mouseButtonRelease(button, x, y);
        else
                mgr->mouseButtonPress(button, x, y);

        glutPostRedisplay();
}

void motion(int x, int y)
{
        mgr->mouseMove(x, y);
        glutPostRedisplay();
}

int setupGLUT(int *argc, char *argv[])
{
        glutInit(argc, argv);
        glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);

        int winid = glutCreateWindow("OpenSG Multithreading Test");

        glutDisplayFunc(display);
        glutMouseFunc(mouse);
        glutMotionFunc(motion);
        glutReshapeFunc(reshape);
        glutIdleFunc(display);

        return winid;
}

Thanks
Marc
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables 
unlimited royalty-free distribution of the report engine 
for externally facing server and web deployment. 
http://p.sf.net/sfu/businessobjects
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users

Reply via email to