aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/native/GLDebugMessageHandler.c
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-04-24 12:21:36 +0200
committerSven Gothel <[email protected]>2011-04-24 12:21:36 +0200
commit6c0ad949be979d5fed95a1166d59100f7bf5580f (patch)
treed69242fabf1f066d43418612209597616fba6cdd /src/jogl/native/GLDebugMessageHandler.c
parentea819ff768d507c37a981c1ab0bdc0cad32c6a87 (diff)
Add unified support for GL_ARB_debug_output and GL_AMD_debug_output.
If GL_ARB_debug_output is not available, but GL_AMD_debug_output exist, fallback to the latter, offering generic aliased methods translating the delta (AMD category <-> ARB source/type). Generic aliased methods reside in GLContext* Enable/Disable via GLContext and GLAutoDrawable. To enable the GLDebugOutput feature GLContext.enableGLDebugMessage(true) or GLContext.setContextCreationFlags(GLContext.CTX_OPTION_DEBUG) shall be called _before_ context creation via GLContext.makeCurrent()! In case GLAutoDrawable is being used, GLAutoDrawable.setContextCreationFlags(GLContext.CTX_OPTION_DEBUG) shall be issued before context creation via GLContext.makeCurrent()!. After context creation, the GLDebugOutput feature may be enabled or disabled at any time using this method. Verify both unit tests for usability.
Diffstat (limited to 'src/jogl/native/GLDebugMessageHandler.c')
-rw-r--r--src/jogl/native/GLDebugMessageHandler.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/jogl/native/GLDebugMessageHandler.c b/src/jogl/native/GLDebugMessageHandler.c
new file mode 100644
index 000000000..22a7433f9
--- /dev/null
+++ b/src/jogl/native/GLDebugMessageHandler.c
@@ -0,0 +1,181 @@
+
+#include "jogamp_opengl_GLDebugMessageHandler.h"
+#include "JoglCommon.h"
+
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+static jmethodID glDebugMessageARB = NULL; // int source, int type, int id, int severity, String msg
+static jmethodID glDebugMessageAMD = NULL; // int id, int category, int severity, String msg
+
+typedef void (GLAPIENTRY* _local_PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const GLvoid *userParam);
+typedef void (GLAPIENTRY* _local_GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+
+typedef void (GLAPIENTRY* _local_PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, const GLvoid *userParam);
+typedef void (GLAPIENTRY* _local_GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+
+/*
+ * Class: jogamp_opengl_GLDebugMessageHandler
+ * Method: initIDs0
+ * Signature: (V)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_opengl_GLDebugMessageHandler_initIDs0
+ (JNIEnv *env, jclass clazz)
+{
+ JoglCommon_init(env);
+
+ glDebugMessageARB = (*env)->GetMethodID(env, clazz, "glDebugMessageARB", "(IIIILjava/lang/String;)V");
+ glDebugMessageAMD = (*env)->GetMethodID(env, clazz, "glDebugMessageAMD", "(IIILjava/lang/String;)V");
+
+ if ( NULL == glDebugMessageARB || NULL == glDebugMessageAMD ) {
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+typedef struct {
+ JavaVM *vm;
+ int version;
+ JNIEnv *env;
+ jobject obj;
+ int extType;
+} DebugHandlerType;
+
+
+// GLDEBUGARB(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+static void GLDebugMessageARBCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
+ GLsizei length, const GLchar *message, GLvoid *userParam) {
+ DebugHandlerType * handle = (DebugHandlerType*) (intptr_t) userParam;
+ JavaVM *vm = handle->vm;
+ int version = handle->version;
+ jobject obj = handle->obj;
+ JNIEnv *curEnv = NULL;
+ JNIEnv *newEnv = NULL;
+ int envRes ;
+
+ // retrieve this thread's JNIEnv curEnv - or detect it's detached
+ envRes = (*vm)->GetEnv(vm, (void **) &curEnv, version) ;
+ if( JNI_EDETACHED == envRes ) {
+ // detached thread - attach to JVM
+ if( JNI_OK != ( envRes = (*vm)->AttachCurrentThread(vm, (void**) &newEnv, NULL) ) ) {
+ fprintf(stderr, "GLDebugMessageARBCallback: can't attach thread: %d\n", envRes);
+ return;
+ }
+ curEnv = newEnv;
+ } else if( JNI_OK != envRes ) {
+ // oops ..
+ fprintf(stderr, "GLDebugMessageARBCallback: can't GetEnv: %d\n", envRes);
+ return;
+ }
+ (*curEnv)->CallVoidMethod(curEnv, obj, glDebugMessageARB,
+ (jint) source, (jint) type, (jint) id, (jint) severity,
+ (*curEnv)->NewStringUTF(curEnv, message));
+ if( NULL != newEnv ) {
+ // detached attached thread
+ (*vm)->DetachCurrentThread(vm);
+ }
+}
+
+// GLDEBUGAMD(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+static void GLDebugMessageAMDCallback(GLuint id, GLenum category, GLenum severity,
+ GLsizei length, const GLchar *message, GLvoid *userParam) {
+ DebugHandlerType * handle = (DebugHandlerType*) (intptr_t) userParam;
+ JavaVM *vm = handle->vm;
+ int version = handle->version;
+ jobject obj = handle->obj;
+ JNIEnv *curEnv = NULL;
+ JNIEnv *newEnv = NULL;
+ int envRes ;
+
+ // retrieve this thread's JNIEnv curEnv - or detect it's detached
+ envRes = (*vm)->GetEnv(vm, (void **) &curEnv, version) ;
+ if( JNI_EDETACHED == envRes ) {
+ // detached thread - attach to JVM
+ if( JNI_OK != ( envRes = (*vm)->AttachCurrentThread(vm, (void**) &newEnv, NULL) ) ) {
+ fprintf(stderr, "GLDebugMessageAMDCallback: can't attach thread: %d\n", envRes);
+ return;
+ }
+ curEnv = newEnv;
+ } else if( JNI_OK != envRes ) {
+ // oops ..
+ fprintf(stderr, "GLDebugMessageAMDCallback: can't GetEnv: %d\n", envRes);
+ return;
+ }
+ (*curEnv)->CallVoidMethod(curEnv, obj, glDebugMessageAMD,
+ (jint) id, (jint) category, (jint) severity,
+ (*curEnv)->NewStringUTF(curEnv, message));
+ if( NULL != newEnv ) {
+ // detached attached thread
+ (*vm)->DetachCurrentThread(vm);
+ }
+}
+
+
+/*
+ * Class: jogamp_opengl_GLDebugMessageHandler
+ * Method: register0
+ * Signature: (JI)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_opengl_GLDebugMessageHandler_register0
+ (JNIEnv *env, jobject obj, jlong procAddress, jint extType)
+{
+ JavaVM *vm;
+ DebugHandlerType * handle = malloc(sizeof(DebugHandlerType));
+ if(0 != (*env)->GetJavaVM(env, &vm)) {
+ vm = NULL;
+ JoglCommon_throwNewRuntimeException(env, "GetJavaVM failed");
+ }
+ handle->vm = vm;
+ handle->version = (*env)->GetVersion(env);
+ handle->env = env;
+ handle->obj = (*env)->NewGlobalRef(env, obj);
+ handle->extType = extType;
+
+ if(jogamp_opengl_GLDebugMessageHandler_EXT_ARB == extType) {
+ _local_PFNGLDEBUGMESSAGECALLBACKARBPROC ptr_glDebugMessageCallbackARB;
+ ptr_glDebugMessageCallbackARB = (_local_PFNGLDEBUGMESSAGECALLBACKARBPROC) (intptr_t) procAddress;
+ ptr_glDebugMessageCallbackARB((_local_GLDEBUGPROCARB)GLDebugMessageARBCallback, handle);
+ } else if(jogamp_opengl_GLDebugMessageHandler_EXT_AMD == extType) {
+ _local_PFNGLDEBUGMESSAGECALLBACKAMDPROC ptr_glDebugMessageCallbackAMD;
+ ptr_glDebugMessageCallbackAMD = (_local_PFNGLDEBUGMESSAGECALLBACKAMDPROC) (intptr_t) procAddress;
+ ptr_glDebugMessageCallbackAMD((_local_GLDEBUGPROCAMD)GLDebugMessageAMDCallback, handle);
+ } else {
+ JoglCommon_throwNewRuntimeException(env, "unsupported extension type %d", extType);
+ }
+
+ return (jlong) (intptr_t) handle;
+}
+
+/*
+ * Class: jogamp_opengl_GLDebugMessageHandler
+ * Method: unregister0
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_opengl_GLDebugMessageHandler_unregister0
+ (JNIEnv *env, jobject obj, jlong procAddress, jlong jhandle)
+{
+ DebugHandlerType * handle = (DebugHandlerType*) (intptr_t) jhandle;
+
+ if(env != handle->env) {
+ JoglCommon_throwNewRuntimeException(env, "wrong handle (env doesn't match)");
+ }
+ if(JNI_FALSE == (*env)->IsSameObject(env, obj, handle->obj)) {
+ JoglCommon_throwNewRuntimeException(env, "wrong handle (obj doesn't match)");
+ }
+
+ if(jogamp_opengl_GLDebugMessageHandler_EXT_ARB == handle->extType) {
+ _local_PFNGLDEBUGMESSAGECALLBACKARBPROC ptr_glDebugMessageCallbackARB;
+ ptr_glDebugMessageCallbackARB = (_local_PFNGLDEBUGMESSAGECALLBACKARBPROC) (intptr_t) procAddress;
+ ptr_glDebugMessageCallbackARB((_local_GLDEBUGPROCARB)NULL, NULL);
+ } else if(jogamp_opengl_GLDebugMessageHandler_EXT_AMD == handle->extType) {
+ _local_PFNGLDEBUGMESSAGECALLBACKAMDPROC ptr_glDebugMessageCallbackAMD;
+ ptr_glDebugMessageCallbackAMD = (_local_PFNGLDEBUGMESSAGECALLBACKAMDPROC) (intptr_t) procAddress;
+ ptr_glDebugMessageCallbackAMD((_local_GLDEBUGPROCAMD)NULL, NULL);
+ } else {
+ JoglCommon_throwNewRuntimeException(env, "unsupported extension type %d", handle->extType);
+ }
+
+ (*env)->DeleteGlobalRef(env, handle->obj);
+ free(handle);
+}
+