Bug 572 - Calling invoke(true,GLRunnable) on several GLCanvases in the same container causes a deadlock
Summary: Calling invoke(true,GLRunnable) on several GLCanvases in the same container c...
Status: RESOLVED FIXED
Alias: None
Product: Jogl
Classification: JogAmp
Component: core (show other bugs)
Version: 2
Hardware: pc_all linux
: --- major
Assignee: Sven Gothel
URL:
Depends on:
Blocks:
 
Reported: 2012-04-02 17:15 CEST by Julien Gouesse
Modified: 2012-10-05 22:02 CEST (History)
2 users (show)

See Also:
Type: ---
SCM Refs:
jogl c066dc997646643a98c35b7c70183930284544d1 jogl a3cb6bb14f410f67fccf5ccd4cd7ecc66f448389
Workaround: ---


Attachments
Ardor3D JOGL2 Patch Fix GLContext makeCurrent/release imbalance / commented-out workaround for old JOGL bug (7.64 KB, patch)
2012-05-14 16:51 CEST, Sven Gothel
Details | Diff
partial revert of commit 4b5a0f6557d7152ec770bc13ad3c494449de0529 (3.11 KB, patch)
2012-10-04 05:49 CEST, Sven Gothel
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Julien Gouesse 2012-04-02 17:15:45 CEST
Lots of people get the following exception when creating a GLCanvas under Windows on a lot of NVIDIA graphics cards including Quadro 1000M and GT 330M:
Exception in thread "main" javax.media.opengl.GLException: Unable to create temp OpenGL context for device context 0x760117f6
at jogamp.opengl.windows.wgl.WindowsWGLContext.createImpl(WindowsWGLContext.java:293)
at jogamp.opengl.GLContextImpl.makeCurrentWithinLock(GLContextImpl.java:505)
at jogamp.opengl.GLContextImpl.makeCurrent(GLContextImpl.java:424)
at com.ardor3d.framework.jogl.JoglCanvasRenderer.init(JoglCanvasRenderer.java:130)
at com.ardor3d.framework.jogl.JoglAwtCanvas.init(JoglAwtCanvas.java:53)
at com.ardor3d.framework.jogl.JoglAwtCanvas.draw(JoglAwtCanvas.java:59)
at com.ardor3d.framework.FrameHandler.updateFrame(FrameHandler.java:90)
at com.ardor3d.example.canvas.JoglAwtExample.main(JoglAwtExample.java:132)

This bug is reproducible with JOGL 2.0 build 724.

Using a GLJPanel is sometimes enough to work around it but sometimes, it causes this:
Exception in thread "main" javax.media.opengl.GLException: Error: attempted to make an external GLContext without a context current, werr 0
at jogamp.opengl.windows.wgl.WindowsExternalWGLContext.create(WindowsExternalWGLContext.java:80)
at jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory.createExternalGLContextImpl(WindowsWGLDrawableFactory.java:531)
at jogamp.opengl.GLDrawableFactoryImpl.createExternalGLContext(GLDrawableFactoryImpl.java:312)
at com.ardor3d.framework.jogl.JoglCanvasRenderer.init(JoglCanvasRenderer.java:127)
at com.ardor3d.framework.jogl.JoglAwtCanvas.init(JoglAwtCanvas.java:55)
at com.ardor3d.framework.jogl.JoglAwtCanvas.draw(JoglAwtCanvas.java:61)
at com.ardor3d.framework.FrameHandler.updateFrame(FrameHandler.java:90)
at com.ardor3d.example.canvas.JoglAwtExample.main(JoglAwtExample.java:132)

I thought it was a bug in my own source code but the same code works fine on other operating systems and under Windows but with other graphics cards and I noticed several other people had the same problem without using Ardor3D:
http://forum.jogamp.org/Unable-to-create-temp-OpenGL-context-for-device-context-tp3089571p3089571.html

Someone posted his logs here:
http://pastebin.com/raw.php?i=i7QHtNuL

I will try to provide a small test case as soon as possible.

N.B: Maybe this problem has something to do with Optimus.
Comment 1 Julien Gouesse 2012-04-02 17:25:43 CEST
It is reproducible on this machine:

MS Win XP
Pro x64 Ed
Vr 2003
SP 2
Intel Core i3-2100 cpu @3.10GHz

NVIDIA Quadro FX 1400
Driver Version 6.14.12.7628
Comment 2 Julien Gouesse 2012-04-13 13:30:58 CEST
Hi

Actually, the original bug was caused by two bugs, one in my source code in Ardor3D's renderer based on JOGL 2.0, one in JOGL 2.0 itself.

When using GLCanvas, the creation of the context fails if it is not performed on the OpenGL thread (AWT EDT by default) and the further successive OpenGL calls do not work fine if they are not done on the same thread too under Windows with some Nvidia graphics cards. I fixed this bug in Ardor3D by using GLCanvas.invoke(true, GLRunnable) to create the context and to perform all OpenGL calls. It works fine when a single GLCanvas is in a container (java.awt.Frame).

