aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-03-05 20:04:17 +0100
committerSven Gothel <[email protected]>2020-03-05 20:27:10 +0100
commita63e7c70bd0041b5553abe2a9724d96a0f07c02c (patch)
tree9eac37f3a841e7c18fceecf73ab9145f5f5b97b7
parent972cd560eed70f1d97ef9ba1bd7a450710d4ba20 (diff)
Bug 1398: Ensure CGLContext lock will be acquired before leaving user makeCurrent() call
Command SetNSViewCmd sets NSOpenGLContext's NSView via [NSOpenGLContext setView:] on the main-thread as enforced since XCode 11 using SDK macosx10.15, see Bug 1398. This command is injected into OSX's main-thread @ NSOpenGLImpl.makeCurrent(long) only if required, i.e. issued only for a newly bound NSView and skipped for surface-less or offscreen 'surfaces'. This operation must be performed w/o blocking other tasks locking the NativeSurface on main-thread to complete. Since [NSOpenGLContext setView:] acquires the CGLContext lock on the main-thread, it can't be locked by the calling thread until this task has been completed. Command issuer NSOpenGLImpl.makeCurrent(long) will not acquire the CGLContext lock if this command is pending. contextMadeCurrent(true) cures the potential unlocked CGLContext by issuing a whole GLContext.release() and GLContext.makeCurrent() cycle while waiting for this command to be completed in-between. This GLContext cycle also ensures an unlocked NativeSurface.getLock() in-between, allowing potentially blocked other tasks on the main-thread to complete and hence this queued command to execute. Notable test provoking critical multithreading issues is com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT. Notable test exposing issues with an unlocked CGLContext is com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT. # Conflicts: # make/scripts/tests.sh # src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java
-rw-r--r--make/scripts/tests.sh9
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java131
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java301
-rw-r--r--www/index.html28
5 files changed, 288 insertions, 187 deletions
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 83553b564..ecf7f3b9c 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -967,9 +967,12 @@ function testawtswt() {
#testawt com.jogamp.opengl.test.junit.newt.event.TestNewtEventModifiersAWTCanvas $*
#
# OSX Bug 1398
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT1 $*
-#testnoawt com.jogamp.opengl.test.junit.graph.TestTextRendererNEWT10 $*
-testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
+#testswt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT $*
+testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT $*
+#
+# to re-test:
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLMesaBug658NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01 $*
# Linux DRM/GBM
#
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index aeec04357..6e4265fa2 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -61,6 +61,7 @@ import com.jogamp.opengl.GLUniformData;
import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
import jogamp.nativewindow.macosx.OSXUtil;
+import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLDynamicLookupHelper;
@@ -93,6 +94,7 @@ public class MacOSXCGLContext extends GLContextImpl
void associateDrawable(boolean bound);
boolean copyImpl(long src, int mask);
boolean makeCurrent(long ctx);
+ void contextMadeCurrent(final boolean current);
boolean release(long ctx);
boolean detachPBuffer();
boolean setSwapInterval(int interval);
@@ -102,12 +104,14 @@ public class MacOSXCGLContext extends GLContextImpl
/* package */ static final boolean isTigerOrLater;
/* package */ static final boolean isLionOrLater;
/* package */ static final boolean isMavericksOrLater;
+ private static final boolean DEBUG1398;
static {
final VersionNumber osvn = Platform.getOSVersionNumber();
isTigerOrLater = osvn.compareTo(Platform.OSXVersion.Tiger) >= 0;
isLionOrLater = osvn.compareTo(Platform.OSXVersion.Lion) >= 0;
isMavericksOrLater = osvn.compareTo(Platform.OSXVersion.Mavericks) >= 0;
+ DEBUG1398 = DEBUG || Debug.debug("Bug1398");
}
static boolean isGLProfileSupported(final int ctp, final int major, final int minor) {
@@ -329,6 +333,12 @@ public class MacOSXCGLContext extends GLContextImpl
}
@Override
+ protected void contextMadeCurrent(final boolean current) {
+ impl.contextMadeCurrent(current);
+ super.contextMadeCurrent(current);
+ }
+
+ @Override
protected void releaseImpl() throws GLException {
if (!impl.release(contextHandle)) {
throw new GLException("Error releasing OpenGL Context: "+this);
@@ -622,7 +632,7 @@ public class MacOSXCGLContext extends GLContextImpl
private AttachGLLayerCmd attachGLLayerCmd;
private NSViewDescriptor lastNSViewDescr; // Bug 1398
private SetNSViewCmd lastSetNSViewCmd; // Bug 1398
- private boolean lockCGL; // Bug 1398
+ private boolean cglContextLocked; // Bug 1398
NSOpenGLImpl() { resetState(); }
@@ -638,7 +648,7 @@ public class MacOSXCGLContext extends GLContextImpl
attachGLLayerCmd = null;
lastNSViewDescr = null;
lastSetNSViewCmd = null;
- lockCGL = true;
+ cglContextLocked = false;
}
@Override
@@ -1012,10 +1022,11 @@ public class MacOSXCGLContext extends GLContextImpl
@Override
public boolean makeCurrent(final long ctx) {
- // Bug 1398: Perform SetNSViewCmd's on Main-Thread async w/o blocking.
+ // Bug 1398: Perform SetNSViewCmd's on Main-Thread w/o blocking other tasks
// - Only issue SetNSViewCmd if changed (boolean nsViewChanged).
- // - Avoid CGLLockContext until async SetNSViewCmd is done (boolean lockCGL).
- // - See api-doc in SetNSViewCmd
+ // - Skip CGLLockContext if SetNSViewCmd is pending (bool lockCGLContext -> cglContextLocked).
+ // - Potentially skipped CGLLockContext gets cured in contextMadeCurrent(true) below
+ // - See SetNSViewCmd API-doc
//
final NSViewDescriptor nsViewDescr = new NSViewDescriptor(drawable);
needsSetContextPBuffer = nsViewDescr.isPBuffer;
@@ -1027,31 +1038,83 @@ public class MacOSXCGLContext extends GLContextImpl
lastSetNSViewCmd = cmd;
OSXUtil.RunOnMainThread(false /* wait */, false /* kickNSApp */, cmd);
}
+ final boolean lockCGLContext;
if( null != lastSetNSViewCmd ) {
synchronized( lastSetNSViewCmd ) {
- lockCGL = lastSetNSViewCmd.done;
- if( lockCGL ) {
+ lockCGLContext = lastSetNSViewCmd.done;
+ if( lockCGLContext ) {
lastSetNSViewCmd = null; // no more required
+ } else if( DEBUG1398 ) {
+ System.err.println("MaxOSXCGLContext.NSOpenGLImpl.makeCurrent: Skip CGLLockContext (Bug1398)");
}
}
} else {
- lockCGL = true;
+ lockCGLContext = true;
}
final long cglCtx = CGL.getCGLContext(ctx);
if(0 == cglCtx) {
throw new InternalError("Null CGLContext for: "+this);
}
- final int err = lockCGL ? CGL.CGLLockContext(cglCtx) : CGL.kCGLNoError;
+ final int err = lockCGLContext ? CGL.CGLLockContext(cglCtx) : CGL.kCGLNoError;
if(CGL.kCGLNoError == err) {
+ cglContextLocked = lockCGLContext;
validatePBufferConfig(ctx); // required to handle pbuffer change ASAP
return CGL.makeCurrentContext(ctx);
- } else if(DEBUG) {
- System.err.println("NSGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+ } else {
+ cglContextLocked = false;
+ if(DEBUG) {
+ System.err.println("MaxOSXCGLContext.NSOpenGLImpl.makeCurrent: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
}
return false;
}
+ boolean insideContextMadeCurrent = false; // ensure no recursion occurs
+
+ @Override
+ public void contextMadeCurrent(final boolean current) {
+ if( current && !insideContextMadeCurrent && !cglContextLocked ) {
+ // Bug 1398: Cure missing CGLContextLock by context release/makeCurrent cycle outside context acquisition code,
+ // only for user makeCurrent calls, not createContext*() only.
+ // See SetNSViewCmd API-doc.
+ insideContextMadeCurrent = true;
+ try {
+ final RecursiveLock surfaceLock = drawable.getNativeSurface().getLock();
+ final int surfaceLockCount = null != surfaceLock ? surfaceLock.getHoldCount() : 1;
+
+ if(DEBUG1398) {
+ System.err.println("MaxOSXCGLContext.NSOpenGLImpl.contextMadeCurrent: Cure missing CGLContextLock (Bug1398), surfaceLock "+surfaceLock);
+ }
+ // Reduce lock-count so context.release()'s surface.unlockSurface() will actually release the lock
+ for(int i=1; i<surfaceLockCount; i++) {
+ surfaceLock.unlock();
+ }
+ MacOSXCGLContext.this.release(); // implies final surface.unlockSurface();
+
+ if( null != lastSetNSViewCmd ) {
+ synchronized( lastSetNSViewCmd ) {
+ while( !lastSetNSViewCmd.done ) {
+ try {
+ if(DEBUG1398) {
+ System.err.println("MaxOSXCGLContext.NSOpenGLImpl.contextMadeCurrent: Wait for SetNSViewCmd (Bug1398), surfaceLock "+surfaceLock);
+ }
+ lastSetNSViewCmd.wait();
+ } catch (final InterruptedException e) { }
+ }
+ }
+ }
+ MacOSXCGLContext.this.makeCurrent();
+ // Repair original lock-count
+ for(int i=1; i<surfaceLockCount; i++) {
+ surfaceLock.lock();
+ }
+ } finally {
+ insideContextMadeCurrent = false;
+ }
+ }
+ }
+
@Override
public boolean release(final long ctx) {
try {
@@ -1069,8 +1132,8 @@ public class MacOSXCGLContext extends GLContextImpl
if(0 == cglCtx) {
throw new InternalError("Null CGLContext for: "+this);
}
- final int err = lockCGL ? CGL.CGLUnlockContext(cglCtx) : CGL.kCGLNoError;
- lockCGL = true;
+ final int err = cglContextLocked ? CGL.CGLUnlockContext(cglCtx) : CGL.kCGLNoError;
+ cglContextLocked = false;
if(DEBUG && CGL.kCGLNoError != err) {
System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err)+": "+this);
}
@@ -1225,26 +1288,40 @@ public class MacOSXCGLContext extends GLContextImpl
}
/**
- * Set NSOpenGLContext's NSView via [NSOpenGLContext setView:]
- * on the main-thread as enforced since XCode 11 using SDL macosx10.15,
+ * Command sets NSOpenGLContext's NSView via [NSOpenGLContext setView:]
+ * on the main-thread as enforced since XCode 11 using SDK macosx10.15,
* see Bug 1398.
* <p>
- * This operation must be performed async w/o blocking to allow
- * other tasks locking the NativeSurface on main-thread to complete.
+ * This command is injected into OSX's main-thread @ {@link NSOpenGLImpl#makeCurrent(long)}
+ * only if required, i.e. issued only for a newly bound NSView and
+ * skipped for surface-less or offscreen 'surfaces'.
+ * </p>
+ * <p>
+ * This operation must be performed w/o blocking
+ * other tasks locking the {@link NativeSurface} on main-thread to complete.
* </p>
* <p>
- * Further, since [NSOpenGLContext setView:] acquired the CGLContext lock,
- * it can't be locked until this task has been completed.
+ * Since [NSOpenGLContext setView:] acquires the CGLContext lock on the main-thread,
+ * it can't be locked by the calling thread until this task has been completed.
+ * <br>
+ * Command issuer {@link NSOpenGLImpl#makeCurrent(long)} will not acquire the CGLContext lock
+ * if this command is pending.
* </p>
* <p>
- * Worst case scenario for a late [NSOpenGLContext setView:] issuance
- * might be corrupt initial frame(s) displayed.
+ * {@link NSOpenGLImpl#contextMadeCurrent(boolean) contextMadeCurrent(true)} cures the potential unlocked CGLContext
+ * by issuing a whole {@link GLContext#release()} and {@link GLContext#makeCurrent()} cycle
+ * while waiting for this command to be completed in-between.
+ * <br>
+ * This {@link GLContext} cycle also ensures an unlocked {@link NativeSurface#getLock()}
+ * in-between, allowing potentially blocked other tasks on the main-thread to complete
+ * and hence this queued command to execute.
* </p>
* <p>
- * Since all concurrent locking is performed within JOGL,
- * the unlocked CGLContext window risk is only academic.
- * However, if native 3rd party toolkits take share control,
- * we might have a situation.
+ * Notable test provoking critical multithreading issues is
+ * {@link com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT}.
+ * <br>
+ * Notable test exposing issues with an unlocked CGLContext is
+ * {@link com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT}.
* </p>
*/
class SetNSViewCmd implements Runnable {
@@ -1370,6 +1447,10 @@ public class MacOSXCGLContext extends GLContextImpl
}
@Override
+ public void contextMadeCurrent(final boolean current) {
+ }
+
+ @Override
public boolean release(final long ctx) {
try {
if( hasRendererQuirk(GLRendererQuirks.GLFlushBeforeRelease) && null != MacOSXCGLContext.this.getGLProcAddressTable() ) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java
index c77745ddb..afad9b49f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java
@@ -67,7 +67,11 @@ public class GLSLMiscHelper {
}
}
- public static void displayVCArrays(final GLDrawable drawable, final GL2ES2 gl, final ShaderState st, final boolean preEnable, final GLArrayDataServer vertices, final GLArrayDataServer colors, final boolean postDisable, final int num, final long postDelay) throws InterruptedException {
+ public static void displayVCArrays(final GLDrawable drawable, final GL2ES2 gl, final ShaderState st,
+ final boolean preEnable, final GLArrayDataServer vertices, final GLArrayDataServer colors,
+ final boolean postDisable, final int num, final long postDelay)
+ throws InterruptedException
+ {
System.err.println("screen #"+num);
if(preEnable) {
vertices.enableBuffer(gl, true);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
index 0f67472ab..2cf017f41 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
@@ -39,9 +39,11 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
import java.io.IOException;
+import com.jogamp.nativewindow.NativeWindowFactory;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GLCapabilities;
+import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLDrawable;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.GLUniformData;
@@ -63,23 +65,184 @@ public class TestGLSLShaderState02NEWT extends UITestCase {
static final int vertices0_loc = 0; // FIXME: AMD needs this to be location 0 ? hu ?
static final int colors0_loc = 5;
+ @Test(timeout=240000)
+ public void test01ShaderStatePerformanceDouble() throws InterruptedException {
+ // preset ..
+ if(true) {
+ System.err.println("CCC01: GLProfile.initSingleton(); START");
+ GLProfile.initSingleton();
+ System.err.println("CCC01: GLProfile.initSingleton(); DONE ");
+ }
+
+ System.err.println("CCC01: Win + Ctx creation incl 1st makeCurrent.");
+ final NEWTGLContext.WindowContext winctx = NEWTGLContext.createWindow(
+ new GLCapabilities(GLProfile.getGL2ES2()), 480, 480, false);
+ final GLDrawable drawable = winctx.context.getGLDrawable();
+ final GL2ES2 gl = winctx.context.getGL().getGL2ES2();
+ System.err.println(winctx.context);
+ gl.setSwapInterval(0);
+
+ Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+
+ // test code ..
+ final ShaderState st = new ShaderState();
+
+ final ShaderCode rsVp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
+ "shader/bin", "RedSquareShader", true);
+ final ShaderCode rsFp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
+ "shader/bin", "RedSquareShader", true);
+ final ShaderCode rsFp1 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
+ "shader/bin", "RedSquareShader2", true);
+ rsVp0.defaultShaderCustomization(gl, true, true);
+ rsFp0.defaultShaderCustomization(gl, true, true);
+ rsFp1.defaultShaderCustomization(gl, true, true);
+
+ final ShaderProgram sp1 = new ShaderProgram();
+ sp1.add(rsVp0);
+ sp1.add(rsFp1);
+ Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+ Assert.assertTrue(0 == sp1.program());
+ Assert.assertTrue(sp1.init(gl));
+ Assert.assertTrue(0 != sp1.program());
+ Assert.assertTrue(sp1.link(gl, System.err));
+
+ final ShaderProgram sp0 = new ShaderProgram();
+ sp0.add(rsVp0);
+ sp0.add(rsFp0);
+
+ Assert.assertTrue(sp0.init(gl));
+ Assert.assertTrue(sp0.link(gl, System.err));
+
+ st.attachShaderProgram(gl, sp0, true);
+
+ // setup mgl_PMVMatrix
+ final PMVMatrix pmvMatrix = new PMVMatrix();
+ final GLUniformData pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
+ st.ownUniform(pmvMatrixUniform);
+ st.uniform(gl, pmvMatrixUniform);
+
+ // Allocate Vertex Array0
+ final GLArrayDataServer vertices0 = GLSLMiscHelper.createVertices(gl, st, 0, -1, GLSLMiscHelper.vertices0);
+ vertices0.enableBuffer(gl, false);
+
+ // Allocate Vertex Array1
+ final GLArrayDataServer vertices1 = GLSLMiscHelper.createVertices(gl, st, 0, -1, GLSLMiscHelper.vertices1);
+ vertices1.enableBuffer(gl, false);
+
+ // Allocate Color Array0
+ final GLArrayDataServer colors0 = GLSLMiscHelper.createColors(gl, st, 0, -1, GLSLMiscHelper.colors0);
+ colors0.enableBuffer(gl, false);
+
+ // Allocate Color Array1
+ final GLArrayDataServer colors1 = GLSLMiscHelper.createColors(gl, st, 0, -1, GLSLMiscHelper.colors1);
+ colors1.enableBuffer(gl, false);
+
+ // misc GL setup
+ gl.glClearColor(0, 0, 0, 1);
+ gl.glEnable(GL.GL_DEPTH_TEST);
+
+ // reshape
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.gluPerspective(45.0F, (float) drawable.getSurfaceWidth() / (float) drawable.getSurfaceHeight(), 1.0F, 100.0F);
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glTranslatef(0, 0, -10);
+ st.uniform(gl, pmvMatrixUniform);
+ gl.glViewport(0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
+
+ gl.setSwapInterval(0);
+
+ // validation ..
+ st.attachShaderProgram(gl, sp0, true);
+ GLSLMiscHelper.displayVCArrays(drawable, gl, st, true, vertices0, colors0, true, 1, 0);
+ GLSLMiscHelper.displayVCArrays(drawable, gl, st, true, vertices1, colors1, true, 2, 0);
+ st.attachShaderProgram(gl, sp1, true);
+ GLSLMiscHelper.displayVCArrays(drawable, gl, st, true, vertices0, colors0, true, 1, 0);
+ GLSLMiscHelper.displayVCArrays(drawable, gl, st, true, vertices1, colors1, true, 2, 0);
+
+ // warmup ..
+ for(int frames=0; frames<GLSLMiscHelper.frames_warmup; frames+=2) {
+ // SP0
+ st.attachShaderProgram(gl, sp0, true);
+ GLSLMiscHelper.displayVCArraysNoChecks(drawable, gl, true, vertices0, colors0, true);
+ // SP1
+ st.attachShaderProgram(gl, sp1, true);
+ GLSLMiscHelper.displayVCArraysNoChecks(drawable, gl, true, vertices1, colors1, true);
+ }
+
+ // measure ..
+ final long t0 = System.currentTimeMillis();
+ int frames;
+
+ for(frames=0; frames<GLSLMiscHelper.frames_perftest; frames+=4) {
+ // SP0
+ st.attachShaderProgram(gl, sp0, true);
+ GLSLMiscHelper.displayVCArraysNoChecks(drawable, gl, true, vertices0, colors0, true);
+ GLSLMiscHelper.displayVCArraysNoChecks(drawable, gl, true, vertices1, colors1, true);
+ // SP1
+ st.attachShaderProgram(gl, sp1, true);
+ GLSLMiscHelper.displayVCArraysNoChecks(drawable, gl, true, vertices0, colors0, true);
+ GLSLMiscHelper.displayVCArraysNoChecks(drawable, gl, true, vertices1, colors1, true);
+ }
+
+ final long t1 = System.currentTimeMillis();
+ final long dt = t1 - t0;
+ final double fps = ( frames * 1000.0 ) / dt;
+ final String fpsS = String.valueOf(fps);
+ final int fpsSp = fpsS.indexOf('.');
+ System.err.println("testShaderState01PerformanceDouble: "+dt/1000.0 +"s: "+ frames + "f, " + fpsS.substring(0, fpsSp+2) + " fps, "+dt/frames+" ms/f");
+
+ // cleanup
+ st.destroy(gl);
+ NEWTGLContext.destroyWindow(winctx);
+ }
+
@Test
- public void testShaderState01ValidationSP1Linked() throws InterruptedException {
- testShaderState01Validation(true);
+ public void test11ShaderStateValidationSP1Linked() throws InterruptedException {
+ test1XShaderStateValidation(true);
}
@Test
- public void testShaderState01ValidationSP1Unlinked() throws InterruptedException {
- testShaderState01Validation(false);
+ public void test12ShaderStateValidationSP1Unlinked() throws InterruptedException {
+ test1XShaderStateValidation(false);
}
- private void testShaderState01Validation(final boolean linkSP1) throws InterruptedException {
+ private void test1XShaderStateValidation(final boolean linkSP1) throws InterruptedException {
// preset ..
+ if(true) {
+ System.err.println("CCC01: GLProfile.initSingleton(); START");
+ GLProfile.initSingleton();
+ System.err.println("CCC01: GLProfile.initSingleton(); DONE ");
+ }
+
+ System.err.println("CCC01: Win + Ctx creation incl 1st makeCurrent.");
final NEWTGLContext.WindowContext winctx = NEWTGLContext.createWindow(
new GLCapabilities(GLProfile.getGL2ES2()), 480, 480, true);
final GLDrawable drawable = winctx.context.getGLDrawable();
final GL2ES2 gl = winctx.context.getGL().getGL2ES2();
System.err.println(winctx.context);
+ if(false) {
+ /**
+ * Bug 1398 OSX: If 'test12ShaderStateValidationSP1Unlinked()'
+ * runs w/o CGLLockContext, a GLError occurs on glClear(..):
+ *
+com.jogamp.opengl.GLException: Thread[main,5,main] glGetError() returned the following error codes after a call to glClear(<int> 0x4100): Unknown glGetError() return value: ( 1286 0x506),
+ at com.jogamp.opengl.DebugGL4bc.writeGLError(DebugGL4bc.java:31781)
+ at com.jogamp.opengl.DebugGL4bc.glClear(DebugGL4bc.java:1240)
+ at com.jogamp.opengl.test.junit.jogl.glsl.GLSLMiscHelper.displayVCArrays(GLSLMiscHelper.java:91)
+ at com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT.test1XShaderStateValidation(TestGLSLShaderState02NEWT.java:351)
+ at com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT.test12ShaderStateValidationSP1Unlinked(TestGLSLShaderState02NEWT.java:207)
+ */
+ System.err.println("CCC01: swap - release");
+ winctx.drawable.swapBuffers();
+ winctx.context.release();
+ Thread.sleep(16);
+ System.err.println("CCC01: makeCurrent");
+ final int res = winctx.context.makeCurrent();
+ Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
+ }
+
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
// test code ..
@@ -237,132 +400,6 @@ public class TestGLSLShaderState02NEWT extends UITestCase {
NEWTGLContext.destroyWindow(winctx);
}
- @Test(timeout=240000)
- public void testShaderState01PerformanceDouble() throws InterruptedException {
- // preset ..
- final NEWTGLContext.WindowContext winctx = NEWTGLContext.createWindow(
- new GLCapabilities(GLProfile.getGL2ES2()), 480, 480, false);
- final GLDrawable drawable = winctx.context.getGLDrawable();
- final GL2ES2 gl = winctx.context.getGL().getGL2ES2();
- System.err.println(winctx.context);
- gl.setSwapInterval(0);
-
- Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-
- // test code ..
- final ShaderState st = new ShaderState();
-
- final ShaderCode rsVp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
- "shader/bin", "RedSquareShader", true);
- final ShaderCode rsFp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
- "shader/bin", "RedSquareShader", true);
- final ShaderCode rsFp1 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
- "shader/bin", "RedSquareShader2", true);
- rsVp0.defaultShaderCustomization(gl, true, true);
- rsFp0.defaultShaderCustomization(gl, true, true);
- rsFp1.defaultShaderCustomization(gl, true, true);
-
- final ShaderProgram sp1 = new ShaderProgram();
- sp1.add(rsVp0);
- sp1.add(rsFp1);
- Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
- Assert.assertTrue(0 == sp1.program());
- Assert.assertTrue(sp1.init(gl));
- Assert.assertTrue(0 != sp1.program());
- Assert.assertTrue(sp1.link(gl, System.err));
-
- final ShaderProgram sp0 = new ShaderProgram();
- sp0.add(rsVp0);
- sp0.add(rsFp0);
-
- Assert.assertTrue(sp0.init(gl));
- Assert.assertTrue(sp0.link(gl, System.err));
-
- st.attachShaderProgram(gl, sp0, true);
-
- // setup mgl_PMVMatrix
- final PMVMatrix pmvMatrix = new PMVMatrix();
- final GLUniformData pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
- st.ownUniform(pmvMatrixUniform);
- st.uniform(gl, pmvMatrixUniform);
-
- // Allocate Vertex Array0
- final GLArrayDataServer vertices0 = GLSLMiscHelper.createVertices(gl, st, 0, -1, GLSLMiscHelper.vertices0);
- vertices0.enableBuffer(gl, false);
-
- // Allocate Vertex Array1
- final GLArrayDataServer vertices1 = GLSLMiscHelper.createVertices(gl, st, 0, -1, GLSLMiscHelper.vertices1);
- vertices1.enableBuffer(gl, false);
-
- // Allocate Color Array0
- final GLArrayDataServer colors0 = GLSLMiscHelper.createColors(gl, st, 0, -1, GLSLMiscHelper.colors0);
- colors0.enableBuffer(gl, false);
-
- // Allocate Color Array1
- final GLArrayDataServer colors1 = GLSLMiscHelper.createColors(gl, st, 0, -1, GLSLMiscHelper.colors1);
- colors1.enableBuffer(gl, false);
-
- // misc GL setup
- gl.glClearColor(0, 0, 0, 1);
- gl.glEnable(GL.GL_DEPTH_TEST);
-
- // reshape
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
- pmvMatrix.glLoadIdentity();
- pmvMatrix.gluPerspective(45.0F, (float) drawable.getSurfaceWidth() / (float) drawable.getSurfaceHeight(), 1.0F, 100.0F);
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
- pmvMatrix.glLoadIdentity();
- pmvMatrix.glTranslatef(0, 0, -10);
- st.uniform(gl, pmvMatrixUniform);
- gl.glViewport(0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
-
- gl.setSwapInterval(0);
-
- // validation ..
- st.attachShaderProgram(gl, sp0, true);
- GLSLMiscHelper.displayVCArrays(drawable, gl, st, true, vertices0, colors0, true, 1, 0);
- GLSLMiscHelper.displayVCArrays(drawable, gl, st, true, vertices1, colors1, true, 2, 0);
- st.attachShaderProgram(gl, sp1, true);
- GLSLMiscHelper.displayVCArrays(drawable, gl, st, true, vertices0, colors0, true, 1, 0);
- GLSLMiscHelper.displayVCArrays(drawable, gl, st, true, vertices1, colors1, true, 2, 0);
-
- // warmup ..
- for(int frames=0; frames<GLSLMiscHelper.frames_warmup; frames+=2) {
- // SP0
- st.attachShaderProgram(gl, sp0, true);
- GLSLMiscHelper.displayVCArraysNoChecks(drawable, gl, true, vertices0, colors0, true);
- // SP1
- st.attachShaderProgram(gl, sp1, true);
- GLSLMiscHelper.displayVCArraysNoChecks(drawable, gl, true, vertices1, colors1, true);
- }
-
- // measure ..
- final long t0 = System.currentTimeMillis();
- int frames;
-
- for(frames=0; frames<GLSLMiscHelper.frames_perftest; frames+=4) {
- // SP0
- st.attachShaderProgram(gl, sp0, true);
- GLSLMiscHelper.displayVCArraysNoChecks(drawable, gl, true, vertices0, colors0, true);
- GLSLMiscHelper.displayVCArraysNoChecks(drawable, gl, true, vertices1, colors1, true);
- // SP1
- st.attachShaderProgram(gl, sp1, true);
- GLSLMiscHelper.displayVCArraysNoChecks(drawable, gl, true, vertices0, colors0, true);
- GLSLMiscHelper.displayVCArraysNoChecks(drawable, gl, true, vertices1, colors1, true);
- }
-
- final long t1 = System.currentTimeMillis();
- final long dt = t1 - t0;
- final double fps = ( frames * 1000.0 ) / dt;
- final String fpsS = String.valueOf(fps);
- final int fpsSp = fpsS.indexOf('.');
- System.err.println("testShaderState01PerformanceDouble: "+dt/1000.0 +"s: "+ frames + "f, " + fpsS.substring(0, fpsSp+2) + " fps, "+dt/frames+" ms/f");
-
- // cleanup
- st.destroy(gl);
- NEWTGLContext.destroyWindow(winctx);
- }
-
public static void main(final String args[]) throws IOException {
System.err.println("main - start");
boolean wait = false;
@@ -378,7 +415,7 @@ public class TestGLSLShaderState02NEWT extends UITestCase {
while(-1 == System.in.read()) ;
final TestGLSLShaderState02NEWT tst = new TestGLSLShaderState02NEWT();
try {
- tst.testShaderState01PerformanceDouble();
+ tst.test01ShaderStatePerformanceDouble();
} catch (final Exception e) {
e.printStackTrace();
}
diff --git a/www/index.html b/www/index.html
index 0394d27c6..c03e2bb79 100644
--- a/www/index.html
+++ b/www/index.html
@@ -401,11 +401,11 @@
</tr>
<tr>
<td width="50%">
- <a href="http://nifty-gui.lessvoid.com/"><img src="media/nifty-logo-new.png" width="160" align="left" alt="Nifty GUI"></img>
+ <a href="http://nifty-gui.github.io/nifty-gui/><img src="media/nifty-logo-new.png" width="160" align="left" alt="Nifty GUI"></img>
Nifty GUI</a> is a Java Library that supports the building of interactive user interfaces for games or similar applications.
The configuration of the GUI is stored in xml files with little supporting Java code.
In short Nifty helps you to layout stuff, display it in a cool way and interact with it :)<br/>
- Source code is available in this <a href="https://github.com/void256/nifty-gui">git repository</a>.
+ Source code is available in this <a href="https://github.com/nifty-gui/nifty-gui">git repository</a>.
JOGL is one renderer backend besides others.
</td>
<td width="50%">
@@ -441,30 +441,6 @@
</td>
</tr>
<tr>
- <td width="50%">
- <a href="http://www.disti.com/Products/glstudio/index.html"><img
- src="media/glstudio.jpg" width="160" height="135" align="left" alt="GL Studio"></img>
- GL Studio</a> is an object oriented rapid application
- development tool that allows a user to graphically combine
- photographs, 3D models and behavior logic to create advanced 2D and 3D
- human machine interfaces. GL Studio generates Java or C++ source code
- which can then be integrated into the user’s application as a user
- interface.
- Java code using JOGL can be exported.
- An <a href="http://www.disti.com/Products/demonstrations/java.html">F-16 Flight Simulator using NASA World Wind is demonstrated</a>.
- </td>
- <td width="50%">
- <a href="http://www.dok-ing.hr/solutions/myhmi"><img src="media/MyHmi-Collage-160x152.png"
- width="160" height="152" align="left" alt="MyHMI"></img>MyHMI</a>
- is a Java based object oriented software framework for industrial graphical user interfaces development.
- It enables creation of visually adjustable interfaces for embedded systems, independently of underlying OS
- or hardware platform, communication or data processing mechanisms.
- An expressive and comprehensive 3D visualization MyHMI provides, is based on
- a low level OpenGL and OpenGL ES standards and a higher interlayer
- based on JOGL enabling multiplatform compatibility.
- </td>
- </tr>
- <tr>
<td width="50%">
<a href="http://jebgl.com/"><img src="media/JebGL_logo.160w.png"
width="160" height="87" align="left" alt="JebGL"></img>JebGL</a>