aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-10-08 08:16:10 +0200
committerSven Gothel <[email protected]>2014-10-08 22:30:48 +0200
commitc7ac21e7d25e5271f600806c93e3bd870d45bce3 (patch)
treeff4c930c68c507c44ce0ef6bae413c96c344c26b
parent054de091f39a9d4e32a559e476247d7f8512d904 (diff)
Bug 1088: Add GLRendererQuirks.NeedSharedObjectSync; Tests: Synchronize GL objects if GLRendererQuirks.NeedSharedObjectSync is set.
GLSharedContextSetter#synchronization GL Object Synchronization Usually synchronization of shared GL objects should not be required, if the shared GL objects are created and immutable before concurrent usage. However, using drivers exposing GLRendererQuirks.NeedSharedObjectSync always require the user to synchronize access of shared GL objects. Synchronization can be avoided if accessing the shared GL objects exclusively via a queue or com.jogamp.common.util.Ringbuffer, see GLMediaPlayerImpl as an example. +++ GLRendererQuirks.NeedSharedObjectSync is set for all OSX versions +++ Handle GLRendererQuirks.NeedSharedObjectSync in user code! +++ All shared context tests passed on OSX 10.9.5, and GNU/Linux w/ Nvidia + Mesa/AMD driver. Conflicts: src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
-rw-r--r--make/scripts/tests.sh10
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java37
-rw-r--r--src/jogl/classes/javax/media/opengl/GLSharedContextSetter.java16
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java7
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java12
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT3.java7
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java21
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java25
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java55
9 files changed, 154 insertions, 36 deletions
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 2d05c2110..0d8fe8d4f 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -88,7 +88,7 @@ function jrun() {
swton=$1
shift
- #D_ARGS="-Djogl.debug.DebugGL"
+ D_ARGS="-Djogl.debug.DebugGL"
#D_ARGS="-Djogl.debug.TraceGL"
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL"
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
@@ -96,6 +96,7 @@ function jrun() {
#D_ARGS="-Djogamp.debug=all"
#D_ARGS="-Dnativewindow.debug=all"
#D_ARGS="-Djogl.debug=all"
+ #D_ARGS="-Djogl.debug=all -Dnewt.debug=all -Djogl.debug.DebugGL"
#D_ARGS="-Dnewt.debug=all"
#D_ARGS="-Djogl.debug=all -Dnewt.debug=all"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all"
@@ -381,7 +382,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLCanvasAWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile00NEWT $*
-testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestVersionSemanticsNOUI $*
#
@@ -502,8 +503,11 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2AWT3 $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2AWT3b $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT0 $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT1 $*
+testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT1 $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT2 $*
+
+#testnoawt com.jogamp.opengl.test.junit.graph.demos.GPUUISceneNewtDemo $*
+
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT3 $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT4 $*
#testswt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2SWT3 $*
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
index 828aca78c..a7749e100 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -363,11 +363,43 @@ public class GLRendererQuirks {
*/
public static final int NoPBufferWithAccum = 19;
+ /**
+ * Need GL objects (VBO, ..) to be synchronized when utilized
+ * concurrently from multiple threads via a shared GL context,
+ * otherwise driver crashes the VM.
+ * <p>
+ * Usually synchronization should not be required, if the shared GL objects
+ * are created and immutable before concurrent usage.<br>
+ * However, using drivers exposing this issue always require the user to
+ * synchronize access of shared GL objects.
+ * </p>
+ * <p>
+ * Synchronization can be avoided if accessing the shared GL objects
+ * exclusively via a queue or {@link com.jogamp.common.util.Ringbuffer Ringbuffer}, see GLMediaPlayerImpl as an example.
+ * </p>
+ * <p>
+ * Appears on:
+ * <ul>
+ * <li>Platform OSX
+ * <ul>
+ * <li>detected on OSX 10.9.5 first</li>
+ * <li>any driver</li>
+ * <li>enabled for all OSX versions</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * </p>
+ * <p>
+ * See Bug 1088 - https://jogamp.org/bugzilla/show_bug.cgi?id=1088
+ * </p>
+ */
+ public static final int NeedSharedObjectSync = 20;
+
/** @deprecated Use {@link #getCount()}, this value is no more valid! */
public static final int COUNT = 18;
/** Return the number of known quirks. */
- public static final int getCount() { return 20; }
+ public static final int getCount() { return 21; }
private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval",
"NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard",
@@ -375,7 +407,8 @@ public class GLRendererQuirks {
"NeedCurrCtx4ARBPixFmtQueries", "NeedCurrCtx4ARBCreateContext",
"NoFullFBOSupport", "GLSLNonCompliant", "GL4NeedsGL3Request",
"GLSharedContextBuggy", "GLES3ViaEGLES2Config", "SingletonEGLDisplayOnly",
- "NoMultiSamplingBuffers", "BuggyColorRenderbuffer", "NoPBufferWithAccum"
+ "NoMultiSamplingBuffers", "BuggyColorRenderbuffer", "NoPBufferWithAccum",
+ "NeedSharedObjectSync"
};
private static final IdentityHashMap<String, GLRendererQuirks> stickyDeviceQuirks = new IdentityHashMap<String, GLRendererQuirks>();
diff --git a/src/jogl/classes/javax/media/opengl/GLSharedContextSetter.java b/src/jogl/classes/javax/media/opengl/GLSharedContextSetter.java
index 526967d69..b8aef126b 100644
--- a/src/jogl/classes/javax/media/opengl/GLSharedContextSetter.java
+++ b/src/jogl/classes/javax/media/opengl/GLSharedContextSetter.java
@@ -28,6 +28,8 @@
package javax.media.opengl;
+import com.jogamp.opengl.GLRendererQuirks;
+
/**
* Adds capabilities to set a shared {@link GLContext} directly or via an {@link GLAutoDrawable}.
* <p>
@@ -88,6 +90,20 @@ package javax.media.opengl;
glad.setVisible(true); // GLWindow creation ..
* </pre>
* </p>
+ * <h5><a name="synchronization">GL Object Synchronization</a></h5>
+ * <p>
+ * Usually synchronization of shared GL objects should not be required, if the shared GL objects
+ * are created and immutable before concurrent usage.
+ * </p>
+ * <p>
+ * However, using drivers exposing {@link GLRendererQuirks#NeedSharedObjectSync} always
+ * require the user to synchronize access of shared GL objects.
+ * </p>
+ * <p>
+ * Synchronization can be avoided if accessing the shared GL objects
+ * exclusively via a queue or {@link com.jogamp.common.util.Ringbuffer Ringbuffer}, see GLMediaPlayerImpl as an example.
+ * </p>
+ * </p>
* <h5><a name="driverissues">Known Driver Issues</a></h5>
* <h7><a name="intelmesa">Intel's Mesa >= 9.1.2 Backend for [Sandybridge/Ivybridge] on GNU/Linux</a></h7>
* <p>
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index bc8d3b7e4..45a4f2426 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -1785,6 +1785,13 @@ public abstract class GLContextImpl extends GLContext {
}
quirks.addQuirk( quirk );
}
+ {
+ final int quirk = GLRendererQuirks.NeedSharedObjectSync;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType());
+ }
+ quirks.addQuirk( quirk );
+ }
if( Platform.getOSVersionNumber().compareTo(Platform.OSXVersion.Mavericks) >= 0 && 3==reqMajor && 4==major ) {
final int quirk = GLRendererQuirks.GL4NeedsGL3Request;
if(DEBUG) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java
index a66aaf9d8..8d040222a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java
@@ -107,12 +107,13 @@ public class TestSharedContextVBOES2NEWT2 extends UITestCase {
animator.start();
final GearsES2 g1 = new GearsES2(0);
+ g1.setSyncObjects(g1); // this is master, since rendered we must use it as sync
final GLWindow f1 = createGLWindow(0, 0, g1);
animator.add(f1);
final InsetsImmutable insets = f1.getInsets();
final GearsES2 g2 = new GearsES2(0);
- g2.setSharedGears(g1);
+ g2.setSharedGears(g1); // also uses master g1 as sync, if required
final GLWindow f2 = createGLWindow(f1.getX()+width+insets.getTotalWidth(),
f1.getY()+0, g2);
f2.setSharedAutoDrawable(f1);
@@ -120,7 +121,7 @@ public class TestSharedContextVBOES2NEWT2 extends UITestCase {
f2.setVisible(true);
final GearsES2 g3 = new GearsES2(0);
- g3.setSharedGears(g1);
+ g3.setSharedGears(g1); // also uses master g1 as sync, if required
final GLWindow f3 = createGLWindow(f1.getX()+0,
f1.getY()+height+insets.getTotalHeight(), g3);
f3.setSharedAutoDrawable(f1);
@@ -222,6 +223,7 @@ public class TestSharedContextVBOES2NEWT2 extends UITestCase {
public void asyncEachAnimator(final boolean destroyCleanOrder) throws InterruptedException {
final Animator a1 = new Animator();
final GearsES2 g1 = new GearsES2(0);
+ g1.setSyncObjects(g1); // this is master, since rendered we must use it as sync
final GLWindow f1 = createGLWindow(0, 0, g1);
a1.add(f1);
a1.start();
@@ -230,7 +232,7 @@ public class TestSharedContextVBOES2NEWT2 extends UITestCase {
final Animator a2 = new Animator();
final GearsES2 g2 = new GearsES2(0);
- g2.setSharedGears(g1);
+ g2.setSharedGears(g1); // also uses master g1 as sync, if required
final GLWindow f2 = createGLWindow(f1.getX()+width+insets.getTotalWidth(),
f1.getY()+0, g2);
f2.setSharedAutoDrawable(f1);
@@ -240,7 +242,7 @@ public class TestSharedContextVBOES2NEWT2 extends UITestCase {
final Animator a3 = new Animator();
final GearsES2 g3 = new GearsES2(0);
- g3.setSharedGears(g1);
+ g3.setSharedGears(g1); // also uses master g1 as sync, if required
final GLWindow f3 = createGLWindow(f1.getX()+0,
f1.getY()+height+insets.getTotalHeight(), g3);
f3.setSharedAutoDrawable(f1);
@@ -336,8 +338,10 @@ public class TestSharedContextVBOES2NEWT2 extends UITestCase {
}
static long duration = 1000; // ms
+ static boolean mainRun = false;
public static void main(final String args[]) {
+ mainRun = true;
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
i++;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT3.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT3.java
index 852b7193e..a0d111c4d 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT3.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT3.java
@@ -248,6 +248,7 @@ public class TestSharedContextVBOES2NEWT3 extends UITestCase {
public void asyncEachAnimator(final boolean destroyCleanOrder, final boolean useMappedBuffers) throws InterruptedException {
final Animator a1 = new Animator();
final GearsES2 g1 = new GearsES2(0);
+ g1.setSyncObjects(g1); // this is master, since rendered we must use it as sync
g1.setUseMappedBuffers(useMappedBuffers);
g1.setValidateBuffers(true);
final GLWindow f1 = createGLWindow(0, 0, g1);
@@ -258,7 +259,7 @@ public class TestSharedContextVBOES2NEWT3 extends UITestCase {
final Animator a2 = new Animator();
final GearsES2 g2 = new GearsES2(0);
- g2.setSharedGears(g1);
+ g2.setSharedGears(g1); // also uses master g1 as sync, if required
final GLWindow f2 = createGLWindow(f1.getX()+width+insets.getTotalWidth(),
f1.getY()+0, g2);
f2.setSharedAutoDrawable(f1);
@@ -288,7 +289,7 @@ public class TestSharedContextVBOES2NEWT3 extends UITestCase {
final Animator a3 = new Animator();
final GearsES2 g3 = new GearsES2(0);
- g3.setSharedGears(g1);
+ g3.setSharedGears(g1); // also uses master g1 as sync, if required
final GLWindow f3 = createGLWindow(f1.getX()+0,
f1.getY()+height+insets.getTotalHeight(), g3);
f3.setSharedAutoDrawable(f1);
@@ -374,8 +375,10 @@ public class TestSharedContextVBOES2NEWT3 extends UITestCase {
static long duration = 1000; // ms
static long durationPostDestroy = 1000; // ms - ~60 frames post destroy
+ static boolean mainRun = false;
public static void main(final String args[]) {
+ mainRun = true;
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
i++;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
index 78242944f..9d20495a0 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
@@ -41,6 +41,7 @@ import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.event.MouseListener;
+import com.jogamp.opengl.GLRendererQuirks;
import com.jogamp.opengl.JoglVersion;
import com.jogamp.opengl.test.junit.jogl.demos.GearsObject;
import com.jogamp.opengl.util.glsl.fixedfunc.FixedFuncUtil;
@@ -65,6 +66,7 @@ public class GearsES1 implements GLEventListener {
private GearsObject gear1=null, gear2=null, gear3=null;
private FloatBuffer gear1Color=GearsObject.red, gear2Color=GearsObject.green, gear3Color=GearsObject.blue;
private GearsES1 sharedGears;
+ private Object syncObjects;
private volatile boolean usesSharedGears = false;
private boolean useMappedBuffers = false;
private boolean validateBuffers = false;
@@ -180,6 +182,13 @@ public class GearsES1 implements GLEventListener {
System.err.println("gear1 reuse: "+gear1);
System.err.println("gear2 reuse: "+gear2);
System.err.println("gear3 reuse: "+gear3);
+ if( gl.getContext().hasRendererQuirk(GLRendererQuirks.NeedSharedObjectSync) ) {
+ syncObjects = sharedGears;
+ System.err.println("Shared GearsES1: Synchronized Objects due to quirk "+GLRendererQuirks.toString(GLRendererQuirks.NeedSharedObjectSync));
+ } else {
+ syncObjects = new Object();
+ System.err.println("Shared GearsES1: Unsynchronized Objects");
+ }
} else {
gear1 = new GearsObjectES1(gl, useMappedBuffers, gear1Color, 1.0f, 4.0f, 1.0f, 20, 0.7f, validateBuffers);
System.err.println("gear1 created: "+gear1);
@@ -189,6 +198,8 @@ public class GearsES1 implements GLEventListener {
gear3 = new GearsObjectES1(gl, useMappedBuffers, gear3Color, 1.3f, 2.0f, 0.5f, 10, 0.7f, validateBuffers);
System.err.println("gear3 created: "+gear3);
+
+ syncObjects = new Object();
}
gl.glEnable(GLLightingFunc.GL_NORMALIZE);
@@ -249,6 +260,8 @@ public class GearsES1 implements GLEventListener {
gear2 = null;
gear3.destroy(gl);
gear3 = null;
+ sharedGears = null;
+ syncObjects = null;
System.err.println(Thread.currentThread()+" GearsES1.dispose FIN");
}
@@ -294,9 +307,11 @@ public class GearsES1 implements GLEventListener {
gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f);
gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f);
- gear1.draw(gl, -3.0f, -2.0f, angle);
- gear2.draw(gl, 3.1f, -2.0f, -2.0f * angle - 9.0f);
- gear3.draw(gl, -3.1f, 4.2f, -2.0f * angle - 25.0f);
+ synchronized ( syncObjects ) {
+ gear1.draw(gl, -3.0f, -2.0f, angle);
+ gear2.draw(gl, 3.1f, -2.0f, -2.0f * angle - 9.0f);
+ gear3.draw(gl, -3.1f, 4.2f, -2.0f * angle - 25.0f);
+ }
// Remember that every push needs a pop; this one is paired with
// rotating the entire gear assembly
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
index 0f63566a2..a548d4ccf 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
@@ -30,6 +30,7 @@ import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.event.MouseListener;
import com.jogamp.newt.event.PinchToZoomGesture;
import com.jogamp.newt.event.GestureHandler.GestureEvent;
+import com.jogamp.opengl.GLRendererQuirks;
import com.jogamp.opengl.JoglVersion;
import com.jogamp.opengl.math.FloatUtil;
import com.jogamp.opengl.math.Quaternion;
@@ -75,6 +76,7 @@ public class GearsES2 implements StereoGLEventListener, TileRendererBase.TileRen
private float panX = 0.0f, panY = 0.0f, panZ=0.0f;
private volatile GearsObjectES2 gear1=null, gear2=null, gear3=null;
private GearsES2 sharedGears = null;
+ private Object syncObjects = null;
private boolean useMappedBuffers = false;
private boolean validateBuffers = false;
private volatile boolean usesSharedGears = false;
@@ -146,6 +148,10 @@ public class GearsES2 implements StereoGLEventListener, TileRendererBase.TileRen
sharedGears = shared;
}
+ public void setSyncObjects(final Object sync) {
+ syncObjects = sync;
+ }
+
/**
* @return gear1
*/
@@ -247,6 +253,13 @@ public class GearsES2 implements StereoGLEventListener, TileRendererBase.TileRen
System.err.println("gear2 "+sid()+" created w/ share: "+sharedGears.getGear2()+" -> "+gear2);
System.err.println("gear3 "+sid()+" created w/ share: "+sharedGears.getGear3()+" -> "+gear3);
}
+ if( gl.getContext().hasRendererQuirk(GLRendererQuirks.NeedSharedObjectSync) ) {
+ syncObjects = sharedGears;
+ System.err.println("Shared GearsES2: Synchronized Objects due to quirk "+GLRendererQuirks.toString(GLRendererQuirks.NeedSharedObjectSync));
+ } else if( null == syncObjects ) {
+ syncObjects = new Object();
+ System.err.println("Shared GearsES2: Unsynchronized Objects");
+ }
} else {
gear1 = new GearsObjectES2(gl, useMappedBuffers, st, gear1Color, 1.0f, 4.0f, 1.0f, 20, 0.7f, pmvMatrix, pmvMatrixUniform, colorU, validateBuffers);
if(verbose) {
@@ -262,6 +275,8 @@ public class GearsES2 implements StereoGLEventListener, TileRendererBase.TileRen
if(verbose) {
System.err.println("gear3 "+sid()+" created: "+gear2);
}
+ if( null == syncObjects ) {
+ syncObjects = new Object();
}
}
@@ -461,6 +476,8 @@ public class GearsES2 implements StereoGLEventListener, TileRendererBase.TileRen
colorU = null;
st.destroy(gl);
st = null;
+ sharedGears = null;
+ syncObjects = null;
if(verbose) {
System.err.println(Thread.currentThread()+" GearsES2.dispose "+sid()+" FIN");
@@ -534,9 +551,11 @@ public class GearsES2 implements StereoGLEventListener, TileRendererBase.TileRen
pmvMatrix.glRotatef(view_roty, 0.0f, 1.0f, 0.0f);
pmvMatrix.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f);
- gear1.draw(gl, -3.0f, -2.0f, 1f * angle - 0f);
- gear2.draw(gl, 3.1f, -2.0f, -2f * angle - 9.0f);
- gear3.draw(gl, -3.1f, 4.2f, -2f * angle - 25.0f);
+ synchronized ( syncObjects ) {
+ gear1.draw(gl, -3.0f, -2.0f, 1f * angle - 0f);
+ gear2.draw(gl, 3.1f, -2.0f, -2f * angle - 9.0f);
+ gear3.draw(gl, -3.1f, 4.2f, -2f * angle - 25.0f);
+ }
pmvMatrix.glPopMatrix();
st.useProgram(gl, false);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java
index 6683f0fbf..28328fcd2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java
@@ -20,6 +20,7 @@ import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.event.MouseListener;
import com.jogamp.newt.event.awt.AWTKeyAdapter;
import com.jogamp.newt.event.awt.AWTMouseAdapter;
+import com.jogamp.opengl.GLRendererQuirks;
import com.jogamp.opengl.JoglVersion;
import com.jogamp.opengl.util.TileRendererBase;
@@ -33,6 +34,8 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList
private float view_rotx = 20.0f, view_roty = 30.0f;
private final float view_rotz = 0.0f;
private int gear1=0, gear2=0, gear3=0;
+ private Gears sharedGears = null;
+ private Object syncObjects = null;
private float angle = 0.0f;
private boolean doRotate = true;
private final int swapInterval;
@@ -42,6 +45,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList
private boolean doRotateBeforePrinting;
private boolean verbose = true;
private boolean flipVerticalInGLOrientation = false;
+ private volatile boolean isInit = false;
// private boolean mouseRButtonDown = false;
private int prevMouseX, prevMouseY;
@@ -182,6 +186,13 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList
System.err.println("gear1 list reused: "+gear1);
System.err.println("gear2 list reused: "+gear2);
System.err.println("gear3 list reused: "+gear3);
+ if( gl.getContext().hasRendererQuirk(GLRendererQuirks.NeedSharedObjectSync) ) {
+ syncObjects = sharedGears;
+ System.err.println("Shared Gears: Synchronized Objects due to quirk "+GLRendererQuirks.toString(GLRendererQuirks.NeedSharedObjectSync));
+ } else {
+ syncObjects = new Object();
+ System.err.println("Shared Gears: Unsynchronized Objects");
+ }
} else {
gear1 = gl.glGenLists(1);
gl.glNewList(gear1, GL2.GL_COMPILE);
@@ -203,6 +214,8 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList
gear(gl, 1.3f, 2.0f, 0.5f, 10, 0.7f);
gl.glEndList();
System.err.println("gear3 list created: "+gear3);
+
+ syncObjects = new Object();
}
enableStates(gl, false);
@@ -295,6 +308,8 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList
gear1 = 0;
gear2 = 0;
gear3 = 0;
+ sharedGears = null;
+ syncObjects = null;
}
@Override
@@ -355,25 +370,27 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList
gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f);
// Place the first gear and call its display list
- gl.glPushMatrix();
- gl.glTranslatef(-3.0f, -2.0f, 0.0f);
- gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);
- gl.glCallList(gear1);
- gl.glPopMatrix();
-
- // Place the second gear and call its display list
- gl.glPushMatrix();
- gl.glTranslatef(3.1f, -2.0f, 0.0f);
- gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f);
- gl.glCallList(gear2);
- gl.glPopMatrix();
-
- // Place the third gear and call its display list
- gl.glPushMatrix();
- gl.glTranslatef(-3.1f, 4.2f, 0.0f);
- gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f);
- gl.glCallList(gear3);
- gl.glPopMatrix();
+ synchronized ( syncObjects ) {
+ gl.glPushMatrix();
+ gl.glTranslatef(-3.0f, -2.0f, 0.0f);
+ gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);
+ gl.glCallList(gear1);
+ gl.glPopMatrix();
+
+ // Place the second gear and call its display list
+ gl.glPushMatrix();
+ gl.glTranslatef(3.1f, -2.0f, 0.0f);
+ gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f);
+ gl.glCallList(gear2);
+ gl.glPopMatrix();
+
+ // Place the third gear and call its display list
+ gl.glPushMatrix();
+ gl.glTranslatef(-3.1f, 4.2f, 0.0f);
+ gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f);
+ gl.glCallList(gear3);
+ gl.glPopMatrix();
+ }
// Remember that every push needs a pop; this one is paired with
// rotating the entire gear assembly