However, there is a deadlock as soon as several GLCanvases are in the same container and it occurs everywhere, not only under Windows. It stays blocked on a call of JAWTUtil.lockToolkit() when pushing the runnable that makes current the context of the second GLCanvas.
Comment 3 Sven Gothel 2012-04-17 10:27:31 CEST
(In reply to comment #2)
> Hi
> 
> Actually, the original bug was caused by two bugs, one in my source code in
> Ardor3D's renderer based on JOGL 2.0, one in JOGL 2.0 itself.
> 
> When using GLCanvas, the creation of the context fails if it is not performed
> on the OpenGL thread (AWT EDT by default) and the further successive OpenGL
> calls do not work fine if they are not done on the same thread too under
> Windows with some Nvidia graphics cards. 

In the pastebin post I read that the initialization, adding the GLCanvas, setVisible(true),
is not done on the AWT-EDT. Even thought this shall be tolerated .. it's not perfectly clean.

> I fixed this bug in Ardor3D by using
> GLCanvas.invoke(true, GLRunnable) to create the context and to perform all
> OpenGL calls. It works fine when a single GLCanvas is in a container
> (java.awt.Frame).

Using invoke for every single frame (maybe even multiple times) IMHO is overkill,
since it creates an object on the fly and risks fluent processing due to GC behavior etc.
However, it should work ..

> 
> However, there is a deadlock as soon as several GLCanvases are in the same
> container and it occurs everywhere, not only under Windows. It stays blocked on
> a call of JAWTUtil.lockToolkit() when pushing the runnable that makes current
> the context of the second GLCanvas.

Can you produce a small test case for this, since it is impossible
to see where your GLRunnable is claiming the AWT lock etc ..
Thank you.
Comment 4 Julien Gouesse 2012-04-17 12:03:58 CEST
(In reply to comment #3)
> (In reply to comment #2)
> > Hi
> > 
> > Actually, the original bug was caused by two bugs, one in my source code in
> > Ardor3D's renderer based on JOGL 2.0, one in JOGL 2.0 itself.
> > 
> > When using GLCanvas, the creation of the context fails if it is not performed
> > on the OpenGL thread (AWT EDT by default) and the further successive OpenGL
> > calls do not work fine if they are not done on the same thread too under
> > Windows with some Nvidia graphics cards. 
> 
> In the pastebin post I read that the initialization, adding the GLCanvas,
> setVisible(true),
> is not done on the AWT-EDT. Even thought this shall be tolerated .. it's not
> perfectly clean.
> 
Ok I'll use invokeAndWait to do it.


> > I fixed this bug in Ardor3D by using
> > GLCanvas.invoke(true, GLRunnable) to create the context and to perform all
> > OpenGL calls. It works fine when a single GLCanvas is in a container
> > (java.awt.Frame).
> 
> Using invoke for every single frame (maybe even multiple times) IMHO is
> overkill,
> since it creates an object on the fly and risks fluent processing due to GC
> behavior etc.
> However, it should work ..
> 
I create a GLRunnable for drawing once only. Can it still cause a problem due to GC behavior? Do you have another solution to suggest? 

> > 
> > However, there is a deadlock as soon as several GLCanvases are in the same
> > container and it occurs everywhere, not only under Windows. It stays blocked on
> > a call of JAWTUtil.lockToolkit() when pushing the runnable that makes current
> > the context of the second GLCanvas.
> 
> Can you produce a small test case for this, since it is impossible
> to see where your GLRunnable is claiming the AWT lock etc ..
> Thank you.
Ok I'll do so as soon as possible. The GLRunnable seems to be stuck when creating a second context. Is there a similar example in NEWT in its JUnit tests?
Comment 5 Sven Gothel 2012-04-17 17:48:24 CEST
> > Using invoke for every single frame (maybe even multiple times) IMHO is
> > overkill,
> > since it creates an object on the fly and risks fluent processing due to GC
> > behavior etc.
> > However, it should work ..
> > 
> I create a GLRunnable for drawing once only. Can it still cause a problem due
> to GC behavior? Do you have another solution to suggest? 

You mean once per frame ?
Even though the GC shall be capable of doing so on desktop,
on mobile it's always a gamble .. but 10-60 temporary objects a second 
should be fine - maybe you even 'cache' those object in which case
no GC trigger would exist at all.

But if using this mechanism for frame rendering, 
why not using the listener model ?

I introduced the GLRunnable to inject some event based GL commands
usually not happening too frequently.

However you like to do it (cached GLRunnable or listener or your own 'loop')
it should work .. and is only a side discussion here, granted!

> 
> > > 
> > > However, there is a deadlock as soon as several GLCanvases are in the same
> > > container and it occurs everywhere, not only under Windows. It stays blocked on
> > > a call of JAWTUtil.lockToolkit() when pushing the runnable that makes current
> > > the context of the second GLCanvas.
> > 
> > Can you produce a small test case for this, since it is impossible
> > to see where your GLRunnable is claiming the AWT lock etc ..
> > Thank you.
> Ok I'll do so as soon as possible. The GLRunnable seems to be stuck when
> creating a second context. Is there a similar example in NEWT in its JUnit
> tests?

I assume a shared GLContext from within a GLRunnable ?

Here are some simple GLRunnable use cases ..

src/test/com/jogamp/opengl/test/junit/graph/demos/ui/SceneUIController.java
src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java
src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java
src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug01NEWT.java
src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
src/test/com/jogamp/opengl/test/junit/newt/parenting/GLRunnableDummy.java
src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java

Lately I ran into some 'chicken-egg' problem myself,
i.e. creating a new shared context:

src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java

It uses NEWT and runs on Android. GLRunnable solves the lifecycle issue
of creating a 2nd GLMoviePlayer with information of the 1st one
with information only available after the 1st player initialized itself.
Since the latter is only possible w/ an initialized GLContext .. :)
This API restriction in GLMediaPlayer I had to add due to some .. bugs 
with Tegra/Android .. yeah, sometime it's all a big compromise :)

Would be great if your can provide a use case, so I can reproduce and 
hopefully fix it.

Laters, .. Sven
Comment 6 Sven Gothel 2012-04-17 18:07:41 CEST
I get a hunch what could happen .. hmm.

Even though it would be best to have a test case,
can you provide a complete trace dump of the case 
when it deadlocks with the following flags:

-Dnativewindow.debug.ToolkitLock.TraceLock
-Djogamp.common.utils.locks.Lock.timeout=600000 
-Djogamp.debug.Lock 
-Djogamp.debug.Lock.TraceLock

1) The increased timeout value (default 5s) to gain the lock
would allow you to properly create a stack trace via
  jstack -l <pid>

Please provide the log file and the stack trace.

2) Then pls provide a log file w/ the normal timeout of 5s
but the other debug flags intact.

