[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)
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.
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.
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).
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.