A light weight system for running jobs in the main thread during cull Transient Jobs run once and are removed unless the getKeep flag is true The general goal of the system is to try and keep frame rates smoother by shuttling graphics work from the cull thread to the main thread and trying to get it done ASAP.
More...
Public Member Functions |
| | DtMainThreadJobsManager () |
| virtual | ~DtMainThreadJobsManager () |
| | DTOR.
|
| virtual void | operator() (osg::Object *obj) |
| | operation function that core osg code calls every frame.
|
| virtual void | startUp () |
| virtual void | release () |
| | lets the jobs system know to exit ASAP
|
| void | setIco (osgUtil::IncrementalCompileOperation *ico) |
| | sets the pointer to the ico, may or may not exist
|
| virtual void | addPersistantJob (osg::Operation *job) |
| | add an operation that will run every frame in the main thread while the cull thread is happening.
|
| virtual void | removePersistantJob (osg::Operation *job) |
| | removes an operation that was running in the main thread while the cull thread is happening.
|
| virtual void | addTransientJob (osg::Operation *job) |
| | adds a jobs for doing work during cull see class doc for DtMainThreadJobManager for more detains
|
| int | getNumberOfTransientJobs () |
A light weight system for running jobs in the main thread during cull Transient Jobs run once and are removed unless the getKeep flag is true The general goal of the system is to try and keep frame rates smoother by shuttling graphics work from the cull thread to the main thread and trying to get it done ASAP.
The best way to think of it as TBB parallel task for the main render thread. It allow us to do arbitrary ICO like tasks without using the ICO infrastructure. Currently it's being used it to speed up texture streaming from indirect: This is pretty much a "simple" multi-threaded producer consumer system where the jobs system will wait till it has work to do and wake up.Currently the ICO can wake it up, or directly adding a transient job. This avoids a spin loop wasting a core. The system also tries to stop doing jobs as soon as cull is done. There are a number of different job types : *Persistent Jobs are added once and happen at the beginning of the job update. *Transient Jobs, they typically only happen once and get deleted, but they can also adjust the _keep value with setKeep(), which allows them to get added once and run for a few frames till completion. *The ICO runs after the Transient jobs,The ico can run multiple times if cull isn't finished yet. *Currently there's no guarantee that a job will run in a given frame... could revisit in the future. *When writing new code that does work in draw implementation it's worth thinking about if it could be moved into a job and run after cull.
IMPORTANT: Linux uses the pthread API, which requires that locks are acquired before any call to Condition::wait or Condition::signal. Failing to properly acquire the lock before these calls can result in deadlock
How to subclass a job class DtIndirectTextureProcessorJob : public osg::Operation { public: DtIndirectTextureProcessorJob(DtIndirectTextureProcessor * proc) : osg::Operation("indirect_texture_processor", false), myProcessor(proc) { ; } virtual void operator () (osg::Object * sv) { osgUtil::SceneView* sceneView = dynamic_cast<osgUtil::SceneView*>(sv); myProcessor->collectCompiledTextures(sceneView->getRenderInfo()); // could change this dynamically depending on the type of job setKeep(false); }
DtIndirectTextureProcessor * myProcessor; };
How to run a job in cull visitor DtOsgCullVisitor* dtcv = dynamic_cast<DtOsgCullVisitor*>(cv); DtOsgRenderer* renderer = dynamic_cast<DtOsgRenderer*> (&(dtcv->de().renderer())); renderer->addMainThreadJob(new DtIndirectTextureProcessorJob(this));