Solution for multithreaded opengl problem

I saw on Mark, or Joshua blog that they had some trouble finding a solution for the multitasking opengl problematics.

My answer for the problematics sounds for me to be too easy, so it properly creates another problem or not possibly anyway.



Why not make the lock/unlock methods use a global lock. And every thing there needed to be done in the opengl class should call this global lock and unlock.



Of course this means most of the classes needs to be search through, and get a GlobalLocker.lock() / GlobalLocker.unlock() in some places, but this would solve all the troubles.

The only problem I see is if it would be called too many times per second.



It sounds bizarre for me, so please reply if its possibly?
Not working :frowning:



If not possibly, I would suggest ALL to come with their idea’s here - since I haven’t seen any other posting about this very big problem.





Teaster.

It wouldn't work. You need to run the code in the rendering thread, locking it and then running some code in a different thread won't help.

Perhaps in Java 7 we will have closures and then you wouldn't have the mess of implementing Callable and such.

That's already part of JME :smiley:

Seriously:

http://www.jmonkeyengine.com/wiki/doku.php?id=simplegame_to_standardgame

Search for lock() and unlock().

That should do what you want.

Momoko_Fan said:

It wouldn't work. You need to run the code in the rendering thread, locking it and then running some code in a different thread won't help.
Perhaps in Java 7 we will have closures and then you wouldn't have the mess of implementing Callable and such.
:( this makes me even more confused when developing games. And java 7 is only in beta now - release scheduled to 2009(late because of the open sourcing problematics)
Very depressing!


pflanzenmoerder said:

Seriously:
http://www.jmonkeyengine.com/wiki/doku.php?id=simplegame_to_standardgame
Search for lock() and unlock().
That should do what you want.
I already know all this, but I got troubles finding out when something should be in the opengl thread, there is only a page on wiki where you can see this - pretty annoying.

I am working on a idea will post it if it comes to anything.
Else anyone else please post your ideas!

Multithreading is never easy. Aside from having issues when calling methods outside of opengl thread there are also concurrency issues when working with the same data from many different threads.



None of the objects in jme are really thread-safe. When you are working with the scene graph that is being rendered, you should only modify that scenegraph inside the openGL thread. Because even if you wont get openGL thread problem, you can get data corruption due to concurrent access.



When it comes to multithreading there no easy magic solution. The only way to make scenegraph thread-safe is to make many methods synchronized (or use some other concurrent access solution), but that would make it very slow.

lex said:

Multithreading is never easy. Aside from having issues when calling methods outside of opengl thread there are also concurrency issues when working with the same data from many different threads.

None of the objects in jme are really thread-safe. When you are working with the scene graph that is being rendered, you should only modify that scenegraph inside the openGL thread. Because even if you wont get openGL thread problem, you can get data corruption due to concurrent access.

When it comes to multithreading there no easy magic solution. The only way to make scenegraph thread-safe is to make many methods synchronized (or use some other concurrent access solution), but that would make it very slow.
I would really like to use multi threading for explore new possibilities with multicores.

I worked on another solution which might work ( As you can hear, I'm very desperate to get this *fixed* )

What about create a static variable in the  com.jme.renderer.lwjgl.*
Which contains a Thread variable(The thread which is the opengl)
Every call to the com.jme.renderer.lwjgl.* will need to check if Thread.CurrentThread equals the same thread, if its not cast a Exception, cast A warning, or do it automatic with the GameTaskQueueManager.

Can it be done?  :?

Teaster.

If you try to make a GL call outside the opengl thread you will just get a NullPointerException, thus it is useless to make the renderer methods throw an exception because the result is the same.

Splitting GL calls into multiple threads would be useless since only one thread could make a call at a time.  Essentially, instead of one thread going A B C D, you will have two threads going A wait… C wait… and wait… B wait… D respectively.  It would be a lot of work for a loss of performance.  There is no point multi threading something that requires a lock for every operation.



If you want to use multi threading, then code it into your game.  There are many candidates for threading, and GL calls are not one of them.  Split IO, networking, AI, physics, logic etc into their own threads if you want.

Momoko_Fan said:

It wouldn't work. You need to run the code in the rendering thread, locking it and then running some code in a different thread won't help.

This actually is not the main problem. LWJGL can switch the OpenGL context to another thread if told (not that i expect that it would do it fast). The problem is that OpenGL is a state machine, and you cannot just throw at it commands from multiple threads. So setting some textures expects that you will be drawing objects with those textures, and not something other from another thread. This is extreme example, but it stand for lots of functionality that is in jME.

A more multithreading friendly design would imply the removal of LWJGL dependency from wherever it could be removed.

Clear separation of load/setup functionality from drawing functionality. Setting up objects can be done mulithreaded. After you load a texture from file or create a VBO, it is unimportant what you will be doing next. Creating textures or VBO-s can be done mutithreaded by creating another OpenGL context in the other thread. Those objects are then shared between every context. Drawing has to be done in (some) order. Front-to back, or sorted some other way. It is best done in a single thread, in a tight loop.

Real multithreaded drivers are still buggy and unpredictable. Until manufacturers fix them, we are left with a single pipe to the graphic card anyway.

I my view, solution to multithreadedness (what a word  :-o) is not making the threads synchronize better with each other, but making them more independent of each other.

Have added an asynchronous queing system into the llama terra demo. ( see the thread http://www.jmonkeyengine.com/jmeforum/index.php?topic=5170.msg57118#new )



It touches on what Momoko mentioned, in particular that the many steps needed to create an object can be split between in the open gl thread and out the opengl thread.



The queue system allows steps to be performed outside and inside the opengl thread. it does this by way of creating tasks that are started outside the opengl thread, if opengl thread invocation is required, then the main task is suspended and a scene task is completed inside the opengl thread, this in turn notifies the original task to continue work.



Its early days, but you may be interested to see it working