Posted by
Marian Schedenig on
Aug 28, 2014; 9:23pm
URL: https://forum.jogamp.org/Rules-for-sharing-context-between-GLJPanels-tp4032950.html
I'm working on a level editor which I originally wrote with plain Java2D and later converted to JOGL.
The original Java2D implementation had several JPanels, a big one for actually editing a level and many small ones as level previews. Each panel was connected to the same instance of my ResourceManager class which held all the images (now textures) and knew how to paint itself when an update was necessary.
When I switched my game to JOGL, I quick-and-dirtily turned each of these panels into a GLJPanel, with its own ResourceManager (because instantiating the ResourceManager required a GL context). Aside from certainly wasting a lot of resources, this also makes things horribly slow when, while scrolling through the list of level previews, each panel that's displayed for the first time reads and initialises its textures.
I've therefore been trying to switch to a shared GL context which would be the home of the ResourceManager. It's been mostly trial and error and Google searches (the link on the GLJPanel Javadoc page that would presumably provide more info doesn't exist:
https://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/javax/spec-overview.html#SHARING).
Before creating any of my panels, I create an offscreen AutoDrawable and call display() on it. In its init() event callback, I initialise my ResourceManager. I then create my panels and set this AutoDrawable as the shared AutoDrawable. But my reshape() and display() method throw exceptions when they actually access GL objects, like this one:
Exception in thread "AWT-EventQueue-0" javax.media.opengl.GLException: Caught GLException: This GL object is being incorrectly used with a different GLContext than that which created it on thread AWT-EventQueue-0
at javax.media.opengl.GLException.newGLException(GLException.java:75)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1318)
at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1138)
at javax.media.opengl.awt.GLJPanel$OffscreenBackend.doPaintComponent(GLJPanel.java:1922)
at javax.media.opengl.awt.GLJPanel.paintComponent(GLJPanel.java:559)
at javax.swing.JComponent.paint(JComponent.java:1045)
[...]
Caused by: javax.media.opengl.GLException: This GL object is being incorrectly used with a different GLContext than that which created it
at javax.media.opengl.DebugGL4bc.checkContext(DebugGL4bc.java:29477)
at javax.media.opengl.DebugGL4bc.glUseProgram(DebugGL4bc.java:24132)
I do all my GL access in GLEventListener callbacks. The threads are indeed different - the offscreen drawable's init() runs on a non-AWT thread, and all the actual drawing calls seem to run on AWT threads.
I've tried to reproduce the issue with a simple test application. It creates a JFrame, initialises an offscreen drawable and two simple shaders, then creates two GLJPanels and sets the shared drawable. Each panel's display() method calls glUseProgram() and clears the panel with a different colour. But all this runs flawlessly.
The threads in the test tool are similar to those in the non-working editor: Non-AWT thread when initialising my resources, AWT thread for actual drawing operations.
Clearly I'm violating some rule about context sharing I'm not aware of. But so far I've been unable to even figure out where my broken editor significantly differs from my test tool.