summaryrefslogtreecommitdiffstats
path: root/src/jogl/native
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/native')
-rw-r--r--src/jogl/native/GLDebugMessageHandler.c181
-rw-r--r--src/jogl/native/JoglCommon.c55
-rw-r--r--src/jogl/native/JoglCommon.h15
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