From c9fc024fa4441d06edad8d9ee54d91eeb0a53879 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Tue, 29 Mar 2005 11:31:22 +0000 Subject: [PATCH] Linux: Moved display connection reference count to java. Linux: Load OpenGL library before opening display to work around a crash in NVIDIA drivers. --- src/java/org/lwjgl/opengl/LinuxDisplay.java | 22 +++++++++- .../lwjgl/opengl/LinuxDisplayPeerInfo.java | 8 ++-- .../lwjgl/opengl/LinuxPbufferPeerInfo.java | 8 ++-- src/native/linux/org_lwjgl_opengl_Display.c | 44 +++++++------------ 4 files changed, 44 insertions(+), 38 deletions(-) diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index d6a9c36a..272db4b4 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -50,6 +50,8 @@ import org.lwjgl.input.Keyboard; final class LinuxDisplay implements DisplayImplementation { private static final int NUM_BUTTONS = 3; + private static int display_connection_usage_count = 0; + private static PeerInfo peer_info; /* Since Xlib is not guaranteed to be thread safe, we need a way to synchronize LWJGL @@ -62,8 +64,24 @@ final class LinuxDisplay implements DisplayImplementation { /** * increment and decrement display usage. */ - static native void incDisplay() throws LWJGLException; - static native void decDisplay(); + static void incDisplay() throws LWJGLException { + if (display_connection_usage_count == 0) { + openDisplay(); + } + display_connection_usage_count++; + } + + static void decDisplay() { + display_connection_usage_count--; + if (display_connection_usage_count < 0) + throw new InternalError("display_connection_usage_count < 0: " + display_connection_usage_count); + if (display_connection_usage_count == 0) { + closeDisplay(); + } + } + + private static native void openDisplay() throws LWJGLException; + private static native void closeDisplay(); public void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException { lockAWT(); diff --git a/src/java/org/lwjgl/opengl/LinuxDisplayPeerInfo.java b/src/java/org/lwjgl/opengl/LinuxDisplayPeerInfo.java index e1e5a527..0f8a10b4 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplayPeerInfo.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplayPeerInfo.java @@ -47,17 +47,17 @@ final class LinuxDisplayPeerInfo extends LinuxPeerInfo { public LinuxDisplayPeerInfo(PixelFormat pixel_format) throws LWJGLException { LinuxDisplay.lockAWT(); try { - LinuxDisplay.incDisplay(); + GLContext.loadOpenGLLibrary(); try { - GLContext.loadOpenGLLibrary(); + LinuxDisplay.incDisplay(); try { initDefaultPeerInfo(getHandle(), pixel_format); } catch (LWJGLException e) { - GLContext.unloadOpenGLLibrary(); + LinuxDisplay.decDisplay(); throw e; } } catch (LWJGLException e) { - LinuxDisplay.decDisplay(); + GLContext.unloadOpenGLLibrary(); throw e; } } finally { diff --git a/src/java/org/lwjgl/opengl/LinuxPbufferPeerInfo.java b/src/java/org/lwjgl/opengl/LinuxPbufferPeerInfo.java index 5d2a938d..8ccae829 100644 --- a/src/java/org/lwjgl/opengl/LinuxPbufferPeerInfo.java +++ b/src/java/org/lwjgl/opengl/LinuxPbufferPeerInfo.java @@ -47,17 +47,17 @@ final class LinuxPbufferPeerInfo extends LinuxPeerInfo { public LinuxPbufferPeerInfo(int width, int height, PixelFormat pixel_format) throws LWJGLException { LinuxDisplay.lockAWT(); try { - LinuxDisplay.incDisplay(); + GLContext.loadOpenGLLibrary(); try { - GLContext.loadOpenGLLibrary(); + LinuxDisplay.incDisplay(); try { nInitHandle(getHandle(), width, height, pixel_format); } catch (LWJGLException e) { - GLContext.unloadOpenGLLibrary(); + LinuxDisplay.decDisplay(); throw e; } } catch (LWJGLException e) { - LinuxDisplay.decDisplay(); + GLContext.unloadOpenGLLibrary(); throw e; } } finally { diff --git a/src/native/linux/org_lwjgl_opengl_Display.c b/src/native/linux/org_lwjgl_opengl_Display.c index e2444ff8..77470992 100644 --- a/src/native/linux/org_lwjgl_opengl_Display.c +++ b/src/native/linux/org_lwjgl_opengl_Display.c @@ -90,7 +90,6 @@ static bool grab; static int current_screen; static Display *display_connection = NULL; -static int display_connection_usage = 0; static bool async_x_error; static char error_message[ERR_MSG_SIZE]; static Atom warp_atom; @@ -127,36 +126,25 @@ Display *getDisplay(void) { return display_connection; } -static Display *incDisplay(JNIEnv *env) { - if (display_connection_usage == 0) { - async_x_error = false; - XSetErrorHandler(errorHandler); - display_connection = XOpenDisplay(NULL); - if (display_connection == NULL) { - if (env != NULL) - throwException(env, "Could not open X display connection"); - else - printfDebugJava(env, "Could not open X display connection"); - return NULL; - } - current_screen = XDefaultScreen(getDisplay()); - warp_atom = XInternAtom(display_connection, "_LWJGL_WARP", False); - } +static void openDisplay(JNIEnv *env) { async_x_error = false; - display_connection_usage++; - return display_connection; + XSetErrorHandler(errorHandler); + display_connection = XOpenDisplay(NULL); + if (display_connection == NULL) { + throwException(env, "Could not open X display connection"); + return; + } + current_screen = XDefaultScreen(getDisplay()); + warp_atom = XInternAtom(display_connection, "_LWJGL_WARP", False); } Atom getWarpAtom(void) { return warp_atom; } -static void decDisplay(void) { - display_connection_usage--; - if (display_connection_usage == 0) { - XCloseDisplay(display_connection); - display_connection = NULL; - } +static void closeDisplay(void) { + XCloseDisplay(display_connection); + display_connection = NULL; } static void waitMapped(Window win) { @@ -309,12 +297,12 @@ static void setWindowTitle(const char *title) { XStoreName(getDisplay(), current_win, title); } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_incDisplay(JNIEnv *env, jclass clazz) { - incDisplay(env); +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_openDisplay(JNIEnv *env, jclass clazz) { + openDisplay(env); } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_decDisplay(JNIEnv *env, jclass clazz) { - decDisplay(); +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_closeDisplay(JNIEnv *env, jclass clazz) { + closeDisplay(); } JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplayPeerInfo_initDrawable(JNIEnv *env, jclass clazz, jobject peer_info_handle) {