[comp.sys.sgi] Stereo sync

certain@hatteras.cs.unc.edu (11/30/90)

I am try to get a stereo display program to work on an Iris.  The problem
that I am having is that to stereo plate flips between the left and right
eye at 60Hz, so I need to make sure that I am alternating eyes with each
buffer swap.  Unfortunately, swapbuffers() is non-blocking, so that if I
can actually draw faster than 120Hz, I get two updates per buffer swap,
which has the effect of always just showing one eye.  Is there a way to
make swapbuffers() to be blocking?  Is there a way to know when the screen
refresh happens?  What have other people done about this problem?  I have
just subscribed to this newsgroup, so I don't know if this problem has been
addressed previously.

Thanks,
	Andrew Certain
	UNC-CH Comp Sci.
	certain@cs.unc.edu

xiaoyan@ecf.toronto.edu (Yan Xiao) (12/01/90)

In article <17848@thorin.cs.unc.edu> certain@hatteras.cs.unc.edu () writes:
>I am try to get a stereo display program to work on an Iris.  The problem
>that I am having is that to stereo plate flips between the left and right
>eye at 60Hz, so I need to make sure that I am alternating eyes with each
>buffer swap.  Unfortunately, swapbuffers() is non-blocking, so that if I
>can actually draw faster than 120Hz, I get two updates per buffer swap,
>which has the effect of always just showing one eye.  Is there a way to
>make swapbuffers() to be blocking?  Is there a way to know when the screen
>refresh happens?  What have other people done about this problem?  I have
>just subscribed to this newsgroup, so I don't know if this problem has been
>addressed previously.

	What we do is to show two dots at lower corner of the screen, each
	one of them representing one field. To control the spectacles, we
	read these two dots via a light-sensor and a circuit.  It sounds not
	so smart, but the setup has been working just fine.

	We got a new monitor with a sync port at the back but no clue how to
	use that port.

xiao

certain@hatteras.cs.unc.edu (Andrew Certain) (12/03/90)

In article <1990Nov30.172515.26299@ecf.utoronto.ca> xiaoyan@ecf.toronto.edu (Yan Xiao) writes:
>
>	What we do is to show two dots at lower corner of the screen, each
>	one of them representing one field. To control the spectacles, we
>	read these two dots via a light-sensor and a circuit.  It sounds not
>	so smart, but the setup has been working just fine.
>
>	We got a new monitor with a sync port at the back but no clue how to
>	use that port.
>
>xiao

We have a passive-glass system, so that there is a plate that we put in front
of the monitor which polarizes the light coming from the screen, switching
directions at 60Hz.  The glasses are just polarized lenses so that each eye
only gets light every other cycle.  So I need to know when the buffers have
swapped (and, hence, the plate has flipped eyes), so that I can start drawing
the other eye.

Andrew

thant@horus.esd.sgi.com (Thant Tessman) (12/04/90)

In article <17848@thorin.cs.unc.edu>, certain@hatteras.cs.unc.edu writes:
> I am try to get a stereo display program to work on an Iris.  The problem
> that I am having is that to stereo plate flips between the left and right
> eye at 60Hz, so I need to make sure that I am alternating eyes with each
> buffer swap.  Unfortunately, swapbuffers() is non-blocking, so that if I
> can actually draw faster than 120Hz, I get two updates per buffer swap,
> which has the effect of always just showing one eye.  Is there a way to
> make swapbuffers() to be blocking?  Is there a way to know when the screen
> refresh happens?  What have other people done about this problem?  I have
> just subscribed to this newsgroup, so I don't know if this problem has been
> addressed previously.

gsync() might be what you need, at least to block on a refresh.

thant

xiaoyan@ecf.toronto.edu (Yan Xiao) (12/04/90)

