diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java')
-rw-r--r-- | src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java | 172 |
1 files changed, 92 insertions, 80 deletions
diff --git a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java index b950c2fdf..2c947693c 100644 --- a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java +++ b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java @@ -27,6 +27,8 @@ */ package jogamp.opengl; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayList; import javax.media.nativewindow.NativeWindowException; @@ -37,68 +39,62 @@ import javax.media.opengl.GLException; import com.jogamp.common.os.Platform; import com.jogamp.gluegen.runtime.ProcAddressTable; -import jogamp.opengl.gl4.GL4bcProcAddressTable; +import com.jogamp.opengl.GLExtensions; /** * 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 { - /** Extension <i>GL_ARB_debug_output</i> implementing GLDebugMessage */ - public static final String GL_ARB_debug_output = "GL_ARB_debug_output".intern(); - - /** Extension <i>GL_AMD_debug_output</i> implementing GLDebugMessage */ - public static final String GL_AMD_debug_output = "GL_AMD_debug_output".intern(); - 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(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) { if(DEBUG) { System.err.println("GLDebugMessageHandler.init("+enable+")"); @@ -110,18 +106,31 @@ 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 (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()) { // Currently buggy, ie. throws an exception after leaving the native callback. @@ -131,101 +140,103 @@ public class GLDebugMessageHandler { } return; } - if( ctx.isExtensionAvailable(GL_ARB_debug_output) ) { - extName = GL_ARB_debug_output; + if( ctx.isExtensionAvailable(GLExtensions.ARB_debug_output) ) { + extName = GLExtensions.ARB_debug_output; extType = EXT_ARB; - } else if( ctx.isExtensionAvailable(GL_AMD_debug_output) ) { - extName = GL_AMD_debug_output; + } else if( ctx.isExtensionAvailable(GLExtensions.AMD_debug_output) ) { + extName = GLExtensions.AMD_debug_output; extType = EXT_AMD; } 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()); } 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 == GL_ARB_debug_output; + return extName == GLExtensions.ARB_debug_output; } - + public final boolean isExtensionAMD() { - return extName == GL_AMD_debug_output; + 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) { 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(GL2GL3.GL_DEBUG_OUTPUT_SYNCHRONOUS); } else { - ctx.getGL().glDisable(GL2GL3.GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); - } + ctx.getGL().glDisable(GL2GL3.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 { ctx.validateCurrent(); @@ -233,7 +244,7 @@ public class GLDebugMessageHandler { return; } enableImpl(enable); - } + } final void enableImpl(boolean enable) throws GLException { if(enable) { if(0 == handle) { @@ -247,19 +258,19 @@ 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) { listenerImpl.addListener(-1, listener); } @@ -267,11 +278,11 @@ public class GLDebugMessageHandler { public final void addListener(int index, GLDebugListener listener) { listenerImpl.addListener(index, listener); } - + public final void removeListener(GLDebugListener listener) { listenerImpl.removeListener(listener); } - + private final void sendMessage(GLDebugMessage msg) { synchronized(listenerImpl) { if(DEBUG) { @@ -283,25 +294,26 @@ public class GLDebugMessageHandler { } } } - + public static class StdErrGLDebugListener implements GLDebugListener { boolean threadDump; - + public StdErrGLDebugListener(boolean threadDump) { this.threadDump = threadDump; } + @Override public void messageSent(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) { final GLDebugMessage event = new GLDebugMessage(ctx, System.currentTimeMillis(), source, type, id, severity, msg); sendMessage(event); @@ -311,11 +323,11 @@ public class GLDebugMessageHandler { 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); |