summaryrefslogtreecommitdiffstats
path: root/src/nativewindow/native/x11/Xmisc.c
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-09-27 17:33:39 +0200
committerSven Gothel <[email protected]>2012-09-27 17:33:39 +0200
commitfbe331f013608eb31ff0d8675f4e4c9881c9c48b (patch)
tree535aae61f299884ce6b61d026a60ed0546e9703b /src/nativewindow/native/x11/Xmisc.c
parentba846a478d616327817dd530dbdcd9a786be5b7a (diff)
Fix Bug 616: X11: Remove XInitThreads() dependency while cleaning up device locking, resulting in a native-lock-free impl.
The X11 implementation details of NativeWindow and NEWT used the X11 implicit locking facility XLockDisplay/XUnlockDisplay, enabled via XInitThreads(). The latter useage is complicated within an unsure environment where the initialization point of JOGL is unknown, but XInitThreads() requires to be called once and before any other X11 calls. The solution is simple and thorough, replace native X11 locking w/ 'application level' locking. Following this pattern actually cleans up a pretty messy part of X11 NativeWindow and NEWT, since the generalization of platform independent locking simplifies code. Simply using our RecursiveLock also speeds up locking, since it doesn't require JNI calls down to X11 anymore. It allows us to get rid of X11ToolkitLock and X11JAWTToolkitLock. Using the RecursiveLock also allows us to remove the shortcut of explicitly createing a NullToolkitLocked device for 'private' display connections. All devices use proper locking as claimed in their toolkit util 'requiresToolkitLock()' in X11Util, OSXUtil, .. Further more a bug has been fixed of X11ErrorHandler usage, i.e. we need to keep our handler alive at all times due to async X11 messaging behavior. This allows to remove the redundant code in X11/NEWT. The AbstractGraphicsDevice lifecycle has been fixed as well, i.e. called when closing NEWT's Display for all driver implementations. On the NEWT side the Display's AbstractGraphicsDevice semantics has been clarified, i.e. it's usage for EDT and lifecycle operations. Hence the X11 Display 2nd device for rendering operations has been moved to X11 Window where it belongs - and the X11 Display's default device used for EDT/lifecycle-ops as it should be. This allows running X11/NEWT properly with the default usage, where the Display instance and hence the EDT thread is shared with many Screen and Window. Rendering using NEWT Window is decoupled from it's shared Display lock via it's own native X11 display. Lock free AbstractGraphicsDevice impl. (Windows, OSX, ..) don't require any attention in this regard since they use NullToolkitLock. Tests: ====== This implementation has been tested manually with Mesa3d (soft, Intel), ATI and Nvidia on X11, Windows and OSX w/o any regressions found in any unit test. Issues on ATI: ============== Only on ATI w/o a composite renderer the unit tests expose a driver or WM bug where XCB claims a lack of locking. Setting env. var 'LIBXCB_ALLOW_SLOPPY_LOCK=true' is one workaround if users refuse to enable compositing. We may investigate this issue in more detail later on.
Diffstat (limited to 'src/nativewindow/native/x11/Xmisc.c')
-rw-r--r--src/nativewindow/native/x11/Xmisc.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index fcba8580c..afdd413eb 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -178,11 +178,14 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
char threadName[80];
char errCodeStr[80];
char reqCodeStr[80];
-
int shallBeDetached = 0;
- JNIEnv *jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ JNIEnv *jniEnv = NULL;
+ if( errorHandlerDebug || errorHandlerThrowException ) {
+ jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ }
(void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
+
snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code);
XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr));
XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr));
@@ -191,7 +194,7 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
(int)e->request_code, (int)e->minor_code, reqCodeStr);
- if( errorHandlerDebug ) {
+ if( errorHandlerDebug && NULL != jniEnv ) {
(*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID);
}
@@ -246,16 +249,17 @@ static int x11IOErrorHandler(Display *dpy)
{
const char * dpyName = XDisplayName(NULL);
const char * errnoStr = strerror(errno);
- char threadName[80];
int shallBeDetached = 0;
- JNIEnv *jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
-
- (void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
+ JNIEnv *jniEnv = NULL;
- fprintf(stderr, "Nativewindow X11 IOError (Thread %s): Display %p (%s): %s\n", threadName, dpy, dpyName, errnoStr);
+ fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, dpyName, errnoStr);
(*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID);
+ jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if (NULL != jniEnv) {
+ char threadName[80];
+ (void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a");
+
NativewindowCommon_FatalError(jniEnv, "Nativewindow X11 IOError (Thread %s): Display %p (%s): %s", threadName, dpy, dpyName, errnoStr);
if (shallBeDetached) {
@@ -305,6 +309,7 @@ Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass clazz, jboo
_initClazzAccess(env);
x11IOErrorHandlerEnable(1, env);
+ NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, 0, 0 /* no dpy, no sync */);
_initialized=1;
if(JNI_TRUE == debug) {
fprintf(stderr, "Info: NativeWindow native init passed\n");
@@ -315,6 +320,7 @@ Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass clazz, jboo
JNIEXPORT void JNICALL
Java_jogamp_nativewindow_x11_X11Util_shutdown0(JNIEnv *env, jclass _unused) {
+ NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0 /* no dpy, no sync */);
x11IOErrorHandlerEnable(0, env);
}
@@ -347,7 +353,7 @@ Java_jogamp_nativewindow_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBuffer_2Lja
}
NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 1, 0, 0);
_res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3);
- NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, 0);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, 0);
count = _ptr3[0];
if (arg3 != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0);
@@ -382,7 +388,7 @@ Java_jogamp_nativewindow_x11_X11Lib_GetVisualIDFromWindow(JNIEnv *env, jclass _u
} else {
r = 0;
}
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
return r;
}
@@ -396,7 +402,7 @@ Java_jogamp_nativewindow_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused,
}
NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 1, 0, 0);
r = (jint) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) );
- NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 0, 0);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 0, 0);
return r;
}
@@ -439,7 +445,7 @@ Java_jogamp_nativewindow_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused
}
NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, 0, 0);
_res = XCloseDisplay((Display *) (intptr_t) display);
- NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0);
return _res;
}
@@ -497,7 +503,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
if (visual==NULL)
{
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!");
return 0;
}
@@ -541,7 +547,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
XSelectInput(dpy, window, 0); // no events
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", window, dpy);
@@ -569,7 +575,7 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow
XUnmapWindow(dpy, w);
XSync(dpy, False);
XDestroyWindow(dpy, w);
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
}
/*
@@ -597,7 +603,7 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_x11_X11Lib_GetRelativeLocatio
res = XTranslateCoordinates(dpy, src_win, dest_win, src_x, src_y, &dest_x, &dest_y, &child);
- NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0);
DBG_PRINT( "X11: GetRelativeLocation0: %p %d/%d -> %p %d/%d - ok: %d\n",
(void*)src_win, src_x, src_y, (void*)dest_win, dest_x, dest_y, (int)res);