diff options
author | Sven Gothel <[email protected]> | 2012-07-22 04:16:55 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2012-07-22 04:16:55 +0200 |
commit | 4b5a0f6557d7152ec770bc13ad3c494449de0529 (patch) | |
tree | 12fc93f9e7f34b61c1d5748f0e6a1cd85fc6125b /src/newt/classes/com/jogamp | |
parent | adc9522ccaff74eb779d4d33905d76d52acb36bb (diff) |
Fix Bug 606 - New AWT threading implementation breaks .. ; Fix GLAutoDrawable multi-threading w/ proper pattern (hope so)
Considering code changes and remarks:
3ed491213f8f7f05d7b9866b50d764370d8ff5f6
1a91ec5c8b6fd9d9db7bc115569c369fe7b38e9b
3334a924309a9361a448d69bc707d4cce416b430
4f27bcecf7484dc041551f52a5c49e2884cb3867
It seems necessary to have
- recursive locking employed for all semantic actions which changes drawable & context (and the Window resource)
- to avoid deadlock, we have to ensure the locked code segment will not spawn
off to another thread, or a thread holds the lock, spawns of an action requiring the lock. .. sure
- other read-only methods (flags, ..) shall at least utilize a safe local copy of a volatile field
if further use to produce the result is necessary.
- flags like sendReshape require to be volatile to guarantee it's being processed
Patch impacts: AWT/SWT GLCanvas, GLAutoDrawableBase [and it's specializations]
and hopefully closes any loopholes of missing a cache hit, etc.
If you review this and find optimizations, i.e. removing a lock due to semantics etc,
don't hold back and discuss it, please.
Diffstat (limited to 'src/newt/classes/com/jogamp')
-rw-r--r-- | src/newt/classes/com/jogamp/newt/opengl/GLWindow.java | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 32d44502f..2205aec8e 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -53,6 +53,7 @@ import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; import jogamp.newt.WindowImpl; @@ -62,6 +63,7 @@ import jogamp.opengl.GLDrawableImpl; import com.jogamp.common.GlueGenVersion; import com.jogamp.common.util.VersionUtil; +import com.jogamp.common.util.locks.RecursiveLock; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; import com.jogamp.newt.Window; @@ -87,13 +89,6 @@ import com.jogamp.opengl.JoglVersion; * you can inject {@link javax.media.opengl.GLRunnable} objects * via {@link #invoke(boolean, javax.media.opengl.GLRunnable)} to the OpenGL command stream.<br> * </p> - * <p> - * NOTE: [MT-0] Methods utilizing [volatile] drawable/context are not synchronized. - In case any of the methods are called outside of a locked state - extra care should be added. Maybe we shall expose locking facilities to the user. - However, since the user shall stick to the GLEventListener model while utilizing - GLAutoDrawable implementations, she is safe due to the implicit locked state. - * </p> */ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Window, NEWTEventConsumer, FPSCounter { private final WindowImpl window; @@ -437,7 +432,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind //e1.printStackTrace(); } - defaultDestroyOp(); + destroyImplInLock(); if(Window.DEBUG_IMPLEMENTATION) { System.err.println("GLWindow.destroy() "+WindowImpl.getThreadName()+", fin"); @@ -515,6 +510,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind private GLContext sharedContext = null; + @Override + protected final RecursiveLock getLock() { + return window.getLock(); + } + /** * Specifies an {@link javax.media.opengl.GLContext OpenGL context} to share with.<br> * At native creation, {@link #setVisible(boolean) setVisible(true)}, @@ -537,19 +537,18 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind return; } - window.lockWindow(); // sync: context/drawable could have been recreated/destroyed while animating + final RecursiveLock lock = window.getLock(); + lock.lock(); // sync: context/drawable could have been recreated/destroyed while animating try { - if( null == context && 0<getWidth()*getHeight() ) { - // retry drawable and context creation - setVisible(true); - } - if( null != context ) { // surface is locked/unlocked implicit by context's makeCurrent/release helper.invokeGL(drawable, context, defaultDisplayAction, defaultInitAction); + } else if( 0<getWidth()*getHeight() ) { + // retry drawable and context creation, will itself issue resize -> display + setVisible(true); } } finally { - window.unlockWindow(); + lock.unlock(); } } @@ -559,7 +558,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind private GLDrawableFactory factory; @Override - public GLDrawableFactory getFactory() { + public final GLDrawableFactory getFactory() { return factory; } @@ -567,6 +566,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind public final void setRealized(boolean realized) { } + @Override + public final void swapBuffers() throws GLException { + defaultSwapBuffers(); + } + //---------------------------------------------------------------------- // NEWTEventConsumer // |