Linux: Release context before destroying it

This commit is contained in:
Elias Naur 2005-01-12 12:20:53 +00:00
parent b27a9697ff
commit 7d8cc6abbb
3 changed files with 37 additions and 25 deletions

View File

@ -108,11 +108,16 @@
* get the current window
*/
extern Window getCurrentWindow(void);
/*
* Release the context if it is current
*/
extern bool releaseContext(GLXContext context);
/*
* get the current context
*/
extern GLXContext getCurrentGLXContext(void);
extern GLXContext getDisplayContext(void);
/*
* get the current GLXFBConfig for the current context

View File

@ -69,7 +69,7 @@ typedef struct {
typedef enum {FULLSCREEN_LEGACY, FULLSCREEN_NETWM, WINDOWED} window_mode;
static GLXContext context = NULL; // OpenGL rendering context
static GLXContext display_context = NULL; // OpenGL rendering context
static GLXFBConfig *configs = NULL;
static GLXWindow glx_window;
static XVisualInfo *vis_info = NULL;
@ -101,8 +101,8 @@ GLXFBConfig getCurrentGLXFBConfig(void) {
return configs[0];
}
GLXContext getCurrentGLXContext(void) {
return context;
GLXContext getDisplayContext(void) {
return display_context;
}
int getCurrentScreen(void) {
@ -443,11 +443,20 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nUpdate
handleMessages(env);
}
bool releaseContext(GLXContext context) {
if (glXGetCurrentContext() != context)
return true;
if (USEGLX13)
return glXMakeContextCurrent(getDisplay(), None, None, NULL) == True;
else
return glXMakeCurrent(getDisplay(), None, NULL) == True;
}
static bool makeCurrent(void) {
if (USEGLX13)
return glXMakeContextCurrent(getDisplay(), glx_window, glx_window, context) == True;
return glXMakeContextCurrent(getDisplay(), glx_window, glx_window, display_context) == True;
else
return glXMakeCurrent(getDisplay(), getCurrentWindow(), context) == True;
return glXMakeCurrent(getDisplay(), getCurrentWindow(), display_context) == True;
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nMakeCurrent
@ -472,10 +481,6 @@ int convertToBPE(int bpp) {
return bpe;
}
GLXContext getCurrentContext(void) {
return context;
}
static GLXFBConfig *chooseVisualGLX13FromBPP(JNIEnv *env, jobject pixel_format, int bpp, int drawable_type, bool double_buffer) {
jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format);
int alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "alpha", "I"));
@ -600,8 +605,9 @@ static void destroyContext(void) {
}
XFree(vis_info);
vis_info = NULL;
glXDestroyContext(getDisplay(), context);
context = NULL;
releaseContext(display_context);
glXDestroyContext(getDisplay(), display_context);
display_context = NULL;
}
static bool initWindowGLX13(JNIEnv *env, jobject pixel_format) {
@ -610,28 +616,28 @@ static bool initWindowGLX13(JNIEnv *env, jobject pixel_format) {
throwException(env, "Could not find a matching pixel format");
return false;
}
context = glXCreateNewContext(getDisplay(), configs[0], GLX_RGBA_TYPE, NULL, True);
if (context == NULL) {
display_context = glXCreateNewContext(getDisplay(), configs[0], GLX_RGBA_TYPE, NULL, True);
if (display_context == NULL) {
XFree(configs);
throwException(env, "Could not create a GLX context");
return false;
}
jboolean allow_software_acceleration = getBooleanProperty(env, "org.lwjgl.opengl.Window.allowSoftwareOpenGL");
if (!allow_software_acceleration && (glXIsDirect(getDisplay(), context) == False)) {
glXDestroyContext(getDisplay(), context);
if (!allow_software_acceleration && (glXIsDirect(getDisplay(), display_context) == False)) {
glXDestroyContext(getDisplay(), display_context);
XFree(configs);
throwException(env, "Could not create a direct GLX context");
return false;
}
vis_info = glXGetVisualFromFBConfig(getDisplay(), configs[0]);
if (vis_info == NULL) {
glXDestroyContext(getDisplay(), context);
glXDestroyContext(getDisplay(), display_context);
XFree(configs);
throwException(env, "Could not get visual from FB config");
return false;
}
if (!checkXError(env)) {
glXDestroyContext(getDisplay(), context);
glXDestroyContext(getDisplay(), display_context);
XFree(configs);
XFree(vis_info);
return false;
@ -647,21 +653,21 @@ static bool initWindowGLX(JNIEnv *env, jobject pixel_format) {
}
if (isDebugEnabled())
dumpVisualInfo(env, vis_info);
context = glXCreateContext(getDisplay(), vis_info, NULL, True);
if (context == NULL) {
display_context = glXCreateContext(getDisplay(), vis_info, NULL, True);
if (display_context == NULL) {
XFree(vis_info);
throwException(env, "Could not create a GLX context");
return false;
}
jboolean allow_software_acceleration = getBooleanProperty(env, "org.lwjgl.opengl.Window.allowSoftwareOpenGL");
if (!allow_software_acceleration && glXIsDirect(getDisplay(), context) == False) {
glXDestroyContext(getDisplay(), context);
if (!allow_software_acceleration && glXIsDirect(getDisplay(), display_context) == False) {
glXDestroyContext(getDisplay(), display_context);
XFree(vis_info);
throwException(env, "Could not create a direct GLX context");
return false;
}
if (!checkXError(env)) {
glXDestroyContext(getDisplay(), context);
glXDestroyContext(getDisplay(), display_context);
XFree(vis_info);
return false;
}
@ -741,7 +747,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateWindow(JNIEnv *
dumpVisualInfo(env, vis_info);
if (USEGLX13)
glx_window = glXCreateWindow(getDisplay(), configs[0], getCurrentWindow(), NULL);
if (!makeCurrent() || !checkXError(env)) {
if (!checkXError(env)) {
glXDestroyWindow(getDisplay(), glx_window);
destroyWindow(env);
}

View File

@ -62,6 +62,7 @@ static void destroyPbuffer(PbufferInfo *buffer_info) {
GLXPbuffer buffer = buffer_info->buffer;
GLXContext context = buffer_info->context;
glXDestroyPbuffer(getDisplay(), buffer);
releaseContext(context);
glXDestroyContext(getDisplay(), context);
decDisplay();
}
@ -143,7 +144,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreatePbuffer(JNIEnv
throwException(env, "Handle buffer not large enough");
return;
}
GLXContext shared_context = getCurrentGLXContext();
GLXContext shared_context = getDisplayContext();
if (shared_context_handle_buffer != NULL) {
PbufferInfo *shared_buffer_info = (PbufferInfo *)(*env)->GetDirectBufferAddress(env, shared_context_handle_buffer);
shared_context = shared_buffer_info->context;