This shall at least disclose the thread sitting on the lock.

It might be the case where:

T1: AWT-EDT: - execute GLRunnable
                        - create resources while 'spawn off' to T2
T2: - attempt to create GLContext on T1 (AWT) 
         *but it's locked already* and we came 'from their'.

?

Thx .. cheers
Comment 7 Julien Gouesse 2012-04-17 19:03:38 CEST
2012-04-17 19:02:17
Full thread dump OpenJDK Client VM (20.0-b11 mixed mode):

"Attach Listener" daemon prio=10 tid=0x8c9f4400 nid=0x300c runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"com.google.common.base.internal.Finalizer" daemon prio=10 tid=0x8f3ea000 nid=0x2fd9 in Object.wait() [0x8d143000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x9b408290> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133)
        - locked <0x9b408290> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149)
        at com.google.common.base.internal.Finalizer.run(Finalizer.java:127)

   Locked ownable synchronizers:
        - None

"AWT-EventQueue-0" prio=10 tid=0x8c9bc800 nid=0x2fd7 in Object.wait() [0x8f696000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x9b1bc9e0> (a java.awt.EventQueue)
        at java.lang.Object.wait(Object.java:502)
        at java.awt.EventQueue.getNextEvent(EventQueue.java:490)
        - locked <0x9b1bc9e0> (a java.awt.EventQueue)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:247)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)

   Locked ownable synchronizers:
        - <0x9b1630c8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        - <0x9b2ab790> (a jogamp.common.util.locks.RecursiveLockImpl01Unfairish$SingleThreadSync)
        - <0x9b2ac370> (a jogamp.common.util.locks.RecursiveLockImpl01Unfairish$SingleThreadSync)

"AWT-Shutdown" prio=10 tid=0x8f33f000 nid=0x2fd5 in Object.wait() [0x8f77d000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x9b21ca98> (a java.lang.Object)
        at java.lang.Object.wait(Object.java:502)
        at sun.awt.AWTAutoShutdown.run(AWTAutoShutdown.java:281)
        - locked <0x9b21ca98> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:679)

   Locked ownable synchronizers:
        - None

"main-SharedResourceRunner" daemon prio=10 tid=0x8fcb3400 nid=0x2fc5 in Object.wait() [0x8f53b000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x9b21ccf0> (a jogamp.opengl.SharedResourceRunner)
        at java.lang.Object.wait(Object.java:502)
        at jogamp.opengl.SharedResourceRunner.run(SharedResourceRunner.java:240)
        - locked <0x9b21ccf0> (a jogamp.opengl.SharedResourceRunner)
        at java.lang.Thread.run(Thread.java:679)

   Locked ownable synchronizers:
        - None

"AWT-XAWT" daemon prio=10 tid=0xb6aa3400 nid=0x2fae waiting on condition [0x8f7ce000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x9b1630c8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:838)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:871)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1201)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:214)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
        at sun.awt.SunToolkit.awtLock(SunToolkit.java:264)
        at sun.awt.X11.XToolkit.waitForEvents(Native Method)
        at sun.awt.X11.XToolkit.run(XToolkit.java:568)
        at sun.awt.X11.XToolkit.run(XToolkit.java:543)
        at java.lang.Thread.run(Thread.java:679)

   Locked ownable synchronizers:
        - None

"Java2D Disposer" daemon prio=10 tid=0x8fc46000 nid=0x2faa in Object.wait() [0x8f8d3000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x9b144890> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133)
        - locked <0x9b144890> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149)
        at sun.java2d.Disposer.run(Disposer.java:143)
        at java.lang.Thread.run(Thread.java:679)

   Locked ownable synchronizers:
        - None

