Handling window events when using a dedicated OpenGL thread

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

Handling window events when using a dedicated OpenGL thread

Peter F
Hello,

I've been converting my program from one threading model to another & have some questions about some behaviour I'm getting regarding window events.

My Question:

The window is no longer automatically prompted to repaint on window events such as when another window moves over mine ( the buffer is left contaminated with the window that moved over it ), I can no longer close the window using the X icon and resizing the window does not result in a call to GLEventListener.reshape(..).

I gather this is because I have the GLContext current on a Thread of mine on a permanent basis ( see background below for more info ) and the NEWT EDT is waiting on it to become free? When I tried releasing the context for other threads then window closing & resizing worked again - but the window could still be contaminated by other windows moving over it, so I'm still missing something here.

How should I interact with window events like these when running with a dedicated OpenGL Thread? Does JOGL/NEWT have one that I should be using instead?


Background Info:

My old model was one where a task executor would fire based off a Thread Pool using scheduleRunnableAtFixedRate with a target FPS rate. This runnable would do a full cycle of executing UI events, animations and then executing all rendering code with the GLContext made current. At the end of the cycle it would release the GLContext - free until the next execution.

My new model uses a dedicated Thread from a pool, with the GLContext made current permanently to save on the context switching overhead. This GL task thread uses a LinkedBlockingQueue to receive tasks from other threads ( loading, unloading, rendering on/off screen etc ).

The idea is that I can have other UI threads handle events, long processes, handle non-GL related updates etc & then post synchronous or asynchronous tasks to the OpenGL Thread - depending on the situation. This frees the GL thread to only run GL related code.

It also enables me to buffer a batched, optimised set of rendering calls on a non-gl thread to pass to the OpenGLThread as a task when it's ready - while the OpenGLThread is drawing the frame previously submitted & doesn't have to optimise the frame itself - all it has to do once the app is loaded is execute batch optimised draw tasks.


I hope this has made some sense - I'm open to any ideas / concerns about my newer model - I imagine its something you've all seen before & any pointers are welcome!

Kind regards & thanks,

Pete.
Reply | Threaded
Open this post in threaded view
|

Re: Handling window events when using a dedicated OpenGL thread

gouessej
Administrator
Hi

Rather use GLAutoDrawable.invoke(boolean, GLRunnable) if you need to execute something that requires a current OpenGL context. In my humble opinion, your design is overcomplicated, it doesn't make sense to me. If you reinvent the wheel, you'll be alone with your bugs because you'll have to reinvent our fixes too. NEWT is very flexible and the documentation tells you which methods have to be called on another thread than the EDT. When you don't need a current OpenGL context, don't use the EDT. You can create some threads to handle the tasks that don't need the UI and OpenGL but you don't have to create a thread to do what NEWT already does pretty well.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Handling window events when using a dedicated OpenGL thread

Peter F
Thanks for the information and you're quite right I don't want to re-invent the wheel - I do tend to go off on a tangent sometimes & make life difficult for myself... I would much rather use something tried & tested written by people more intelligent than I - my issue is I haven't done enough to learn about NEWT's threading model for which I humbly apologise.

To work with NEWT's Threading model, do I:

A)
Setup an Animator to handle calling GLWindow.display() in a loop, and within the execution of display() do any rendering work my producer Threads have produced & end with a call to GLAutoDrawable.swapBuffers() if I have new content to show - where I've set GLWindow.setAutoSwapBufferMode( false ) ?

B)
Not use an animator, and instead use GLAutoDrawable.invoke(boolean, GLRunnable) from my producer threads directly & in the case of a frame update return true in the GLRunnable implementation to signal I want a GLWindow.display call - where I have set GLWindow.setAutoSwapBufferMode( true ) ?

Or neither of these because I'm still missing the point :(

Thank you very much for your help & time! It's much appreciated to be able to get support like this.
Reply | Threaded
Open this post in threaded view
|

Re: Handling window events when using a dedicated OpenGL thread

gouessej
Administrator
You're welcome. There is no silly question, don't hesitate to ask anything about NEWT.

You can use an animator (preferably Animator instead of FPSAnimator) so that GLAutoDrawable.display() will be called, leave the auto swap buffer mode unchanged (enabled by default) and call GLAutoDrawable.invoke(boolean, GLRunnable) from your producer threads when they need to modify something requiring a current OpenGL context (for example to update a VBO). However, you seem to wish a tight control on the update, don't call GLAutoDrawable.display() in GLAutoDrawable.invoke(boolean, GLRunnable), just call GLAutoDrawable.display(), it should be enough but then you don't need an animator. The solution B is close to what seems to fit into your need.

P.S: Use an engine if you don't really want to drive things more complicated than they need to be, that's why they exist.
Julien Gouesse | Personal blog | Website