aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/net/java/games/jogl/GLCanvas.java16
-rw-r--r--src/net/java/games/jogl/impl/GLPbufferImpl.java55
-rwxr-xr-xsrc/net/java/games/jogl/impl/SingleThreadedWorkaround.java22
3 files changed, 78 insertions, 15 deletions
diff --git a/src/net/java/games/jogl/GLCanvas.java b/src/net/java/games/jogl/GLCanvas.java
index 827184dac..17aed5bea 100644
--- a/src/net/java/games/jogl/GLCanvas.java
+++ b/src/net/java/games/jogl/GLCanvas.java
@@ -72,9 +72,9 @@ public final class GLCanvas extends Canvas implements GLDrawable {
}
public void display() {
- withSingleThreadedWorkaroundDo(displayOnEventDispatchThreadAction,
- displayAction,
- false);
+ maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction,
+ displayAction,
+ false);
}
/** Overridden from Canvas; calls {@link #display}. Should not be
@@ -122,7 +122,7 @@ public final class GLCanvas extends Canvas implements GLDrawable {
context.invokeGL(reshapeRunnable, true, initAction);
}
};
- withSingleThreadedWorkaroundDo(reshapeOnEDTRunnable, reshapeRunnable, true);
+ maybeDoSingleThreadedWorkaround(reshapeOnEDTRunnable, reshapeRunnable, true);
}
/** Overridden from Canvas to prevent Java2D's clearing of the
@@ -184,7 +184,7 @@ public final class GLCanvas extends Canvas implements GLDrawable {
}
public void swapBuffers() {
- withSingleThreadedWorkaroundDo(swapBuffersOnEventDispatchThreadAction, swapBuffersAction, false);
+ maybeDoSingleThreadedWorkaround(swapBuffersOnEventDispatchThreadAction, swapBuffersAction, false);
}
public boolean canCreateOffscreenDrawable() {
@@ -205,9 +205,9 @@ public final class GLCanvas extends Canvas implements GLDrawable {
// Internals only below this point
//
- private void withSingleThreadedWorkaroundDo(Runnable eventDispatchThreadAction,
- Runnable invokeGLAction,
- boolean isReshape) {
+ private void maybeDoSingleThreadedWorkaround(Runnable eventDispatchThreadAction,
+ Runnable invokeGLAction,
+ boolean isReshape) {
if (SingleThreadedWorkaround.doWorkaround() && !EventQueue.isDispatchThread()) {
try {
// Reshape events must not block on the event queue due to the
diff --git a/src/net/java/games/jogl/impl/GLPbufferImpl.java b/src/net/java/games/jogl/impl/GLPbufferImpl.java
index 03d161fdd..be0f23398 100644
--- a/src/net/java/games/jogl/impl/GLPbufferImpl.java
+++ b/src/net/java/games/jogl/impl/GLPbufferImpl.java
@@ -40,6 +40,7 @@
package net.java.games.jogl.impl;
import java.awt.Dimension;
+import java.awt.EventQueue;
import java.awt.event.*;
import java.beans.PropertyChangeListener;
@@ -61,7 +62,9 @@ public class GLPbufferImpl implements GLPbuffer {
}
public void display() {
- context.invokeGL(displayAction, false, initAction);
+ maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction,
+ displayAction,
+ false);
}
public void setSize(int width, int height) {
@@ -107,7 +110,7 @@ public class GLPbufferImpl implements GLPbuffer {
}
void willSetRenderingThread() {
- context.willSetRenderingThread();
+ // Not supported for pbuffers
}
public void setRenderingThread(Thread currentThreadOrNull) throws GLException {
@@ -135,7 +138,7 @@ public class GLPbufferImpl implements GLPbuffer {
}
public void swapBuffers() {
- context.invokeGL(swapBuffersAction, false, initAction);
+ maybeDoSingleThreadedWorkaround(swapBuffersOnEventDispatchThreadAction, swapBuffersAction, false);
}
public boolean canCreateOffscreenDrawable() {
@@ -149,10 +152,14 @@ public class GLPbufferImpl implements GLPbuffer {
}
public void bindTexture() {
+ // Doesn't make much sense to try to do this on the event dispatch
+ // thread given that it has to be called while the context is current
context.bindPbufferToTexture();
}
public void releaseTexture() {
+ // Doesn't make much sense to try to do this on the event dispatch
+ // thread given that it has to be called while the context is current
context.releasePbufferFromTexture();
}
@@ -204,6 +211,30 @@ public class GLPbufferImpl implements GLPbuffer {
// Internals only below this point
//
+ private void maybeDoSingleThreadedWorkaround(Runnable eventDispatchThreadAction,
+ Runnable invokeGLAction,
+ boolean isReshape) {
+ if (SingleThreadedWorkaround.doWorkaround() && !EventQueue.isDispatchThread()) {
+ try {
+ // Reshape events must not block on the event queue due to the
+ // possibility of deadlocks during initial component creation.
+ // This solution is not optimal, because it changes the
+ // semantics of reshape() to have some of the processing being
+ // done asynchronously, but at least it preserves the
+ // semantics of the single-threaded workaround.
+ if (!isReshape) {
+ EventQueue.invokeAndWait(eventDispatchThreadAction);
+ } else {
+ EventQueue.invokeLater(eventDispatchThreadAction);
+ }
+ } catch (Exception e) {
+ throw new GLException(e);
+ }
+ } else {
+ context.invokeGL(invokeGLAction, isReshape, initAction);
+ }
+ }
+
class InitAction implements Runnable {
public void run() {
drawableHelper.init(GLPbufferImpl.this);
@@ -225,4 +256,22 @@ public class GLPbufferImpl implements GLPbuffer {
}
}
private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
+
+ // Workaround for ATI driver bugs related to multithreading issues
+ // like simultaneous rendering via Animators to canvases that are
+ // being resized on the AWT event dispatch thread
+ class DisplayOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ context.invokeGL(displayAction, false, initAction);
+ }
+ }
+ private DisplayOnEventDispatchThreadAction displayOnEventDispatchThreadAction =
+ new DisplayOnEventDispatchThreadAction();
+ class SwapBuffersOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ context.invokeGL(swapBuffersAction, false, initAction);
+ }
+ }
+ private SwapBuffersOnEventDispatchThreadAction swapBuffersOnEventDispatchThreadAction =
+ new SwapBuffersOnEventDispatchThreadAction();
}
diff --git a/src/net/java/games/jogl/impl/SingleThreadedWorkaround.java b/src/net/java/games/jogl/impl/SingleThreadedWorkaround.java
index eb7d8f09d..7b9fa46c4 100755
--- a/src/net/java/games/jogl/impl/SingleThreadedWorkaround.java
+++ b/src/net/java/games/jogl/impl/SingleThreadedWorkaround.java
@@ -45,10 +45,20 @@ import java.security.PrivilegedAction;
/** Encapsulates the workaround of running all display operations on
the AWT event queue thread for the purposes of working around
problems seen primarily on ATI cards when rendering into a surface
- that is simultaneously being resized by the event queue thread */
+ that is simultaneously being resized by the event queue thread.
+ <p>
+
+ As of JOGL 1.1 b10, this property defaults to true. Problems have
+ been seen on Windows, Linux and Mac OS X platforms that are solved
+ by switching all OpenGL work to a single thread, which this
+ workaround provides. The forthcoming JSR-231 work will rethink how
+ such a mechanism is implemented, but the core result of needing to
+ perform all OpenGL work on a single thread for best compatibility
+ will remain.
+*/
public class SingleThreadedWorkaround {
- private static boolean singleThreadedWorkaround = false;
+ private static boolean singleThreadedWorkaround = true;
// If the user specified the workaround's system property (either
// true or false), don't let the automatic detection have any effect
private static boolean systemPropertySpecified = false;
@@ -56,12 +66,16 @@ public class SingleThreadedWorkaround {
static {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
- String workaround = System.getProperty("JOGL_SINGLE_THREADED_WORKAROUND");
+ String workaround = System.getProperty("jogl.1thread");
if (workaround == null) {
// Old system property (for compatibility)
+ workaround = System.getProperty("JOGL_SINGLE_THREADED_WORKAROUND");
+ }
+ if (workaround == null) {
+ // Older system property (for compatibility)
workaround = System.getProperty("ATI_WORKAROUND");
}
- if (workaround != null) {
+ if (workaround != null && (!workaround.equals("auto"))) {
systemPropertySpecified = true;
singleThreadedWorkaround = Boolean.valueOf(workaround).booleanValue();
}