diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java')
-rw-r--r-- | src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java | 183 |
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); |