Trying to understand NEWT threading model

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Trying to understand NEWT threading model

ariekenb
I'm trying to understand the NEWT threading model using the RedSquare demo (https://github.com/sgothel/jogl-demos/blob/master/src/demos/es2/RedSquare.java)

If I run RedSquare with no command line arguments, it does the following:

1. Main creates one RedSquare and calls start on it.  This creates a thread named Thread-0.  Thread-0 runs RedSquare.run, which sits in a loop calling display() while the boolean quit is not true.  So RedSquare.display(GLAutoDrawable drawable) is continually being called from Thread-0.

2. RedSquare registers mouse and key listeners.  These listeners are invoked from the EDT created by NEWT for the display.  When I run this EDT is named Thread-0-Display-X11_:0.0-1-EDT.

Suppose the user hits the q key.  RedSquare.keyTyped will be invoked from the NEWT EDT (Thread-0-Display-X11_:0.0-1-EDT) and quit will be set to true.  Thread-0 in RedSquare.run will read quit and maybe if it is lucky see that it is true, but this is not guaranteed by the java memory model.  At the very least I think quit should be volatile.

So I am a bit confused by this example because it seems to be not very thread safe.  What is the recommended model for handling key/mouse events in NEWT and handling them in a thread safe way?  Setting non-synchronized variables and hoping for the best does not seem like a good idea. :)

I am used to the normal Swing/AWT model of all events and paint() actions being run from the AWT EDT.  The difference in this NEWT example is display() is being called from some other thread, while key and mouse events come in from the NEWT EDT.  Is there a way to have all rendering in NEWT happen in the NEWT EDT?  I suppose I could use com.jogamp.newt.Display.getEDTUtil().invoke() to do rendering - is this recommended?
Reply | Threaded
Open this post in threaded view
|

Re: Trying to understand NEWT threading model

Sven Gothel
Administrator
On Saturday, November 27, 2010 15:18:57 ariekenb [via jogamp] wrote:
>
> I'm trying to understand the NEWT threading model using the RedSquare demo (https://github.com/sgothel/jogl-demos/blob/master/src/demos/es2/RedSquare.java)
>

Try these here .. :)

http://jogamp.org/git/?p=jogl.git;a=tree;f=src/junit/com/jogamp/test/junit/newt

They are the actual NEWT unit tests, with lifecycle and threading tests,
assert tests on most behaviors.

> If I run RedSquare with no command line arguments, it does the following:
>
> 1. Main creates one RedSquare and calls start on it.  This creates a thread named Thread-0.  Thread-0 runs RedSquare.run, which sits in a loop calling display() while the boolean quit is not true.  So RedSquare.display(GLAutoDrawable drawable) is continually being called from Thread-0.

yup, was a self animated test.

the above unit test use the animator and are more simple,
or let's say comprehensive - you are right.

>
> 2. RedSquare registers mouse and key listeners.  These listeners are invoked from the EDT created by NEWT for the display.  When I run this EDT is named Thread-0-Display-X11_:0.0-1-EDT.

yup EDT thread is kicked off with a name derived from it's parent for better comprehension.

>
> Suppose the user hits the q key.  RedSquare.keyTyped will be invoked from the NEWT EDT (Thread-0-Display-X11_:0.0-1-EDT) and quit will be set to true.  Thread-0 in RedSquare.run will read quit and maybe if it is lucky see that it is true, but this is not guaranteed by the java memory model.  At the very least I think quit should be volatile.

yup

>
> So I am a bit confused by this example because it seems to be not very thread safe.  
sorry :)

> What is the recommended model for handling key/mouse events in NEWT
well, the usual event listener model of course.

> and handling them in a thread safe way?  Setting non-synchronized variables and hoping for the best does not seem like a good idea. :)

thats a different question :)

you are right, should use some sort of memory barrier, or volatile, .. etc

eventually the memory gets synced .. then the app will stop,
lets call in a bit incorrect here .. but will work eventually.

>
> I am used to the normal Swing/AWT model of all events and paint() actions being run from the AWT EDT.  The difference in this NEWT example is display() is being called from some other thread, while key and mouse events come in from the NEWT EDT.  

You got it !

> Is there a way to have all rendering in NEWT happen in the NEWT EDT?  I suppose I could use com.jogamp.newt.Display.getEDTUtil().invoke() to do rendering - is this recommended?

That would remove all NEWT benefits in constrast to AWT.

Rendering in the EDT is a blocking dependency on the whole system.
Worse, AWT's EDT is one global lock.

NEWT's event module is pretty simple.
NEWT EDT's role is to handle:
 - input events
 - window lifecycle actions (window visibility, resize, .. etc)
 - _NOT_ rendering

Hight performance rendering is achieved without being blocked by input events
and the other way around, ie rendering does not disturb (lag) user input.
So you will have a much more fluent animation especially for more complex models.

For example we had to create NewtCanvasAWT, hooking a NEWT window natively to a AWT Canvas.
Enabling us to use both worlds, AWT/Swing UI and decoupled high performance rendering.

How to pass user input back to the rendering loop ?
  Shows you how to use a fifo to pipe events from the EDT (listener) to the rendering loop.

  http://jogamp.org/git/?p=jogl.git;a=blob;f=src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02NEWT.java;h=23e3e1c443bbb5551d86236e1fce96d2d4ec15e3;hb=HEAD#l111
  http://jogamp.org/git/?p=jogl.git;a=blob;f=src/junit/com/jogamp/test/junit/newt/parenting/KeyAction.java;h=4948ce9f4f7b0b6f8498b37a19dd63651bb88b5b;hb=HEAD


How to inject some GL action to the rendering loop ?
  Shows you how to inject GL render actions into a GL fifo from another thread.

  http://jogamp.org/git/?p=jogl.git;a=blob;f=src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cSwingAWT.java;h=fb2c744557c5b83eedfbea1d6e65d746bce5b03d;hb=HEAD#l207
  http://jogamp.org/git/?p=jogl.git;a=blob;f=src/junit/com/jogamp/test/junit/newt/parenting/GLRunnableDummy.java;h=2459c8687afed130d038760a1b94ff07ccc72f70;hb=HEAD#l39


We also have a way to write AWT agnostic input event listener:
  http://jogamp.org/git/?p=jogl.git;a=blob;f=src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/newt/TestGearsNEWT.java;h=d83deea4bccde0121b46ced0cf76dfbb17352a3e;hb=HEAD
  http://jogamp.org/git/?p=jogl.git;a=blob;f=src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java;h=3e7e5988ba3631486e18474ec56fdbcffd23028d;hb=HEAD

So in short .. we provide some utilities to make it happen.
These are not really necessary, ie you could use your own, just convenience.

The NEWT threading requirements are easy - they are just none for rendering,
and the input event listener should better not lock the rendering GL context.
They can (with GLContext.setSynchronized(true) etc .. but that would be a pitty performance wise.

Glad that you asks, I guess I should put this email to a tutorial/explanation for NEWT.

Cheers, Sven
Reply | Threaded
Open this post in threaded view
|

Re: Trying to understand NEWT threading model

ariekenb
Thanks for the explanation, that makes a lot more sense now.