"Low Memory Detector" daemon prio=10 tid=0xb6a7c000 nid=0x2fa3 runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C1 CompilerThread0" daemon prio=10 tid=0xb6a7a000 nid=0x2fa2 waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"JDWP Command Reader" daemon prio=10 tid=0x089a8400 nid=0x2f9c runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"JDWP Event Helper Thread" daemon prio=10 tid=0xb6a78400 nid=0x2f9b runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"JDWP Transport Listener: dt_socket" daemon prio=10 tid=0xb6a75800 nid=0x2f9a runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Signal Dispatcher" daemon prio=10 tid=0xb6a6d400 nid=0x2f97 runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Finalizer" daemon prio=10 tid=0xb6a5e000 nid=0x2f95 in Object.wait() [0x900ad000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x9b144998> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133)
        - locked <0x9b144998> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)

   Locked ownable synchronizers:
        - None

"Reference Handler" daemon prio=10 tid=0xb6a5cc00 nid=0x2f94 in Object.wait() [0x900fe000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x9b1449b8> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
        - locked <0x9b1449b8> (a java.lang.ref.Reference$Lock)

   Locked ownable synchronizers:
        - None

"main" prio=10 tid=0xb6a07400 nid=0x2f8e waiting on condition [0xb6bf8000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x9b1630c8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:838)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:871)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1201)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:214)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
        at sun.awt.SunToolkit.awtLock(SunToolkit.java:264)
        at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:616)
        at jogamp.nativewindow.jawt.JAWTUtil.awtLock(JAWTUtil.java:298)
        at jogamp.nativewindow.jawt.JAWTUtil.lockToolkit(JAWTUtil.java:328)
        at jogamp.nativewindow.jawt.JAWTUtil$2.lock(JAWTUtil.java:227)
        at javax.media.nativewindow.DefaultGraphicsDevice.lock(DefaultGraphicsDevice.java:128)
        at com.jogamp.nativewindow.awt.JAWTWindow.lockSurface(JAWTWindow.java:278)
        at jogamp.opengl.GLDrawableImpl.lockSurface(GLDrawableImpl.java:195)
        at jogamp.opengl.GLDrawableImpl.setRealized(GLDrawableImpl.java:156)
        - locked <0x9b2aec78> (a jogamp.opengl.x11.glx.X11OnscreenGLXDrawable)
        at javax.media.opengl.awt.GLCanvas.validateGLDrawable(GLCanvas.java:556)
        at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:398)
        at jogamp.opengl.GLDrawableHelper.invoke(GLDrawableHelper.java:287)
        - locked <0x907532b8> (a java.lang.Object)
        at javax.media.opengl.awt.GLCanvas.invoke(GLCanvas.java:654)
        at com.ardor3d.framework.jogl.JoglAwtCanvas.init(JoglAwtCanvas.java:64)
        at com.ardor3d.framework.jogl.JoglAwtCanvas.draw(JoglAwtCanvas.java:76)
        at com.ardor3d.framework.FrameHandler.updateFrame(FrameHandler.java:90)
        at com.ardor3d.example.canvas.JoglAwtExample.main(JoglAwtExample.java:132)

   Locked ownable synchronizers:
        - <0x9b2aeb98> (a jogamp.common.util.locks.RecursiveLockImpl01Unfairish$SingleThreadSync)

"VM Thread" prio=10 tid=0xb6a58c00 nid=0x2f93 runnable

"VM Periodic Task Thread" prio=10 tid=0xb6a7e400 nid=0x2fa4 waiting on condition

