Thanks Robert. I did a quick test with two viewers from two threads and it appears to be working. Btw, from my experience, PBO doesn't seem to be any faster (and on some hardware much slower) for downloading textures to host than glReadPixels, while for uploads it is almost consistently faster. Anyway, that should not be a problem, even to code it manually.

One question about the OpenGL driver, are you by any chance aware of any threading issues? Is it completely re-entrant from two different contexts and threads? With this two-thread setup, I see some occasional erratic fluctuation in drawing time in the osg performance hud for a completely still scene. The GPU performance is very stable, regardless of the load on the other card, but the drawing time (software) sometimes goes from something like 0.4 to 2.6 or 1.5 for a couple of frames. I do not notice this, or not as much, when using two separate processes instead of two threads. The only difference I can think of here is that the OpenGL driver part is in the same address space and maybe internally locks occasionally? Or is this nonsense?

Anyway, the osg part seems to be fairly straightforward and simple like this. Thanks.


Robert Osfield wrote:
Hi Ferdi,

osgViewer::CompositeViewer runs all of the views synchronously - one
frame() call dispatches update, event, cull and draw traversals for
all the views.  So for you case where you want them to run async, this
isn't supported.  Supporting within CompositeViewer would really
complicate the API so it's not something I gone for.

What you will be able to do is use two separate Viewer's.  You are
likely to want to run two threads for each of the viewers frame loops
as well.  To get the render to image result to the second viewer all
you need to do is assign the same osg::Image to the first viewer's
Camera for it to copy to, and then attach the same osg::Image to a
texture in the scene of the second viewer.  The OSG should
automatically do the glReadPixels to the image data, dirty the Image,
and then automatically the texture will update in the second viewer.
You could potentially optimize things by using an PBO but the off the
shelf osg::PixelBufferObject isn't suitable for read in this way so
you'll need to roll you own support for this.

It's worth noting that I've never written a app like the above, so you
are rather working on the bleeding edge.  I "think" it should work, or
at least I can't spot any major problems that might appear.

Robert.

On Mon, Nov 17, 2008 at 9:37 AM, Ferdi Smit <[EMAIL PROTECTED]> wrote:
I'm looking to do the following in OSG, and I wonder if I'm on the right
track (before wasting time needlessly): have two render processes run in
parallel on two different GPUs, have one render a scene to texture and let
this texture be read by the other process and mapped to an object in a
different scene. Problem, the rendering of the first scene to texture is
very slow and the rendering of the second scene is very fast.

I intend to solve it in the following way in pseudo-code:

- new CompositeViewer
- Add two Views
- Construct two contexts, one on localhost:0.0, one on localhost:0.1
- Attach contexts to cameras of corresponding Views
- Set composite viewer threading mode to thread-per-context

--- First process
- Set view camera mode to FBO and pre-render
- Add post-draw callback and render textures
- Download texture to host memory in post-draw callback
- (possibly add post-render camera to render textured screen quad as output)

--- Second process
- Add update-callback and regular texture
- Upload host memory to texture in update callback (if available,
non-blocking)

The downloading and uploading of textures uses multiple slots and regular
threaded locking, so to ensure we never read or write the same memory at the
same time. The second process doesn't block if no new texture is available,
it just continues using the old one then.

Some questions. Will the two processes now run at independent frame rates,
or will the composite viewer synchronize them? I need them to run
independently. I read OSG does not support multi-threaded updating of the
scene graph. However, if I use two distinct scene graphs with two contexts,
I can _pull_ updates in an update callback from another thread, right? What
I can not do is push updates at arbitrary times; that would make sense. How
do I make the TrackballManipulator work for only the first process? It seems
that as soon as I set that camera to FBO it just doesn't respond to events
(or maybe something else is wrong...  I added another orthogonal camera to
the view1->getCamera() that renders the screenquad in post-render mode).
Also, the second process camera is affected when I move the mouse in the
first process window. Is it sufficient to call
view2->getCamera()->setAllowEventFocus(false); to disable this behavior?
Finally, can I do this the same way with a shared context on a single GPU
(i.e. both on :0.0) sharing texture data directly on the GPU in different
textures? Ignoring the slow context switching issues for the time being.

Am I one the right track here, or should this be done differently? I know
all this is possible because I have the manual OpenGL code for it working,
both using shared contexts and with up/downloading of texture data.

--
Regards,

Ferdi Smit
INS3 Visualization and 3D Interfaces
CWI Amsterdam, The Netherlands

_______________________________________________
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


--
Regards,

Ferdi Smit
INS3 Visualization and 3D Interfaces
CWI Amsterdam, The Netherlands

_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to