Bug 722

Summary: GLEventListenerState doesn't track AbstractGraphicsDevice's Toolkit Lock. It also shall lock the GLAutoDrawable's NativeSurface while operating.
Product: [JogAmp] Jogl Reporter: Sven Gothel <sgothel>
Component: coreAssignee: Sven Gothel <sgothel>
Status: RESOLVED FIXED    
Severity: critical CC: sgothel
Priority: P1    
Version: 2   
Hardware: All   
OS: all   
Type: DEFECT SCM Refs:
0f7412855c118cb501d8a001df7a7487354b5029
Workaround: ---

Description Sven Gothel 2013-04-18 23:50:50 CEST
[junit] Thread-9-null: ** screenshot: TestGLContextDrawableSwitch21Newt2AWT.test11GLWindow2GLCanvasOnScrnGL2ES2_-n0000-GL2ES2-hw-onscreen-Bdbl-Frgb__Irgba8880-D24-St00-Sa00_default-0256x0256.png
    [junit] Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: <AWT-EventQueue-0>: Not locked: <f35f44e, 1f3a34af>[count 0, qsz 0, owner <NULL>]
    [junit]     at jogamp.common.util.locks.RecursiveLockImpl01Unfairish.validateLocked(RecursiveLockImpl01Unfairish.java:180)
    [junit]     at jogamp.common.util.locks.RecursiveLockImpl01Unfairish.unlock(RecursiveLockImpl01Unfairish.java:275)
    [junit]     at jogamp.common.util.locks.RecursiveLockImpl01Unfairish.unlock(RecursiveLockImpl01Unfairish.java:268)
    [junit]     at jogamp.nativewindow.ResourceToolkitLock.unlock(ResourceToolkitLock.java:63)
    [junit]     at javax.media.nativewindow.DefaultGraphicsDevice.unlock(DefaultGraphicsDevice.java:155)
    [junit]     at com.jogamp.nativewindow.awt.JAWTWindow.unlockSurface(JAWTWindow.java:422)
    [junit]     at jogamp.opengl.GLDrawableImpl.setRealized(GLDrawableImpl.java:203)
    [junit]     at javax.media.opengl.awt.GLCanvas.setRealizedImpl(GLCanvas.java:441)
    [junit]     at javax.media.opengl.awt.GLCanvas.access$000(GLCanvas.java:153)
    [junit]     at javax.media.opengl.awt.GLCanvas$2.run(GLCanvas.java:449)
    [junit]     at com.jogamp.common.util.awt.AWTEDTExecutor.invoke(AWTEDTExecutor.java:88)
    [junit]     at javax.media.opengl.awt.GLCanvas.setRealized(GLCanvas.java:455)
    [junit]     at javax.media.opengl.awt.GLCanvas.validateGLDrawable(GLCanvas.java:631)
    [junit]     at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:476)
    [junit]     at javax.media.opengl.awt.GLCanvas.paint(GLCanvas.java:537)
    [junit]     at sun.awt.RepaintArea.paintComponent(RepaintArea.java:248)
    [junit]     at sun.awt.X11.XRepaintArea.paintComponent(XRepaintArea.java:56)
    [junit]     at sun.awt.RepaintArea.paint(RepaintArea.java:224)
    [junit]     at sun.awt.X11.XComponentPeer.handleEvent(XComponentPeer.java:695)
    [junit]     at java.awt.Component.dispatchEventImpl(Component.java:4727)
    [junit]     at java.awt.Component.dispatchEvent(Component.java:4481)
    [junit]     at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
    [junit]     at java.awt.EventQueue.access$000(EventQueue.java:84)
    [junit]     at java.awt.EventQueue$1.run(EventQueue.java:602)
    [junit]     at java.awt.EventQueue$1.run(EventQueue.java:600)
    [junit]     at java.security.AccessController.doPrivileged(Native Method)
    [junit]     at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    [junit]     at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
    [junit]     at java.awt.EventQueue$2.run(EventQueue.java:616)
    [junit]     at java.awt.EventQueue$2.run(EventQueue.java:614)
    [junit]     at java.security.AccessController.doPrivileged(Native Method)
    [junit]     at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    [junit]     at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
    [junit]     at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    [junit]     at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    [junit]     at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    [junit]     at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    [junit]     at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    [junit]     at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Comment 1 Sven Gothel 2013-04-19 02:19:03 CEST
Bug appeared after updating NV driver to 313.30.

After updating OpenIndiana itself, I could not reproduce this behavior
within 5 test runs, including one jenkins build.

Keeping an eye on it, and can be marked invalid if it doesn't happen again.
Comment 2 Sven Gothel 2013-04-19 02:32:38 CEST
Reproduced on GNU/Linux w/ AMD GPU within same unit test, i.e. 
   TestGLContextDrawableSwitch21Newt2AWT - test11GLWindow2GLCanvasOnScrnGL2ES2

Seems that the aDevice can become unlocked by a previous 
drawable/context switch operation. 

Rarely reproducible, needs to analyze code.
Comment 3 Sven Gothel 2013-04-19 18:06:39 CEST
Root cause found, see new title:

GLEventListenerState doesn't track AbstractGraphicsDevice's Toolkit Lock. It also shall lock the GLAutoDrawable's NativeSurface while operating.

GLEventListenerState swaps the AbstractGraphicsDevice to preserve the device handle
being used for GL context was creation.
It's ToolkitLock was kept, hence the confusion.

On another thought .. it may be far easier to move the the device handle value itself
if compatible (X11/EGL).
Comment 4 Sven Gothel 2013-04-23 22:45:40 CEST
Make GLEventListenerState 'transaction' safe Animator.pause[ surface.lock[ modify ] ]
    
GLEventListenerState:
  New model for GLEventListenerState's transaction safety:
   - Z Decorate-1: Animator.pause [ X ]  Animator.resume
   - X Decorate-2: Surface.lock [ Y ] Surface.unlock
    
  - Instead of setting AbstractGraphicsDevice, just swap the handle and ownership.
    
  - Issuing setRealized(..) only if required, i.e. having an upstream-surface (EGL..) depending on used device
    
  - Utilizing setRealized(..) on the GLAD's delegated 'real' drawable, avoiding optional GLAD locking.
    
  - Cleanup and above changes shall render impl. easier to read.
    
GLEventListenerState Unit Tests:
  - If swapping/moving from AWT -> NEWT, use a NEWT dedicated Display
    avoiding ATI driver XCB crash - read comment.