JNI global references: 3871
Comment 8 Julien Gouesse 2012-04-17 19:08:12 CEST
I use a cached GLRunnable, I cannot use our listener model in order to respect Ardor3D framework that uses its own abstraction above all OpenGL bindings. There is no shared context involved yet, each canvas has its own context.
Comment 9 Julien Gouesse 2012-04-17 19:26:02 CEST
+++ LOCK 0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
+++ LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
Info: XInitThreads() called for concurrent Thread support
+++ LOCK 0 <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ], cur <main>
+++ LOCK XR <a826da, 18ed77a>[count 2 [ add. 0, orig 2], qsz 0, owner <main>, add.owner ], cur <main>
NullToolkitLock.lock()
NullToolkitLock.unlock()
X11ToolkitLock.lock() - native: false
+++ LOCK 0 <1e29b99, 5585dc>[count 0, qsz 0, owner <NULL>], cur <main-SharedResourceRunner>
+++ LOCK X0 <1e29b99, 5585dc>[count 0, qsz 0, owner <NULL>], cur <main-SharedResourceRunner>
+++ LOCK 0 <a826da, 18ed77a>[count 2 [ add. 0, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner], cur <main-SharedResourceRunner>
+++ LOCK XR <a826da, 18ed77a>[count 3 [ add. 1, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner], cur <main-SharedResourceRunner>
++ unlock(0): currentThread main-SharedResourceRunner, lock: <a826da, 18ed77a>[count 3 [ add. 1, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner]
++ unlock(X): currentThread main-SharedResourceRunner, lock: <a826da, 18ed77a>[count 3 [ add. 1, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner]
--- LOCK XR <a826da, 18ed77a>[count 2 [ add. 0, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner], cur <main-SharedResourceRunner>
+++ LOCK 0 <a826da, 18ed77a>[count 2 [ add. 0, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner], cur <main-SharedResourceRunner>
+++ LOCK XR <a826da, 18ed77a>[count 3 [ add. 1, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner], cur <main-SharedResourceRunner>
++ unlock(0): currentThread main-SharedResourceRunner, lock: <a826da, 18ed77a>[count 3 [ add. 1, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner]
++ unlock(X): currentThread main-SharedResourceRunner, lock: <a826da, 18ed77a>[count 3 [ add. 1, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner]
--- LOCK XR <a826da, 18ed77a>[count 2 [ add. 0, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner], cur <main-SharedResourceRunner>
+++ LOCK 0 <a826da, 18ed77a>[count 2 [ add. 0, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner], cur <main-SharedResourceRunner>
+++ LOCK XR <a826da, 18ed77a>[count 3 [ add. 1, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner], cur <main-SharedResourceRunner>
++ unlock(0): currentThread main-SharedResourceRunner, lock: <a826da, 18ed77a>[count 3 [ add. 1, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner]
++ unlock(X): currentThread main-SharedResourceRunner, lock: <a826da, 18ed77a>[count 3 [ add. 1, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner]
--- LOCK XR <a826da, 18ed77a>[count 2 [ add. 0, orig 2], qsz 0, owner <main>, add.owner main-SharedResourceRunner], cur <main-SharedResourceRunner>
+++ LOCK 0 <1f8f8c8, 952905>[count 0, qsz 0, owner <NULL>], cur <main-SharedResourceRunner>
+++ LOCK X0 <1f8f8c8, 952905>[count 0, qsz 0, owner <NULL>], cur <main-SharedResourceRunner>
+++ LOCK 0 <b83be0, 1631573>[count 0, qsz 0, owner <NULL>], cur <main-SharedResourceRunner>
+++ LOCK X0 <b83be0, 1631573>[count 0, qsz 0, owner <NULL>], cur <main-SharedResourceRunner>
X11ToolkitLock.lock() - native: false
+++ LOCK 0 <1e29b99, 5585dc>[count 1, qsz 0, owner <main-SharedResourceRunner>], cur <main-SharedResourceRunner>
+++ LOCK XR <1e29b99, 5585dc>[count 2, qsz 0, owner <main-SharedResourceRunner>], cur <main-SharedResourceRunner>
X11ToolkitLock.unlock() - native: false
--- LOCK XR <1e29b99, 5585dc>[count 1, qsz 0, owner <main-SharedResourceRunner>], cur <main-SharedResourceRunner>
--- LOCK X0 <b83be0, 1631573>[count 0, qsz 0, owner <NULL>], cur <main-SharedResourceRunner>, signal any
--- LOCK X0 <1f8f8c8, 952905>[count 0, qsz 0, owner <NULL>], cur <main-SharedResourceRunner>, signal any
X11ToolkitLock.unlock() - native: false
--- LOCK X0 <1e29b99, 5585dc>[count 0, qsz 0, owner <NULL>], cur <main-SharedResourceRunner>, signal any
++ unlock(X): currentThread main, lock: <a826da, 18ed77a>[count 2 [ add. 0, orig 2], qsz 0, owner <main>, add.owner ]
--- LOCK XR <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ], cur <main>
++ unlock(X): currentThread main, lock: <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ]
--- LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>, signal any
+++ LOCK 0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
+++ LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
++ unlock(X): currentThread main, lock: <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ]
--- LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>, signal any
+++ LOCK 0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
+++ LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
++ unlock(X): currentThread main, lock: <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ]
--- LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>, signal any
JAWTUtil-ToolkitLock.lock()
NullToolkitLock.lock()
NullToolkitLock.unlock()
JAWTUtil-ToolkitLock.lock()
JAWTUtil-ToolkitLock.lock()
+++ LOCK 0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
+++ LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
++ unlock(X): currentThread main, lock: <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ]
--- LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>, signal any
+++ LOCK 0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
+++ LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
++ unlock(X): currentThread main, lock: <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ]
--- LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>, signal any
JAWTUtil-ToolkitLock.unlock()
JAWTUtil-ToolkitLock.unlock()
JAWTUtil-ToolkitLock.unlock()
+++ LOCK 0 <4e50ee, 1a3551c>[count 0, qsz 0, owner <NULL>], cur <main>
+++ LOCK X0 <4e50ee, 1a3551c>[count 0, qsz 0, owner <NULL>], cur <main>
JAWTUtil-ToolkitLock.lock()
JAWTUtil-ToolkitLock.lock()
JAWTUtil-ToolkitLock.unlock()
JAWTUtil-ToolkitLock.unlock()
--- LOCK X0 <4e50ee, 1a3551c>[count 0, qsz 0, owner <NULL>], cur <main>, signal any
JAWTUtil-ToolkitLock.lock()
NullToolkitLock.lock()
NullToolkitLock.unlock()
JAWTUtil-ToolkitLock.lock()
JAWTUtil-ToolkitLock.lock()
+++ LOCK 0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
+++ LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
++ unlock(X): currentThread main, lock: <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ]
--- LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>, signal any
+++ LOCK 0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
+++ LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
++ unlock(X): currentThread main, lock: <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ]
--- LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>, signal any
JAWTUtil-ToolkitLock.unlock()
JAWTUtil-ToolkitLock.unlock()
JAWTUtil-ToolkitLock.unlock()
+++ LOCK 0 <1cbcf91, 1a847df>[count 0, qsz 0, owner <NULL>], cur <main>
+++ LOCK X0 <1cbcf91, 1a847df>[count 0, qsz 0, owner <NULL>], cur <main>
JAWTUtil-ToolkitLock.lock()
JAWTUtil-ToolkitLock.lock()
JAWTUtil-ToolkitLock.unlock()
JAWTUtil-ToolkitLock.unlock()
--- LOCK X0 <1cbcf91, 1a847df>[count 0, qsz 0, owner <NULL>], cur <main>, signal any
JAWTUtil-ToolkitLock.lock()
NullToolkitLock.lock()
NullToolkitLock.unlock()
JAWTUtil-ToolkitLock.lock()
JAWTUtil-ToolkitLock.lock()
+++ LOCK 0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
+++ LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
++ unlock(X): currentThread main, lock: <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ]
--- LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>, signal any
+++ LOCK 0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
+++ LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
++ unlock(X): currentThread main, lock: <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ]
--- LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>, signal any
JAWTUtil-ToolkitLock.unlock()
JAWTUtil-ToolkitLock.unlock()
JAWTUtil-ToolkitLock.unlock()
+++ LOCK 0 <1734b48, 537d55>[count 0, qsz 0, owner <NULL>], cur <main>
+++ LOCK X0 <1734b48, 537d55>[count 0, qsz 0, owner <NULL>], cur <main>
JAWTUtil-ToolkitLock.lock()
JAWTUtil-ToolkitLock.lock()
JAWTUtil-ToolkitLock.unlock()
JAWTUtil-ToolkitLock.unlock()
--- LOCK X0 <1734b48, 537d55>[count 0, qsz 0, owner <NULL>], cur <main>, signal any
+++ LOCK 0 <4e50ee, 1a3551c>[count 0, qsz 0, owner <NULL>], cur <main>
+++ LOCK X0 <4e50ee, 1a3551c>[count 0, qsz 0, owner <NULL>], cur <main>
JAWTUtil-ToolkitLock.lock()
JAWTUtil-ToolkitLock.lock()
JAWTUtil-ToolkitLock.lock()
+++ LOCK 0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
+++ LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
++ unlock(X): currentThread main, lock: <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ]
--- LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>, signal any
+++ LOCK 0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
+++ LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>
++ unlock(X): currentThread main, lock: <a826da, 18ed77a>[count 1 [ add. 0, orig 1], qsz 0, owner <main>, add.owner ]
--- LOCK X0 <a826da, 18ed77a>[count 0 [ add. 0, orig 0], qsz 0, owner <NULL>, add.owner ], cur <main>, signal any
JAWTUtil-ToolkitLock.unlock()
JAWTUtil-ToolkitLock.unlock()
JAWTUtil-ToolkitLock.unlock()
--- LOCK X0 <4e50ee, 1a3551c>[count 0, qsz 0, owner <NULL>], cur <main>, signal any
+++ LOCK 0 <1dacb2b, 15092c0>[count 0, qsz 0, owner <NULL>], cur <AWT-EventQueue-0>
+++ LOCK X0 <1dacb2b, 15092c0>[count 0, qsz 0, owner <NULL>], cur <AWT-EventQueue-0>
+++ LOCK 0 <4e50ee, 1a3551c>[count 0, qsz 0, owner <NULL>], cur <AWT-EventQueue-0>
+++ LOCK X0 <4e50ee, 1a3551c>[count 0, qsz 0, owner <NULL>], cur <AWT-EventQueue-0>
JAWTUtil-ToolkitLock.lock()
+++ LOCK 0 <1dacb2b, 15092c0>[count 1, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK XR <1dacb2b, 15092c0>[count 2, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK 0 <4e50ee, 1a3551c>[count 1, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK XR <4e50ee, 1a3551c>[count 2, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
--- LOCK XR <4e50ee, 1a3551c>[count 1, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
--- LOCK XR <1dacb2b, 15092c0>[count 1, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK 0 <1dacb2b, 15092c0>[count 1, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK XR <1dacb2b, 15092c0>[count 2, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK 0 <4e50ee, 1a3551c>[count 1, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK XR <4e50ee, 1a3551c>[count 2, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK 0 <1dacb2b, 15092c0>[count 2, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK XR <1dacb2b, 15092c0>[count 3, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK 0 <4e50ee, 1a3551c>[count 2, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK XR <4e50ee, 1a3551c>[count 3, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK 0 <4e50ee, 1a3551c>[count 3, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK XR <4e50ee, 1a3551c>[count 4, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
--- LOCK XR <4e50ee, 1a3551c>[count 3, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
--- LOCK XR <4e50ee, 1a3551c>[count 2, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
--- LOCK XR <1dacb2b, 15092c0>[count 2, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
--- LOCK XR <4e50ee, 1a3551c>[count 1, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
--- LOCK XR <1dacb2b, 15092c0>[count 1, qsz 0, owner <AWT-EventQueue-0>], cur <AWT-EventQueue-0>
+++ LOCK 0 <1cbcf91, 1a847df>[count 0, qsz 0, owner <NULL>], cur <main>
+++ LOCK X0 <1cbcf91, 1a847df>[count 0, qsz 0, owner <NULL>], cur <main>
JAWTUtil-ToolkitLock.lock()
Comment 10 Sven Gothel 2012-04-21 22:19:10 CEST
'AWT-EventQueue-0' holds 
  - 0x9b1630c8 (AWTTreeLock).
  - 0x9b2ab790 (jogl lock)
  - 0x9b2ac370 (jogl lock)

     'main' waits for it - it tries to lock AWT due to setRealized(true).

'main' holds:
  - 0x9b2aeb98 (jogl lock)

+++

IMHO this is a starvation. AWT-EDT-0 doesn't release the AWTTreeLock, nor the jogl locks.
Why ? Maybe you didn't ensure releasing the lock like
       lock();
       try {
          do-some-thing;
       } finally {
          unlock();
       }
Maybe one of your GLRunnables you execute on the AWT-EDT throws an exception
and w/o the unlock in the finally clause, starvation. Just a guess.

+++

Also your 'canvas' impl. call setRealized(true) not from the AWT-EDT, as we do it.
This is a possible source of a deadlock .. but I am not so sure here,
since it looks more like a starvation (See above).

But try it - it's always good to be consistent, i.e. call all AWT resource utilization from the AWT-EDT.
Comment 11 Julien Gouesse 2012-04-22 17:23:16 CEST
I tried to call requestFocus and setVisible(true) directly in the GLRunnable but it did not solve my problem.
Comment 12 Julien Gouesse 2012-04-24 13:24:32 CEST
Hi

This bug is reproducible only under GNU Linux, not under Microsoft Windows:
http://www.ardor3d.com/forums/viewtopic.php?f=11&t=274&start=130#p15724

If you want to reproduce this bug (until I provide a smaller test case), please install Ardor3D and the renderer based on JOGL 2.0 by following these instructions:
http://gouessej.wordpress.com/2011/09/18/le-moteur-3d-ardor3d-fonctionne-desormais-avec-jogl-2-the-3d-engine-ardor3d-now-works-with-jogl-2/

Finally, run JoglAwtExample.
Comment 13 Sven Gothel 2012-05-14 14:17:06 CEST
Sorry for the long delay .. reproduced with ardor3d's trunk and your svn repo.

Triaging now...
Comment 14 Sven Gothel 2012-05-14 16:51:59 CEST
Created attachment 348 [details]
Ardor3D JOGL2 Patch Fix GLContext makeCurrent/release imbalance / commented-out workaround for old JOGL bug

Ardor3D JOGL2 Patch Fix:
-  GLContext makeCurrent/release imbalance 

- Commented-out workaround for old JOGL bug
  as fixed in JOGL commit  c066dc997646643a98c35b7c70183930284544d1

- Update to Ardor3D-core SVN r1853

- Eclipse .classpath: Added gluegen & jogl source attachment
Comment 15 Sven Gothel 2012-05-14 16:58:59 CEST
(In reply to comment #14)
> Created attachment 348 [details]
> Ardor3D JOGL2 Patch Fix GLContext makeCurrent/release imbalance / commented-out
> workaround for old JOGL bug
> 
> Ardor3D JOGL2 Patch Fix:
> -  GLContext makeCurrent/release imbalance

The imbalance throws an exception in JOGL (at exit).
You were doing more makeCurrent() calls then release(),
where destroy() shall be either done w/o holding the context
or while holding it once. Further recursive locking at destroy
will fail-fast to help developer to fix this bug.
 
> 
> - Commented-out workaround for old JOGL bug
>   as fixed in JOGL commit  c066dc997646643a98c35b7c70183930284544d1

Since we don't produce builds until end of May,
you may want to check JoglAwtCanvas.java line 59-72 in the patched file.
Instead of calling setVisible(true) directly, which will be valid w/ the latest JOGL fix,
you need to uncomment this call and use the commented-out variant
which issues the call on the AWT-EDT including a forced display(). 
 
> 
> - Update to Ardor3D-core SVN r1853
> 
> - Eclipse .classpath: Added gluegen & jogl source attachment

Works fine here now.
Comment 16 Julien Gouesse 2012-05-14 18:03:34 CEST
Hi

Thank you so much. I confirm your fixes work fine. I have committed them, I will remove one of them when the nightly builds are available.
Comment 17 Sven Gothel 2012-10-04 05:48:44 CEST
It seems that commit 4b5a0f6557d7152ec770bc13ad3c494449de0529
caused a regression, where validateGL()'s drawable.setRealize(true) 
might not get called from the AWT-EDT.
Comment 18 Sven Gothel 2012-10-04 05:49:47 CEST
Created attachment 370 [details]
partial revert of commit 4b5a0f6557d7152ec770bc13ad3c494449de0529

partial revert of commit 4b5a0f6557d7152ec770bc13ad3c494449de0529
Comment 19 Sven Gothel 2012-10-04 05:50:29 CEST
Pls test Attachment 370 [details]
Comment 20 Julien Gouesse 2012-10-04 16:01:40 CEST
The GLCanvas is no more realized when calling setVisible(true) even though I do it from the AWT EDT. If I call invoke(true, GLRunnable) just after, it returns false and the drawable is not null but not realized. I have to test your suggestion.
Comment 21 Sven Gothel 2012-10-04 17:21:23 CEST
(In reply to comment #20)
> The GLCanvas is no more realized when calling setVisible(true) even though I do
> it from the AWT EDT. If I call invoke(true, GLRunnable) just after, it returns
> false and the drawable is not null but not realized. I have to test your
> suggestion.

Well, realization of the AWT component @ setVisible(true) is lazy (as we know), 
hence we 'poll' it's validity. This was same w/ pre 4b5a0f6557d7152ec770bc13ad3c494449de0529

The patch partially brings back the flow of validateGLDrawable 
issuuing setRealized(true) on the AWT-EDT. Don't really know whether this is the cause or not.

Again, if you can create a 'reliable' unit test to demonstrate the bug it would be great.
Maybe it is enough to call display() from a non AWT-EDT before and after setVisible(true) ?
Comment 22 Julien Gouesse 2012-10-04 19:08:51 CEST
(In reply to comment #21)
> (In reply to comment #20)
> > The GLCanvas is no more realized when calling setVisible(true) even though I do
> > it from the AWT EDT. If I call invoke(true, GLRunnable) just after, it returns
> > false and the drawable is not null but not realized. I have to test your
> > suggestion.
> 
> Well, realization of the AWT component @ setVisible(true) is lazy (as we know), 
> hence we 'poll' it's validity. This was same w/ pre
> 4b5a0f6557d7152ec770bc13ad3c494449de0529
> 
> The patch partially brings back the flow of validateGLDrawable 
> issuuing setRealized(true) on the AWT-EDT. Don't really know whether this is
> the cause or not.
> 
> Again, if you can create a 'reliable' unit test to demonstrate the bug it would
> be great.
> Maybe it is enough to call display() from a non AWT-EDT before and after
> setVisible(true) ?

Your change does not solve the problem, I have just tested. Yes I would like to write a unit test but it is a bit difficult because Ardor3D uses an elaborated framework whereas a unit test should be as rudimentary as possible.
Comment 23 Julien Gouesse 2012-10-04 19:38:03 CEST
(In reply to comment #21)
> Again, if you can create a 'reliable' unit test to demonstrate the bug it would
> be great.

Just use TestBug551AWT and add the following code into the line 102:
System.out.println(glCanvas[0].getDelegatedDrawable().isRealized());

It returned true in RC9, it returns false in RC10.

Calling display() to realize the drawable seems to be needed only with AWT GLCanvas, neither with NewtCanvasAWT nor with GLWindow.
Comment 24 Sven Gothel 2012-10-05 06:37:03 CEST
See <http://jogamp.org/git/?p=jogl.git;a=commit;h=a3cb6bb14f410f67fccf5ccd4cd7ecc66f448389>

I have added the size validation patch .. in this one as well, as reported here:
  <http://forum.jogamp.org/InternalError-in-GLDrawableHelper-on-OSX-10-8-td4026337.html>

Pls also read the new unit test for clarification.
Comment 25 Julien Gouesse 2012-10-05 12:45:36 CEST
(In reply to comment #24)
> See
> <http://jogamp.org/git/?p=jogl.git;a=commit;h=a3cb6bb14f410f67fccf5ccd4cd7ecc66f448389>
> 
> I have added the size validation patch .. in this one as well, as reported
> here:
>  
> <http://forum.jogamp.org/InternalError-in-GLDrawableHelper-on-OSX-10-8-td4026337.html>
> 
> Pls also read the new unit test for clarification.

Ok I'm going to test it immediately. You were not forced to remove the null check in setRealizedOnEDTAction.
Comment 26 Sven Gothel 2012-10-05 12:54:04 CEST
(In reply to comment #25)
> You were not forced to remove the null
> check in setRealizedOnEDTAction.

Well, we claim the lock, hence assuming null and size checks would be redundant.
But earmarking it ..
Comment 27 Julien Gouesse 2012-10-05 14:47:18 CEST
(In reply to comment #26)
> (In reply to comment #25)
> > You were not forced to remove the null
> > check in setRealizedOnEDTAction.
> 
> Well, we claim the lock, hence assuming null and size checks would be
> redundant.
> But earmarking it ..

Ok :)

It would be fine to have an autobuild with this fix so that I can remove the kludge from the Ardor3D renderer based on JOGL 2.0.
Comment 28 Sven Gothel 2012-10-05 14:56:42 CEST
(In reply to comment #27)
> 
> It would be fine to have an autobuild with this fix so that I can remove the
> kludge from the Ardor3D renderer based on JOGL 2.0.

Will happen today, just testing another FBO 'hack', regarding the dummySurface.
Comment 29 Julien Gouesse 2012-10-05 22:02:49 CEST
(In reply to comment #28)
> (In reply to comment #27)
> > 
> > It would be fine to have an autobuild with this fix so that I can remove the
> > kludge from the Ardor3D renderer based on JOGL 2.0.
> 
> Will happen today, just testing another FBO 'hack', regarding the dummySurface.

It works perfectly :) Thanks for the fix and the unit test.