diff options
author | Sven Gothel <[email protected]> | 2014-10-08 08:16:10 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-10-08 08:16:10 +0200 |
commit | 73654365e6147a5eabe8747e5f4802b1fba83829 (patch) | |
tree | 300e2895e8419252ca72314fa5774b8bed2d5152 /src/test | |
parent | 5d3b7dc83c04e2c626a635eb3d143710f7ef4db2 (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.
Diffstat (limited to 'src/test')
5 files changed, 89 insertions, 31 deletions
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 |