diff options
Diffstat (limited to 'src/jogl/native')
-rw-r--r-- | src/jogl/native/GLDebugMessageHandler.c | 181 | ||||
-rw-r--r-- | src/jogl/native/JoglCommon.c | 55 | ||||
-rw-r--r-- | src/jogl/native/JoglCommon.h | 15 |
3 files changed, 251 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); +} + diff --git a/src/jogl/native/JoglCommon.c b/src/jogl/native/JoglCommon.c new file mode 100644 index 000000000..16f60e4e7 --- /dev/null +++ b/src/jogl/native/JoglCommon.c @@ -0,0 +1,55 @@ + +#include "JoglCommon.h" + +static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException"; +static jclass runtimeExceptionClz=NULL; + +void JoglCommon_FatalError(JNIEnv *env, const char* msg, ...) +{ + char buffer[512]; + va_list ap; + + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); + + fprintf(stderr, "%s\n", buffer); + (*env)->FatalError(env, buffer); +} + +void JoglCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...) +{ + char buffer[512]; + va_list ap; + + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); + + (*env)->ThrowNew(env, runtimeExceptionClz, buffer); +} + +void JoglCommon_init(JNIEnv *env) { + if(NULL==runtimeExceptionClz) { + jclass c = (*env)->FindClass(env, ClazzNameRuntimeException); + if(NULL==c) { + JoglCommon_FatalError(env, "JOGL: can't find %s", ClazzNameRuntimeException); + } + runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==runtimeExceptionClz) { + JoglCommon_FatalError(env, "JOGL: can't use %s", ClazzNameRuntimeException); + } + } +} + +jchar* JoglCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str) +{ + jchar* strChars = NULL; + strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); + if (strChars != NULL) { + (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + } + return strChars; +} + diff --git a/src/jogl/native/JoglCommon.h b/src/jogl/native/JoglCommon.h new file mode 100644 index 000000000..d82b445ce --- /dev/null +++ b/src/jogl/native/JoglCommon.h @@ -0,0 +1,15 @@ + +#ifndef JOGL_COMMON_H +#define JOGL_COMMON_H 1 + +#include <jni.h> +#include <stdlib.h> + +void JoglCommon_init(JNIEnv *env); + +jchar* JoglCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str); + +void JoglCommon_FatalError(JNIEnv *env, const char* msg, ...); +void JoglCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...); + +#endif |