From 39c06a14abc8b6d8716fce40d64e8e0e93b00d34 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Mon, 5 Jul 2004 14:57:02 +0000 Subject: [PATCH] LINUX: Made pbuffer creation independent of the Display context --- src/java/org/lwjgl/opengl/Pbuffer.java | 24 ++-- src/native/common/Makefile.am | 1 - src/native/linux/Makefile.am | 1 + src/native/linux/org_lwjgl_opengl_Display.cpp | 84 +---------- .../linux/org_lwjgl_opengl_GLContext.cpp | 131 ++++++++++++++++++ src/native/linux/org_lwjgl_opengl_Pbuffer.cpp | 24 +--- .../org_lwjgl_opengl_GLContext.cpp | 0 .../win32/org_lwjgl_opengl_GLContext.cpp | 50 +++++++ 8 files changed, 202 insertions(+), 113 deletions(-) create mode 100644 src/native/linux/org_lwjgl_opengl_GLContext.cpp rename src/native/{common => macosx}/org_lwjgl_opengl_GLContext.cpp (100%) create mode 100644 src/native/win32/org_lwjgl_opengl_GLContext.cpp diff --git a/src/java/org/lwjgl/opengl/Pbuffer.java b/src/java/org/lwjgl/opengl/Pbuffer.java index 2d473137..c88d2c2e 100644 --- a/src/java/org/lwjgl/opengl/Pbuffer.java +++ b/src/java/org/lwjgl/opengl/Pbuffer.java @@ -161,9 +161,8 @@ public final class Pbuffer { /** * Construct an instance of a Pbuffer. If this fails then an LWJGLException will be thrown. The buffer is single-buffered. *

- * NOTE: An OpenGL window must be created before a Pbuffer can be created. The Pbuffer will have its own context that shares - * display lists and textures with the OpenGL window context, but it will have its own OpenGL state. Therefore, state changes - * to a pbuffer will not be seen in the window context and vice versa. + * NOTE: The Pbuffer will have its own context that shares display lists and textures with the Display context (if it is created), + * but it will have its own OpenGL state. Therefore, state changes to a pbuffer will not be seen in the window context and vice versa. *

* NOTE: Some OpenGL implementations requires the shared contexts to use the same pixel format. So if possible, use the same * bpp, alpha, depth and stencil values used to create the main window. @@ -181,12 +180,18 @@ public final class Pbuffer { this.width = width; this.height = height; - if ( renderTexture == null ) - handle = nCreate(width, height, pixel_format, null, null); - else - handle = nCreate(width, height, pixel_format, - renderTexture.pixelFormatCaps, - renderTexture.pBufferAttribs); + GLContext.loadOpenGLLibrary(); + try { + if ( renderTexture == null ) + handle = nCreate(width, height, pixel_format, null, null); + else + handle = nCreate(width, height, pixel_format, + renderTexture.pixelFormatCaps, + renderTexture.pBufferAttribs); + } catch (LWJGLException e) { + GLContext.unloadOpenGLLibrary(); + throw e; + } } /** @@ -245,6 +250,7 @@ public final class Pbuffer { int error = GL11.glGetError(); nDestroy(handle); GLContext.useContext(null); + GLContext.unloadOpenGLLibrary(); if (error != GL11.GL_NO_ERROR) throw new OpenGLException(error); } catch (LWJGLException e) { diff --git a/src/native/common/Makefile.am b/src/native/common/Makefile.am index 6de1fe5c..3465a4f0 100644 --- a/src/native/common/Makefile.am +++ b/src/native/common/Makefile.am @@ -37,7 +37,6 @@ COMMON = \ org_lwjgl_openal_eax_EAXBufferProperties.h \ org_lwjgl_openal_eax_EAXListenerProperties.cpp \ org_lwjgl_openal_eax_EAXListenerProperties.h \ - org_lwjgl_opengl_GLContext.cpp \ org_lwjgl_opengl_GL11.cpp \ org_lwjgl_opengl_GL11.h \ org_lwjgl_opengl_GL12.cpp \ diff --git a/src/native/linux/Makefile.am b/src/native/linux/Makefile.am index 284ff00d..9bc793d3 100644 --- a/src/native/linux/Makefile.am +++ b/src/native/linux/Makefile.am @@ -11,6 +11,7 @@ NATIVE = \ org_lwjgl_input_Cursor.cpp \ org_lwjgl_opengl_Display.cpp \ org_lwjgl_opengl_Pbuffer.cpp \ + org_lwjgl_opengl_GLContext.cpp \ display.cpp \ extgl_glx.cpp \ extxcursor.cpp diff --git a/src/native/linux/org_lwjgl_opengl_Display.cpp b/src/native/linux/org_lwjgl_opengl_Display.cpp index 0114a447..a60bda30 100644 --- a/src/native/linux/org_lwjgl_opengl_Display.cpp +++ b/src/native/linux/org_lwjgl_opengl_Display.cpp @@ -55,7 +55,6 @@ #include "org_lwjgl_opengl_Display.h" #define USEGLX13 extgl_Extensions.GLX13 -#define ERR_MSG_SIZE 1024 static GLXContext context = NULL; // OpenGL rendering context static GLXWindow glx_window; @@ -65,7 +64,6 @@ static GLXFBConfig *configs; static Atom delete_atom; static Colormap cmap; static Window current_win; -static int current_screen; static bool current_fullscreen; static int current_height; static int current_width; @@ -80,61 +78,6 @@ static bool closerequested; static bool grab; static bool ignore_motion_events; -static Display *display_connection = NULL; -static Atom warp_atom; -static int display_connection_usage = 0; -static bool async_x_error; -static char error_message[ERR_MSG_SIZE]; - -bool checkXError(JNIEnv *env) { - XSync(getDisplay(), False); - if (async_x_error) { - async_x_error = false; - throwException(env, error_message); - return false; - } else - return true; -} - -static int errorHandler(Display *disp, XErrorEvent *error) { - char err_msg_buffer[ERR_MSG_SIZE]; - XGetErrorText(disp, error->error_code, err_msg_buffer, ERR_MSG_SIZE); - err_msg_buffer[ERR_MSG_SIZE - 1] = '\0'; - snprintf(error_message, ERR_MSG_SIZE, "X Error - serial: %d, error_code: %s, request_code: %d, minor_code: %d", (int)error->serial, err_msg_buffer, (int)error->request_code, (int)error->minor_code); - error_message[ERR_MSG_SIZE - 1] = '\0'; - async_x_error = true; - return 0; -} - -Display *getDisplay(void) { - return display_connection; -} - -Display *incDisplay(JNIEnv *env) { - if (display_connection_usage == 0) { - async_x_error = false; - XSetErrorHandler(errorHandler); - display_connection = XOpenDisplay(NULL); - if (display_connection == NULL) { - throwException(env, "Could not open X display"); - return NULL; - } - warp_atom = XInternAtom(getDisplay(), "ignore_warp_atom", False); - } - display_connection_usage++; - return display_connection; -} - -Atom getWarpAtom(void) { - return warp_atom; -} - -void decDisplay(void) { - display_connection_usage--; - if (display_connection_usage == 0) - XCloseDisplay(display_connection); -} - static void waitMapped(Window win) { XEvent event; @@ -209,7 +152,7 @@ static void handleMessages() { XNextEvent(getDisplay(), &event); switch (event.type) { case ClientMessage: - if (event.xclient.message_type == warp_atom) { + if (event.xclient.message_type == getWarpAtom()) { ignore_motion_events = event.xclient.data.b[0] == 1 ? true : false; } else if ((event.xclient.format == 32) && ((Atom)event.xclient.data.l[0] == delete_atom)) closerequested = true; @@ -325,10 +268,6 @@ static bool createWindow(JNIEnv* env, int width, int height) { return true; } -int getCurrentScreen(void) { - return current_screen; -} - Window getCurrentWindow(void) { return current_win; } @@ -511,15 +450,14 @@ static void dumpVisualInfo(XVisualInfo *vis_info) { static void destroyContext(void) { releaseContext(); + context = NULL; if (USEGLX13) { glXDestroyWindow(getDisplay(), glx_window); XFree(configs); } XFree(vis_info); glXDestroyContext(getDisplay(), context); - context = NULL; setRepeatMode(AutoRepeatModeDefault); - decDisplay(); } static bool initWindowGLX13(JNIEnv *env, jobject pixel_format) { @@ -617,24 +555,10 @@ JNIEXPORT jstring JNICALL Java_org_lwjgl_opengl_Display_getVersion(JNIEnv *env, } JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_createContext(JNIEnv *env, jclass clazz, jobject pixel_format) { - Display *disp = incDisplay(env); - if (disp == NULL) - return; - current_screen = XDefaultScreen(disp); - if (!extgl_InitGLX(env, disp, current_screen)) { - decDisplay(); - throwException(env, "Could not init GLX"); - return; - } - bool create_success; if (USEGLX13) { - create_success = initWindowGLX13(env, pixel_format); + initWindowGLX13(env, pixel_format); } else { - create_success = initWindowGLX(env, pixel_format); - } - if (!create_success) { - decDisplay(); - return; + initWindowGLX(env, pixel_format); } } diff --git a/src/native/linux/org_lwjgl_opengl_GLContext.cpp b/src/native/linux/org_lwjgl_opengl_GLContext.cpp new file mode 100644 index 00000000..4ef30e8c --- /dev/null +++ b/src/native/linux/org_lwjgl_opengl_GLContext.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2002-2004 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "org_lwjgl_opengl_GLContext.h" +#include "extgl.h" +#include "extgl_glx.h" +#include "common_tools.h" +#include "Window.h" + +#define ERR_MSG_SIZE 1024 + +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; + +Atom getWarpAtom(void) { + return warp_atom; +} + +int getCurrentScreen(void) { + return current_screen; +} + +bool checkXError(JNIEnv *env) { + XSync(getDisplay(), False); + if (async_x_error) { + async_x_error = false; + throwException(env, error_message); + return false; + } else + return true; +} + +static int errorHandler(Display *disp, XErrorEvent *error) { + char err_msg_buffer[ERR_MSG_SIZE]; + XGetErrorText(disp, error->error_code, err_msg_buffer, ERR_MSG_SIZE); + err_msg_buffer[ERR_MSG_SIZE - 1] = '\0'; + snprintf(error_message, ERR_MSG_SIZE, "X Error - serial: %d, error_code: %s, request_code: %d, minor_code: %d", (int)error->serial, err_msg_buffer, (int)error->request_code, (int)error->minor_code); + error_message[ERR_MSG_SIZE - 1] = '\0'; + async_x_error = true; + return 0; +} + + +Display *getDisplay(void) { + return display_connection; +} + +Display *incDisplay(JNIEnv *env) { + if (display_connection_usage == 0) { + async_x_error = false; + XSetErrorHandler(errorHandler); + display_connection = XOpenDisplay(NULL); + if (display_connection == NULL) { + throwException(env, "Could not open X display"); + return NULL; + } + warp_atom = XInternAtom(getDisplay(), "ignore_warp_atom", False); + } + display_connection_usage++; + return display_connection; +} + +void decDisplay(void) { + display_connection_usage--; + if (display_connection_usage == 0) + XCloseDisplay(display_connection); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GLContext_nLoadOpenGLLibrary(JNIEnv * env, jclass clazz) { + if (!extgl_Open()) { + throwException(env, "Failed to load OpenGL library"); + return; + } + Display *disp = incDisplay(env); + if (disp == NULL) { + extgl_Close(); + return; + } + current_screen = XDefaultScreen(disp); + if (!extgl_InitGLX(env, disp, current_screen)) { + decDisplay(); + extgl_Close(); + throwException(env, "Could not init GLX"); + return; + } + +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GLContext_nUnloadOpenGLLibrary(JNIEnv * env, jclass clazz) { + decDisplay(); + extgl_Close(); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GLContext_resetNativeStubs(JNIEnv *env, jclass clazz, jclass gl_class) { + env->UnregisterNatives(gl_class); +} diff --git a/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp b/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp index b467aaac..f3dfa2e7 100644 --- a/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp +++ b/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp @@ -50,11 +50,6 @@ typedef struct _PbufferInfo { GLXContext context; } PbufferInfo; -/* - * Class: org_lwjgl_opengl_Pbuffer - * Method: nIsBufferLost - * Signature: (I)Z - */ JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Pbuffer_nIsBufferLost (JNIEnv *env, jclass clazz, jint handle) { @@ -62,11 +57,6 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Pbuffer_nIsBufferLost return JNI_FALSE; } -/* - * Class: org_lwjgl_opengl_Pbuffer - * Method: isPbufferSupported - * Signature: ()Z - */ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_getPbufferCaps (JNIEnv *env, jclass clazz) { @@ -80,19 +70,12 @@ static void destroyPbuffer(PbufferInfo *buffer_info) { glXDestroyPbuffer(getDisplay(), buffer); glXDestroyContext(getDisplay(), context); free(buffer_info); - decDisplay(); } -/* - * Class: org_lwjgl_opengl_Pbuffer - * Method: nCreate - */ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate(JNIEnv *env, jclass clazz, jint width, jint height, jobject pixel_format, jobject pixelFormatCaps, jobject pBufferAttribs) { - Display *disp = incDisplay(env); - if (disp == NULL) - return 0; + Display *disp = getDisplay(); GLXFBConfig *configs = chooseVisualGLX13(env, pixel_format, false, GLX_PBUFFER_BIT, false); if (configs == 0) { XFree(configs); @@ -142,11 +125,6 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_nCreate(JNIEnv *env, jclass return (jint)buffer_info; } -/* - * Class: org_lwjgl_opengl_Pbuffer - * Method: nMakeCurrent - * Signature: (I)V - */ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Pbuffer_nMakeCurrent (JNIEnv *env, jclass clazz, jint handle) { diff --git a/src/native/common/org_lwjgl_opengl_GLContext.cpp b/src/native/macosx/org_lwjgl_opengl_GLContext.cpp similarity index 100% rename from src/native/common/org_lwjgl_opengl_GLContext.cpp rename to src/native/macosx/org_lwjgl_opengl_GLContext.cpp diff --git a/src/native/win32/org_lwjgl_opengl_GLContext.cpp b/src/native/win32/org_lwjgl_opengl_GLContext.cpp new file mode 100644 index 00000000..1a383620 --- /dev/null +++ b/src/native/win32/org_lwjgl_opengl_GLContext.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2002-2004 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "org_lwjgl_opengl_GLContext.h" +#include "extgl.h" +#include "common_tools.h" + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GLContext_nLoadOpenGLLibrary(JNIEnv * env, jclass clazz) { + if (!extgl_Open()) { + throwException(env, "Failed to load OpenGL library"); + return; + } +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GLContext_nUnloadOpenGLLibrary(JNIEnv * env, jclass clazz) { + extgl_Close(); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GLContext_resetNativeStubs(JNIEnv *env, jclass clazz, jclass gl_class) { + env->UnregisterNatives(gl_class); +}