Linux: Moved display connection reference count to java. Linux: Load OpenGL library before opening display to work around a crash in NVIDIA drivers.

This commit is contained in:
Elias Naur 2005-03-29 11:31:22 +00:00
parent 6fe0155a44
commit c9fc024fa4
4 changed files with 44 additions and 38 deletions

View File

@ -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();

View File

@ -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 {

View File

@ -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 {

View File

@ -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) {