Multi-scene-manager and UB

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
crousser
Gnoblar
Posts: 12
Joined: Tue Dec 18, 2007 2:05 pm

Multi-scene-manager and UB

Post by crousser »

Hello all...
Sorry for my bad English :)
In the project we use more than two active RenderTargets (vieports) associated with different scene managers .
In release build (sometimes) application has crashed.
In debug build - a see asserts in QueuedRenderableCollection::addRenderable()
Error inserting new pass entry into PassGroupRenderableMap
I was shoked :shock: . It's meens something make invalide map-conteiner (make modiffication of Pass-object without before erase Pass from mGrouped)
I tried to find what the problem is.
This diagram show of the most important functions call:

Code: Select all

OgreRoot::renderOneFrame()
             |
             |
             +->RenderTarget::update()
                       |
                       |
                       +->SceneManager::_renderScene()
                                    |
                                    |
                                    +-->ControllerManager::updateAllController()
                                    |                     |
                                    |                     |
                                    |                     +-->Pass::_dirtyHash()
                                    |                                 |
                                    |                                 +-> ...msDirtyHashList.insert(Pass* p)
                                    |                     
                                    +-->prepareRenderQueue()
                                    |            |         
                                    |            |         
                                    |            +-->RenderQueueGroup::clear()
                                    |            |         |
                                    |            |         +--...->QueuedRenderableCollection::removePassGroup(Pass* p)
                                    |            |                               |
                                    |            |                               |
                                    |            |                               +--> ... mGrouped.erase(Pass* p)
                                    |            |          
                                    |            |          
                                    |            +-->Pass::processPendingPassUpdates();
                                    |                       |           
                                    |                       |           
                                    |                       +->Pass::_recalculateHash();
                                    |                       |           
                                    |                       |  
                                    |                       +-> .. msDirtyHashList.clear();
                                    |
                                    |
                                    +-->... RenderQueue::processVisibleObject()
                                                         |
                                                         |
                                                         +--> ...QueuedRenderableCollection::addRenderable()
                                                                         |
                                                                         +--> ... mGrouped.insert(Pass* p)

In case when we use more than two scene-mamngers:

1) ControllerManager::updateAllController() - can modiffiy any Pass (even that which is contained in other scene-manager the yet to be processed), and mark it insert to global msDirtyHashList
2) Try to erase dirty Pass, but if Pass-object does not belong to current scene-manager we have a problem, because
3) Call recalulate hash for dirty Pass-object (remember - owner of it other scene-manager)
4) In each iteration for render target (scene-manager in my case) - msDirtyHashList was cleanup. :? That means - for next iteration, for other scene-manager we are lose Passes for erase from mGrouped map-container. But call recalculateHash previously, it is still all the spoils

use ogre version 1.7.2

I have some question - the problem is still present in the new version? What are the solutions without modifying the core? We use a number of scene-managers to be able to display the main-scene with 3d object and location-map (game radar etc.)
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 219

Re: Multi-scene-manager and UB

Post by scrawl »

I believe this was fixed in 1.8.
crousser
Gnoblar
Posts: 12
Joined: Tue Dec 18, 2007 2:05 pm

Re: Multi-scene-manager and UB

Post by crousser »

scrawl wrote:I believe this was fixed in 1.8.
It is interesting how? I have 1.8.1 source an don't see any fix (diffs for fix). Please, can you give me a some refs for this?
There is ControllerManager::updateAllController() call, and msDirtyHashList still static container (global-list)
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 219

Re: Multi-scene-manager and UB

Post by scrawl »

Actually it seems that this problem still exists, see bug report: https://ogre3d.atlassian.net/browse/OGRE-89
Since 1.8, the new terrain system no longer triggers this bug, so I thought that it was fixed, but apparently it's just worked around.

Maybe try using the workaround mentioned here:

Code: Select all

// in frameStarted
sm1->getRenderQueue()->clear();
sm2->getRenderQueue()->clear();
.. all other SMs
Pass::processPendingPassUpdates();
crousser
Gnoblar
Posts: 12
Joined: Tue Dec 18, 2007 2:05 pm

Re: Multi-scene-manager and UB

Post by crousser »

scrawl wrote:Actually it seems that this problem still exists, see bug report: https://ogre3d.atlassian.net/browse/OGRE-89

Maybe try using the workaround mentioned here:

Code: Select all

// in frameStarted
sm1->getRenderQueue()->clear();
sm2->getRenderQueue()->clear();
.. all other SMs
Pass::processPendingPassUpdates();
no no, what about call of ControllerManager::updateAllController() ? This call make marking Pass to dirtyHash inside Root::renderOneFrame, and Your advice does not helps (in 1.7.2)