aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java')
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java183
1 files changed, 100 insertions, 83 deletions
diff --git a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
index 0000e6199..7519d568b 100644
--- a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
+++ b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
@@ -27,75 +27,78 @@
*/
package jogamp.opengl;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.opengl.GL2ES2;
import javax.media.opengl.GL2GL3;
import javax.media.opengl.GLDebugListener;
import javax.media.opengl.GLDebugMessage;
import javax.media.opengl.GLException;
+import jogamp.common.os.PlatformPropsImpl;
+
import com.jogamp.common.os.Platform;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.opengl.GLExtensions;
-import jogamp.opengl.gl4.GL4bcProcAddressTable;
-
/**
* The GLDebugMessageHandler, handling <i>GL_ARB_debug_output</i> or <i>GL_AMD_debug_output</i>
* debug messages.<br>
- *
+ *
* <p>An instance must be bound to the current thread's GLContext to achieve thread safety.</p>
- *
- * <p>A native callback function is registered at {@link #enable(boolean) enable(true)},
- * which forwards received messages to the added {@link GLDebugListener} directly.
+ *
+ * <p>A native callback function is registered at {@link #enable(boolean) enable(true)},
+ * which forwards received messages to the added {@link GLDebugListener} directly.
* Hence the {@link GLDebugListener#messageSent(GLDebugMessage)} implementation shall
* return as fast as possible.</p>
- *
+ *
* <p>In case no <i>GL_ARB_debug_output</i> is available, but <i>GL_AMD_debug_output</i>,
* the messages are translated to <i>ARB</i> {@link GLDebugMessage}, using {@link GLDebugMessage#translateAMDEvent(javax.media.opengl.GLContext, long, int, int, int, String)}.</p>
*/
public class GLDebugMessageHandler {
private static final boolean DEBUG = Debug.debug("GLDebugMessageHandler");
-
+
private static final int EXT_ARB = 1;
- private static final int EXT_AMD = 2;
-
+ private static final int EXT_AMD = 2;
+
static {
if ( !initIDs0() ) {
throw new NativeWindowException("Failed to initialize GLDebugMessageHandler jmethodIDs");
- }
+ }
}
-
- private final GLContextImpl ctx;
+
+ private final GLContextImpl ctx;
private final ListenerSyncedImplStub<GLDebugListener> listenerImpl;
-
+
// licefycle: init - EOL
private String extName;
private int extType;
private long glDebugMessageCallbackProcAddress;
- private boolean extAvailable;
+ private boolean extAvailable;
private boolean synchronous;
-
+
// licefycle: enable - disable/EOL
private long handle;
-
+
/**
* @param ctx the associated GLContext
* @param glDebugExtension chosen extension to use
*/
- public GLDebugMessageHandler(GLContextImpl ctx) {
+ public GLDebugMessageHandler(final GLContextImpl ctx) {
this.ctx = ctx;
- this.listenerImpl = new ListenerSyncedImplStub<GLDebugListener>();
+ this.listenerImpl = new ListenerSyncedImplStub<GLDebugListener>();
this.glDebugMessageCallbackProcAddress = 0;
this.extName = null;
this.extType = 0;
- this.extAvailable = false;
+ this.extAvailable = false;
this.handle = 0;
this.synchronous = true;
}
-
- public void init(boolean enable) {
+
+ public void init(final boolean enable) {
if(DEBUG) {
System.err.println("GLDebugMessageHandler.init("+enable+")");
}
@@ -106,20 +109,33 @@ public class GLDebugMessageHandler {
System.err.println("GLDebugMessageHandler.init("+enable+") .. n/a");
}
}
-
+
+ private final long getAddressFor(final ProcAddressTable table, final String functionName) {
+ return AccessController.doPrivileged(new PrivilegedAction<Long>() {
+ @Override
+ public Long run() {
+ try {
+ return Long.valueOf( table.getAddressFor(functionName) );
+ } catch (final IllegalArgumentException iae) {
+ return Long.valueOf(0);
+ }
+ }
+ } ).longValue();
+ }
+
public void init() {
ctx.validateCurrent();
if( isAvailable()) {
return;
}
-
+
if( !ctx.isGLDebugEnabled() ) {
if(DEBUG) {
System.err.println("GLDebugMessageHandler: GL DEBUG not set in ARB ctx options: "+ctx.getGLVersion());
}
- return;
+ return;
}
- if(Platform.OS_TYPE == Platform.OSType.WINDOWS && Platform.is32Bit()) {
+ if(PlatformPropsImpl.OS_TYPE == Platform.OSType.WINDOWS && Platform.is32Bit()) {
// Currently buggy, ie. throws an exception after leaving the native callback.
// Probably a 32bit on 64bit JVM / OpenGL-driver issue.
if(DEBUG) {
@@ -137,102 +153,102 @@ public class GLDebugMessageHandler {
if(DEBUG) {
System.err.println("GLDebugMessageHandler: Using extension: <"+extName+">");
}
-
+
if(0 == extType) {
if(DEBUG) {
System.err.println("GLDebugMessageHandler: No extension available! "+ctx.getGLVersion());
System.err.println("GL_EXTENSIONS "+ctx.getGLExtensionCount());
- System.err.println(ctx.getGLExtensionsString());
+ System.err.println(ctx.getGLExtensionsString());
}
return;
}
-
+
final ProcAddressTable procAddressTable = ctx.getGLProcAddressTable();
- if( procAddressTable instanceof GL4bcProcAddressTable) {
- final GL4bcProcAddressTable desktopProcAddressTable = (GL4bcProcAddressTable)procAddressTable;
+ if( !ctx.isGLES1() && !ctx.isGLES2() ) {
switch(extType) {
- case EXT_ARB:
- glDebugMessageCallbackProcAddress = desktopProcAddressTable._addressof_glDebugMessageCallbackARB;
+ case EXT_ARB:
+ glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallbackARB");
break;
- case EXT_AMD:
- glDebugMessageCallbackProcAddress = desktopProcAddressTable._addressof_glDebugMessageCallbackAMD;
+ case EXT_AMD:
+ glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallbackAMD");
break;
}
} else {
+ glDebugMessageCallbackProcAddress = 0;
if(DEBUG) {
- System.err.println("Non desktop context not supported");
- }
+ System.err.println("Non desktop context not supported");
+ }
}
extAvailable = 0 < extType && null != extName && 0 != glDebugMessageCallbackProcAddress;
-
+
if(DEBUG) {
System.err.println("GLDebugMessageHandler: extAvailable: "+extAvailable+", glDebugMessageCallback* : 0x"+Long.toHexString(glDebugMessageCallbackProcAddress));
}
-
+
if(!extAvailable) {
glDebugMessageCallbackProcAddress = 0;
}
-
+
handle = 0;
}
public final boolean isAvailable() { return extAvailable; }
-
+
/**
- * @return The extension implementing the GLDebugMessage feature,
- * either {@link #GL_ARB_debug_output} or {@link #GL_AMD_debug_output}.
- * If unavailable <i>null</i> is returned.
+ * @return The extension implementing the GLDebugMessage feature,
+ * either {@link #GL_ARB_debug_output} or {@link #GL_AMD_debug_output}.
+ * If unavailable <i>null</i> is returned.
*/
public final String getExtension() {
return extName;
}
-
+
public final boolean isExtensionARB() {
return extName == GLExtensions.ARB_debug_output;
}
-
+
public final boolean isExtensionAMD() {
return extName == GLExtensions.AMD_debug_output;
}
-
+
/**
- * @see javax.media.opengl.GLContext#isGLDebugSynchronous()
+ * @see javax.media.opengl.GLContext#isGLDebugSynchronous()
*/
public final boolean isSynchronous() { return synchronous; }
-
+
/**
- * @see javax.media.opengl.GLContext#setGLDebugSynchronous(boolean)
+ * @see javax.media.opengl.GLContext#setGLDebugSynchronous(boolean)
*/
- public final void setSynchronous(boolean synchronous) {
+ public final void setSynchronous(final boolean synchronous) {
this.synchronous = synchronous;
if( isEnabled() ) {
setSynchronousImpl();
}
- }
+ }
private final void setSynchronousImpl() {
if(isExtensionARB()) {
if(synchronous) {
- ctx.getGL().glEnable(GL2GL3.GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+ ctx.getGL().glEnable(GL2ES2.GL_DEBUG_OUTPUT_SYNCHRONOUS);
} else {
- ctx.getGL().glDisable(GL2GL3.GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
- }
+ ctx.getGL().glDisable(GL2ES2.GL_DEBUG_OUTPUT_SYNCHRONOUS);
+ }
if(DEBUG) {
System.err.println("GLDebugMessageHandler: synchronous "+synchronous);
}
}
}
-
+
/**
- * @see javax.media.opengl.GLContext#enableGLDebugMessage(boolean)
+ * @see javax.media.opengl.GLContext#enableGLDebugMessage(boolean)
*/
- public final void enable(boolean enable) throws GLException {
+ public final void enable(final boolean enable) throws GLException {
ctx.validateCurrent();
if(!isAvailable()) {
return;
}
enableImpl(enable);
- }
- final void enableImpl(boolean enable) throws GLException {
+ }
+ final void enableImpl(final boolean enable) throws GLException {
if(enable) {
if(0 == handle) {
setSynchronousImpl();
@@ -245,32 +261,32 @@ public class GLDebugMessageHandler {
if(0 != handle) {
unregister0(glDebugMessageCallbackProcAddress, handle);
handle = 0;
- }
+ }
}
if(DEBUG) {
System.err.println("GLDebugMessageHandler: enable("+enable+") -> 0x" + Long.toHexString(handle));
}
}
-
+
public final boolean isEnabled() { return 0 != handle; }
- public final int listenerSize() {
- return listenerImpl.size();
+ public final int listenerSize() {
+ return listenerImpl.size();
}
-
- public final void addListener(GLDebugListener listener) {
+
+ public final void addListener(final GLDebugListener listener) {
listenerImpl.addListener(-1, listener);
}
- public final void addListener(int index, GLDebugListener listener) {
+ public final void addListener(final int index, final GLDebugListener listener) {
listenerImpl.addListener(index, listener);
}
-
- public final void removeListener(GLDebugListener listener) {
+
+ public final void removeListener(final GLDebugListener listener) {
listenerImpl.removeListener(listener);
}
-
- private final void sendMessage(GLDebugMessage msg) {
+
+ private final void sendMessage(final GLDebugMessage msg) {
synchronized(listenerImpl) {
if(DEBUG) {
System.err.println("GLDebugMessageHandler: "+msg);
@@ -281,39 +297,40 @@ public class GLDebugMessageHandler {
}
}
}
-
+
public static class StdErrGLDebugListener implements GLDebugListener {
boolean threadDump;
-
- public StdErrGLDebugListener(boolean threadDump) {
+
+ public StdErrGLDebugListener(final boolean threadDump) {
this.threadDump = threadDump;
}
- public void messageSent(GLDebugMessage event) {
+ @Override
+ public void messageSent(final GLDebugMessage event) {
System.err.println(event);
if(threadDump) {
Thread.dumpStack();
}
- }
+ }
}
-
+
//
// native -> java
//
-
- protected final void glDebugMessageARB(int source, int type, int id, int severity, String msg) {
+
+ protected final void glDebugMessageARB(final int source, final int type, final int id, final int severity, final String msg) {
final GLDebugMessage event = new GLDebugMessage(ctx, System.currentTimeMillis(), source, type, id, severity, msg);
sendMessage(event);
}
- protected final void glDebugMessageAMD(int id, int category, int severity, String msg) {
+ protected final void glDebugMessageAMD(final int id, final int category, final int severity, final String msg) {
final GLDebugMessage event = GLDebugMessage.translateAMDEvent(ctx, System.currentTimeMillis(), id, category, severity, msg);
sendMessage(event);
}
-
+
//
// java -> native
- //
-
+ //
+
private static native boolean initIDs0();
private native long register0(long glDebugMessageCallbackProcAddress, int extType);
private native void unregister0(long glDebugMessageCallbackProcAddress, long handle);