In article <17895@thorin.cs.unc.edu> certain@hatteras.cs.unc.edu (Andrew Certain) writes:
>
>We have a passive-glass system, so that there is a plate that we put in front
>of the monitor which polarizes the light coming from the screen, switching
>directions at 60Hz.  The glasses are just polarized lenses so that each eye
>only gets light every other cycle.  So I need to know when the buffers have
>swapped (and, hence, the plate has flipped eyes), so that I can start drawing
>the other eye.
>
>Andrew

I don't quite understand your system.  Can't you just draw two dots on
the screen, each representing an eye's view?  Whenever the buffer swaps,
you light up a cooresponding dot?

xiao

mg@ (Mike Gigante) (12/04/90)

I believe that Andrew Certain's problem can be solved with the routine
`swapinterval', it sets the *minimum* no. of vertical retraces b/n swapbuffers.

As long as you *know* that your drawing will be finished by
the interval you specify you will stay in sync. (Otherwise, you may get
a left<->right switch!)

On gsync, I don't understand Thant Tessman's comment -- surely a swapbuffer
doesn't happen until a vertical retrace anyhow -- so the gsync is redundant
right?

Mike
mg@godzilla.cgl.rmit.oz.au

mds@sgi.com (Mark Stadler) (12/04/90)

In article <1990Dec3.181548.5300@odin.corp.sgi.com> thant@horus.esd.sgi.com (Thant Tessman) writes:
>In article <17848@thorin.cs.unc.edu>, certain@hatteras.cs.unc.edu writes:
>> I am try to get a stereo display program to work on an Iris.  The problem
>> that I am having is that to stereo plate flips between the left and right
>> eye at 60Hz, so I need to make sure that I am alternating eyes with each
>> buffer swap.  Unfortunately, swapbuffers() is non-blocking, so that if I
>> can actually draw faster than 120Hz, I get two updates per buffer swap,
>> which has the effect of always just showing one eye.  Is there a way to
>> make swapbuffers() to be blocking?  Is there a way to know when the screen
>> refresh happens?  What have other people done about this problem?  I have
>> just subscribed to this newsgroup, so I don't know if this problem has been
>> addressed previously.
>
>gsync() might be what you need, at least to block on a refresh.
>

it is true that swapbuffers() is non-blocking, but only until you attempt to
perform the next graphics operation.  if you issue a swapbuffer() command,
then you are free to go off and do some number crunching, or update internal
data structures etc... but once you attempt to do the next graphics command,
your process will block until the pending swapbuffer() completes.  if you
issue a swapbuffer() command and immediately follow it with any other
graphics command you will hang until the swapbuffer is complete.  i think
i'm getting repetetive.  anyway, i wish i could help explain what your problem
really is.  all i can say that it has nothing to do with non-blocking swapbuffer().

by the way, gsync() (in the near future) will also be non-blocking, so don't
count on it for absolute times.  it will block only block if you attempt to
do another graphics command before the next vertical retrace.

--
-- mds	[aka Mark D Stadler  mds@sgi.com  ...!uunet!sgi!mds  (415)335-1327]

certain@aesop.cs.unc.edu (Andrew Certain) (12/05/90)

I admit it:  I was wrong.  My problem was more complex.  I have
realized that swapbuffers indeed does block once you try to do a
graphics call.  I have discovered that my problem was that although
usually my program could draw the scene in 1/60th of a second,
sometimes it wouldn't, and the eye would switch.  I can't use
swapinterval because the plate we have switchs at 60Hz on its
slowest setting.  I guess we're going to have to go to a different
stereo system like one with active glasses, since, no matter
how simple the scene is that you're drawing, it is always
possible that somebody will grab the processor for long enough
to cause a left-right switch.  Do people have recommendations on
stereo systems?  What about StereoView?

On a slightly different note, I called m_set_procs to set the
number of procedures on an m_fork to three and ran my program
and was interested to see that, using gr_osview, all four
processors we being used to a non-negligible(sp?) extent?
Why does this happen?  I think the same thing happens if I set
it to two....

Andrew Certain
certain@cs.unc.edu

osmoviita@cc.helsinki.fi (12/06/90)

                                                                               ) writes                                                                                Thant Tessm                                                                             
                                                                                                                                                              > by the way, gsync() (in the n                                                                  
                                                        327]                                                                                                                                                                                                   
                                                            |
1) function which swaps buffers only between the stereo pairs but not between
fields of the same stereo pair
2) function which swaps whenever a vertical retrace occurs.

Is there some way to achieve both functions?

Kari Osmoviita

thant@horus.esd.sgi.com (Thant Tessman) (12/07/90)

In article <mg.660259402@godzilla>, mg@ (Mike Gigante) writes:
> 
[...]

> On gsync, I don't understand Thant Tessman's comment -- surely a swapbuffer
> doesn't happen until a vertical retrace anyhow -- so the gsync is redundant
> right?

The act of swapbuffering itself only happens on the vertical retraces.  The 
old swapbuffer used to freeze the program thread until that happened.  The 
new swapbuffer actually allows the program to continue as long as it doesn't
draw into the same context.  This allows swapbuffers to be ganged up.  A 
program that had three windows used to be limited to 3/60 of a second per 
update cycle assuming a swapbuffers was called for all three windows.  Now
the whole thing is only limited to 1/60 of a second if I understand it
correctly.

A call to 'gsync' would force the program to wait.  It isn't clear that 
this was the source of the original problem.  But I thought I'd mention
it.


> Mike
> mg@godzilla.cgl.rmit.oz.au

thant

bam@sgi.com (Brian McClendon) (12/07/90)

In article <1990Dec6.194603.7016@odin.corp.sgi.com> thant@horus.esd.sgi.com (Thant Tessman) writes:
>
>The act of swapbuffering itself only happens on the vertical retraces.  The 
>old swapbuffer used to freeze the program thread until that happened.  The 
>new swapbuffer actually allows the program to continue as long as it doesn't
>draw into the same context.  This allows swapbuffers to be ganged up.  A 
>program that had three windows used to be limited to 3/60 of a second per 
>update cycle assuming a swapbuffers was called for all three windows.  Now
>the whole thing is only limited to 1/60 of a second if I understand it
>correctly.
>
>A call to 'gsync' would force the program to wait.  It isn't clear that 
>this was the source of the original problem.  But I thought I'd mention
>it.
>
>
>thant


On the VGX, 'gsync' acts just like swapbuffers(), only hanging the program
when it tries to access gfx in the same window.  This seems to do everything
we could imagine gsync used for, but is slightly different from what
might be expected.   Any comments on how you _want_ it to work?

--
----------------------------------------------------------------------------
 Brian McClendon bam@rudedog.SGI.COM ...!uunet!sgi!rudedog!bam 415-335-1110
** Legalize drugs! **                                            ** RU486 **
----------------------------------------------------------------------------

vjs@rhyolite.wpd.sgi.com (Vernon Schryver) (12/08/90)

In article <17956@thorin.cs.unc.edu>, certain@aesop.cs.unc.edu (Andrew Certain) writes:
> I admit it:  I was wrong.  My problem was more complex.  I have
> realized that swapbuffers indeed does block once you try to do a
> graphics call.  I have discovered that my problem was that although
> usually my program could draw the scene in 1/60th of a second,
> sometimes it wouldn't, and the eye would switch....

Could you use gettimeofday(2) or (better to avoid adjtime(2) effects)
times(2) to read the system clock, divide the resulting timestamp by a
number related to 1/60th sec, and depending on the remainder, use sginap(2)
or select(2) to delay a little to get back into sync?  Or maybe just do an
extra swapbuffer to delay?  Or instead of delaying, skip forward to the
correct frame?  If the cause is infrequent enough to make the resulting
artifacts unobjectionable?


Vernon Schryver,   vjs@sgi.com