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