Re: [osg-users] Complete garbage in OSG / XP / multi monitor /multithreaded / NVidia
Hi Wojtek, This morning I awoke and had an idea about why the compile bit be running currently with the update traversal, so I got up and reviewed the code and your test example. First up I can reproduce the problem of the red then green flag on my linux box so when I/we do come up with a solution I do have a chance of confirming the solution works at my end. The problem itself looks to be caused by the GLObjectOperation which does runs GLObjectVisitor is something that is added to the GraphicsContext's GraphicsThread prior to the RunOperaration which will intigate the rendering of the cameras. What this will mean is that compile will always occur before the rendering of the cameras - this is a good thing. The compile will also happen right away after the realize()/startThreading() and before any barriers/blocks have been joined, now normally this is a good thing i.e. to get the compile done before any serious rendering happens, but and this is this big but, it will run concurrently with the first frames update/event traversal in all non SingleThreaded models, and even concurrently to the first frames cull traversal. So... this is why we have the problem. The solution is either to add a block that prevents the first frame from commencing till all the CompileOperations have been complete, or to move the compile into the osgViewer::Renderer::draw() implementation, so the compile is done after cull, but before the first draw(). The first solution introduces greater internal complexity, the second solution will mean the first frame will be very slow. I'm not clear on what route to take. Doing a hack of the second would probably the first thing to try. Robert. ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Complete garbage in OSG / XP / multi monitor/multithreaded / NVidia
Hi Robert, The solution is either to add a block that prevents the first frame from commencing till all the CompileOperations have been complete, or to move the compile into the osgViewer::Renderer::draw() implementation, so the compile is done after cull, but before the first draw(). The first solution introduces greater internal complexity, the second solution will mean the first frame will be very slow. I'm not clear on what route to take. Doing a hack of the second would probably the first thing to try. Realize in Producer::Viewer was usually explicitly called before entering update/event/cull/render loop. osgViewer::Viewer::Realize can still be called by user before main loop. I believe this makes first solution pretty tricky, one would need to sync return from Viewer::Realize with completion of GL compile operations. I don't know if this is simple task considering number of Threading modes. Second solution does not differ so much from what we have now with this exception that lengthy compilation would be invoked after first update/event/cull traversal. Currently its done before these traversals. But from timing perspective it would not change much. Am I right ? Wojtek ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Complete garbage in OSG / XP / multi monitor/multithreaded / NVidia
Hi Wojciech, On Sat, May 10, 2008 at 4:23 PM, Wojciech Lewandowski [EMAIL PROTECTED] wrote: Realize in Producer::Viewer was usually explicitly called before entering update/event/cull/render loop. osgViewer::Viewer::Realize can still be called by user before main loop. I believe this makes first solution pretty tricky, one would need to sync return from Viewer::Realize with completion of GL compile operations. I don't know if this is simple task considering number of Threading modes. Actually osgViewer::Viewer::realize() is little different than the old Producer::CameraGroup::realize()/osgProducer::Viewer::realize() in terms of order of operations. osgViewer::Viewer::realize() will be called automatically on the first frame is it hasn't already been called by the user, so this is the only real difference in terms of order. osgProducer/Producer based apps did have a sync() at the begining of each frame, something that osgViewer doesn't have, rather then sync() of threads in done internally in renderingTraversals() at the end of the frame. This change makes it simpler to use osgViewer based apps as one doesn't need to worry about sync. One could still keep the external API simple by placing a barrier at the end of startThreading() in a similar way to renderinTraversals() does. However, while the API would not change, the internal implementation would be more complicated. Second solution does not differ so much from what we have now with this exception that lengthy compilation would be invoked after first update/event/cull traversal. Currently its done before these traversals. But from timing perspective it would not change much. Am I right ? The difference is the order of when the compile is done, and where the compile is instigated. The first frame which contains the compile does have a big hit - it's frame time will be higher than all subsequent frames, so we'll see a hesitation on first frame then the app will get going smoothly. I have gone ahead an implemented this approach, extending osgViewer::Renderer so it now has a compile() method that gets called automatically on the next draw, but once called won't get called again unless explicitly requested to do so. An svn update will get this change. In osgViewer::Renderer there is now a s/getCompileOnNextDraw() method to control when the compile is done, I've modified osgViewer::View::setSceneData() so that it now will reset the CompileOnNextDraw() so it'll now do a compile when you load new models, so this is nice little bonus from this change. In testing with your modified osgprerender things are now working smoothly. Could you let me know how you get on at your end. Robert. Wojtek ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Complete garbage in OSG / XP / multi monitor/multithreaded / NVidia
Thanks Robert, I did some testing. Fix seems to work at my Home. No red frames at all. However there seems to be an issue with --CullThreadPerCameraDrawThreadPerContext mode which looks like a deadlock after third frame (plane moved three times and stopped). Mode can be invoked either by threading handler or by simply running the app with --CullThreadPerCameraDrawThreadPerContext. I have a really slow computer at home Athlon XP 1700 + GeForce 6200. I was seeing some issues in this threading mode previously so this might be nothing special and related to my machine. I will retest on monday with my company machine. If it may help this is a dump from call stack for all the threads. I skipped irrelevant system calls after cooperativeWait and before mainCRTStartup/ StartThread. // Main thread: ot10-OpenThreadsd.dll!OpenThreads::cooperativeWait(void * waitHandle=0x2efc, unsigned long timeout=4294967295) Line 54 + 0x10 bytes ot10-OpenThreadsd.dll!OpenThreads::Win32ConditionPrivateData::wait(OpenThrea ds::Mutex external_mutex={...}, long timeout_ms=-1) Line 107 + 0x1d bytes ot10-OpenThreadsd.dll!OpenThreads::Condition::wait(OpenThreads::Mutex * mutex=0x0202f708) Line 63 osg35-osgViewerd.dll!OpenThreads::BlockCount::block() Line 133 + 0x17 bytes osg35-osgViewerd.dll!osgViewer::ViewerBase::renderingTraversals() Line 695 osg35-osgViewerd.dll!osgViewer::ViewerBase::frame(double simulationTime=1.7976931348623157e+308) Line 578 + 0xf bytes osg35-osgViewerd.dll!osgViewer::ViewerBase::run() Line 550 + 0x1b bytes osg35-osgViewerd.dll!osgViewer::Viewer::run() Line 306 osgprerenderd.exe!main(int argc=1, char * * argv=0x01f8d9f0) Line 486 + 0xe bytes osgprerenderd.exe!__tmainCRTStartup() Line 582 + 0x19 bytes osgprerenderd.exe!mainCRTStartup() Line 399 // First Worker Thread:( My bet its a Cull Thread ) ot10-OpenThreadsd.dll!OpenThreads::cooperativeWait(void * waitHandle=0x2ef8, unsigned long timeout=4294967295) Line 49 + 0x14 bytes ot10-OpenThreadsd.dll!OpenThreads::Win32ConditionPrivateData::wait(OpenThrea ds::Mutex external_mutex={...}, long timeout_ms=-1) Line 107 + 0x1d bytes ot10-OpenThreadsd.dll!OpenThreads::Condition::wait(OpenThreads::Mutex * mutex=0x0202f9d8) Line 63 ot10-OpenThreadsd.dll!OpenThreads::Barrier::block(unsigned int numThreads=0) Line 93 + 0x16 bytes osg35-osgd.dll!osg::BarrierOperation::operator()(osg::Object * object=0x01f8edd0) Line 72 + 0x15 bytes osg35-osgd.dll!osg::OperationThread::run() Line 413 + 0x26 bytes ot10-OpenThreadsd.dll!OpenThreads::ThreadPrivateActions::StartThread(void * data=0x02030868) Line 112 + 0xf bytes // Second Worker Thread:( This looks like a Draw Thread ) ot10-OpenThreadsd.dll!OpenThreads::cooperativeWait(void * waitHandle=0x2f64, unsigned long timeout=4294967295) Line 49 + 0x14 bytes ot10-OpenThreadsd.dll!OpenThreads::Win32ConditionPrivateData::wait(OpenThrea ds::Mutex external_mutex={...}, long timeout_ms=-1) Line 107 + 0x1d bytes ot10-OpenThreadsd.dll!OpenThreads::Condition::wait(OpenThreads::Mutex * mutex=0x01f90e4c) Line 63 osg35-osgViewerd.dll!OpenThreads::Block::block() Line 42 + 0x17 bytes osg35-osgViewerd.dll!osgViewer::Renderer::TheadSafeQueue::takeFront() Line 137 osg35-osgViewerd.dll!osgViewer::Renderer::draw() Line 335 + 0xe bytes osg35-osgViewerd.dll!osgViewer::Renderer::operator()(osg::GraphicsContext * context=0x0202e468) Line 634 + 0xf bytes osg35-osgd.dll!osg::GraphicsContext::runOperations() Line 701 + 0x33 bytes osg35-osgd.dll!osg::RunOperations::operator()(osg::GraphicsContext * context=0x0202e468) Line 135 osg35-osgd.dll!osg::GraphicsOperation::operator()(osg::Object * object=0x0202e468) Line 50 + 0x19 bytes osg35-osgd.dll!osg::OperationThread::run() Line 413 + 0x26 bytes osg35-osgd.dll!osg::GraphicsThread::run() Line 40 ot10-OpenThreadsd.dll!OpenThreads::ThreadPrivateActions::StartThread(void * data=0x0202fe78) Line 112 + 0xf bytes Thanks again, Wojtek -Original Message- From: Robert Osfield [mailto:[EMAIL PROTECTED] Sent: Saturday, May 10, 2008 6:18 PM To: [EMAIL PROTECTED]; OpenSceneGraph Users Subject: Re: [osg-users] Complete garbage in OSG / XP / multi monitor/multithreaded / NVidia Hi Wojciech, On Sat, May 10, 2008 at 4:23 PM, Wojciech Lewandowski [EMAIL PROTECTED] wrote: Realize in Producer::Viewer was usually explicitly called before entering update/event/cull/render loop. osgViewer::Viewer::Realize can still be called by user before main loop. I believe this makes first solution pretty tricky, one would need to sync return from Viewer::Realize with completion of GL compile operations. I don't know if this is simple task considering number of Threading modes. Actually osgViewer::Viewer::realize() is little different than the old Producer::CameraGroup::realize()/osgProducer::Viewer::realize() in terms of order of operations. osgViewer::Viewer::realize() will be called automatically on the first frame is it hasn't already been called by the user, so this is the only real