Calling Display from different Threads

Started by Slashy, April 27, 2014, 12:40:51

Previous topic - Next topic

Slashy

Hi all!

This is my first post. I've searched for the answer to my question exhaustively and could not find the answer.
So here it is:

I'm running my openGL Display in a thread.
I want to call GL11.glClearColor(1.0f, 0.0f, 0.0f, 0.0f), to change the background color, from a different thread (the one linked to a Swing checkbox).
I get this error:
"Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: From thread Thread[AWT-EventQueue-0,6,main]: Thread[main,5,main] already has the context current"

Please, please help. Its driving me crazy.
I'm reading up on concurrency and synchronization but I just can't figure it out.

Thanks in advanced!

Slashy

Cornix

The OpenGL context can not be shared between threads.
You have 2 options:
1) You make the context current in your second thread, do all your openGL function calls and then make the context current in your openGL thread again.
This is very slow, and of course, while the context is current in your second thread your main openGL thread has to wait.

2) Just let the OpenGL thread do all OpenGL-related function calls. You could, for example, have a synchronized list of actions which is shared across threads.
All threads can enque actions in this list but only the OpenGL thread will execute them one after the other.

quew8

OpenGL is a single threaded API. Each OpenGL context can only be "current" on one thread at a time, which means that if you try to call any OpenGL methods from another thread that'll happen.

Solution:
There are actually two solutions for this but I'm only going to give you the simple one because A) it's simpler B) I think it's more appropriate for your purposes C) it's simpler to explain. So essentially use an event queue system. When you are on another thread, add the OpenGL commands you want to call to a list (probably just as a Runnable instance). Each loop on your main thread, loop through this list, run them all and clear the list.

The other thing (which I'm calling equivalent because it is essentially the same) is to create a little state machine which stores all the states you need to change (such as the clear colour) and also when it has been changed. As before you change this state machine on the Swing thread and then actually do the changes in the OpenGL thread.

Anything unclear about my response don't hesitate to ask.

Edit: Sorry @Cornix. I repeated what you said. Didn't notice you had posted.

Slashy

Thank you both for the response. By the looks of things I'll end up implementing the synchronized list option.

Though I would like to know why I can't get the Swing thread to get the GL context.
I'm trying with the Display.makeCurrent() command but its simply not working.
I've tried using simple locks and fences but that doesn't seem to make much difference.