Linux: Handle different GLX capabilities on different screens

This commit is contained in:
Elias Naur 2005-02-24 10:44:34 +00:00
parent 165084e12d
commit bdcb68a582
9 changed files with 277 additions and 259 deletions

View File

@ -35,6 +35,7 @@ import java.nio.ByteBuffer;
import org.lwjgl.LWJGLException; import org.lwjgl.LWJGLException;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
import org.lwjgl.Sys;
/** /**
* $Id$ * $Id$
@ -131,11 +132,16 @@ final class LinuxContextImplementation implements ContextImplementation {
private static native boolean nIsCurrent(ByteBuffer context_handle) throws LWJGLException; private static native boolean nIsCurrent(ByteBuffer context_handle) throws LWJGLException;
public void setVSync(boolean enabled) { public void setVSync(boolean enabled) {
LinuxDisplay.lockAWT(); Context current_context = Context.getCurrentContext();
nSetVSync(enabled); if (current_context == null)
LinuxDisplay.unlockAWT(); throw new IllegalStateException("No context is current");
synchronized (current_context) {
LinuxDisplay.lockAWT();
nSetVSync(current_context.getHandle(), enabled);
LinuxDisplay.unlockAWT();
}
} }
private static native void nSetVSync(boolean enabled); private static native void nSetVSync(ByteBuffer context_handle, boolean enabled);
public void destroy(PeerInfo peer_info, ByteBuffer handle) throws LWJGLException { public void destroy(PeerInfo peer_info, ByteBuffer handle) throws LWJGLException {
LinuxDisplay.lockAWT(); LinuxDisplay.lockAWT();

View File

@ -359,9 +359,17 @@ final class LinuxDisplay implements DisplayImplementation {
public int getPbufferCapabilities() { public int getPbufferCapabilities() {
lockAWT(); lockAWT();
int caps = nGetPbufferCapabilities(); try {
unlockAWT(); incDisplay();
return caps; int caps = nGetPbufferCapabilities();
decDisplay();
return caps;
} catch (LWJGLException e) {
Sys.log("Exception occurred in getPbufferCapabilities: " + e);
return 0;
} finally {
unlockAWT();
}
} }
private static native int nGetPbufferCapabilities(); private static native int nGetPbufferCapabilities();

View File

@ -70,7 +70,7 @@ XVisualInfo *getVisualInfoFromPeerInfo(JNIEnv *env, X11PeerInfo *peer_info) {
GLXFBConfig *configs = getFBConfigFromPeerInfo(env, peer_info); GLXFBConfig *configs = getFBConfigFromPeerInfo(env, peer_info);
if (configs == NULL) if (configs == NULL)
return NULL; return NULL;
vis_info = glXGetVisualFromFBConfig(peer_info->display, configs[0]); vis_info = _glXGetVisualFromFBConfig(peer_info->display, configs[0]);
if (vis_info == NULL) if (vis_info == NULL)
throwException(env, "Could not get VisualInfo from GLX 1.3 config"); throwException(env, "Could not get VisualInfo from GLX 1.3 config");
XFree(configs); XFree(configs);
@ -81,7 +81,7 @@ XVisualInfo *getVisualInfoFromPeerInfo(JNIEnv *env, X11PeerInfo *peer_info) {
GLXFBConfig *getFBConfigFromPeerInfo(JNIEnv *env, X11PeerInfo *peer_info) { GLXFBConfig *getFBConfigFromPeerInfo(JNIEnv *env, X11PeerInfo *peer_info) {
int attribs[] = {GLX_FBCONFIG_ID, peer_info->config.glx13_config.config_id, None, None}; int attribs[] = {GLX_FBCONFIG_ID, peer_info->config.glx13_config.config_id, None, None};
int num_elements; int num_elements;
GLXFBConfig *configs = glXChooseFBConfig(peer_info->display, peer_info->screen, attribs, &num_elements); GLXFBConfig *configs = _glXChooseFBConfig(peer_info->display, peer_info->screen, attribs, &num_elements);
if (configs == NULL) { if (configs == NULL) {
throwException(env, "Could not find GLX 1.3 config from peer info"); throwException(env, "Could not find GLX 1.3 config from peer info");
return NULL; return NULL;
@ -140,13 +140,14 @@ static GLXFBConfig *chooseVisualGLX13FromBPP(JNIEnv *env, Display *disp, int scr
putAttrib(&attrib_list, GLX_ACCUM_BLUE_SIZE); putAttrib(&attrib_list, accum_bpe); putAttrib(&attrib_list, GLX_ACCUM_BLUE_SIZE); putAttrib(&attrib_list, accum_bpe);
putAttrib(&attrib_list, GLX_ACCUM_ALPHA_SIZE); putAttrib(&attrib_list, accum_alpha); putAttrib(&attrib_list, GLX_ACCUM_ALPHA_SIZE); putAttrib(&attrib_list, accum_alpha);
putAttrib(&attrib_list, GLX_STEREO); putAttrib(&attrib_list, stereo ? True : False); putAttrib(&attrib_list, GLX_STEREO); putAttrib(&attrib_list, stereo ? True : False);
if (samples > 0 && extension_flags.GLX_ARB_multisample) { // Assume the caller has checked support for multisample
if (samples > 0) {
putAttrib(&attrib_list, GLX_SAMPLE_BUFFERS_ARB); putAttrib(&attrib_list, 1); putAttrib(&attrib_list, GLX_SAMPLE_BUFFERS_ARB); putAttrib(&attrib_list, 1);
putAttrib(&attrib_list, GLX_SAMPLES_ARB); putAttrib(&attrib_list, samples); putAttrib(&attrib_list, GLX_SAMPLES_ARB); putAttrib(&attrib_list, samples);
} }
putAttrib(&attrib_list, None); putAttrib(&attrib_list, None); putAttrib(&attrib_list, None); putAttrib(&attrib_list, None);
int num_formats = 0; int num_formats = 0;
GLXFBConfig* configs = glXChooseFBConfig(disp, screen, attrib_list.attribs, &num_formats); GLXFBConfig* configs = _glXChooseFBConfig(disp, screen, attrib_list.attribs, &num_formats);
if (num_formats > 0) { if (num_formats > 0) {
return configs; return configs;
} else { } else {
@ -201,12 +202,13 @@ static XVisualInfo *chooseVisualGLXFromBPP(JNIEnv *env, Display *disp, int scree
putAttrib(&attrib_list, GLX_ACCUM_ALPHA_SIZE); putAttrib(&attrib_list, accum_alpha); putAttrib(&attrib_list, GLX_ACCUM_ALPHA_SIZE); putAttrib(&attrib_list, accum_alpha);
if (stereo) if (stereo)
putAttrib(&attrib_list, GLX_STEREO); putAttrib(&attrib_list, GLX_STEREO);
if (samples > 0 && extension_flags.GLX_ARB_multisample) { // Assume the caller has checked support for multisample
if (samples > 0) {
putAttrib(&attrib_list, GLX_SAMPLE_BUFFERS_ARB); putAttrib(&attrib_list, 1); putAttrib(&attrib_list, GLX_SAMPLE_BUFFERS_ARB); putAttrib(&attrib_list, 1);
putAttrib(&attrib_list, GLX_SAMPLES_ARB); putAttrib(&attrib_list, samples); putAttrib(&attrib_list, GLX_SAMPLES_ARB); putAttrib(&attrib_list, samples);
} }
putAttrib(&attrib_list, None); putAttrib(&attrib_list, None);
return glXChooseVisual(disp, screen, attrib_list.attribs); return _glXChooseVisual(disp, screen, attrib_list.attribs);
} }
XVisualInfo *chooseVisualGLX(JNIEnv *env, Display *disp, int screen, jobject pixel_format, bool use_display_bpp, bool double_buffer) { XVisualInfo *chooseVisualGLX(JNIEnv *env, Display *disp, int screen, jobject pixel_format, bool use_display_bpp, bool double_buffer) {
@ -224,19 +226,19 @@ XVisualInfo *chooseVisualGLX(JNIEnv *env, Display *disp, int screen, jobject pix
return chooseVisualGLXFromBPP(env, disp, screen, pixel_format, bpp, double_buffer); return chooseVisualGLXFromBPP(env, disp, screen, pixel_format, bpp, double_buffer);
} }
static void dumpVisualInfo(JNIEnv *env, Display *display, XVisualInfo *vis_info) { static void dumpVisualInfo(JNIEnv *env, Display *display, GLXExtensions *extension_flags, XVisualInfo *vis_info) {
int alpha, depth, stencil, r, g, b; int alpha, depth, stencil, r, g, b;
int sample_buffers = 0; int sample_buffers = 0;
int samples = 0; int samples = 0;
glXGetConfig(display, vis_info, GLX_RED_SIZE, &r); _glXGetConfig(display, vis_info, GLX_RED_SIZE, &r);
glXGetConfig(display, vis_info, GLX_GREEN_SIZE, &g); _glXGetConfig(display, vis_info, GLX_GREEN_SIZE, &g);
glXGetConfig(display, vis_info, GLX_BLUE_SIZE, &b); _glXGetConfig(display, vis_info, GLX_BLUE_SIZE, &b);
glXGetConfig(display, vis_info, GLX_ALPHA_SIZE, &alpha); _glXGetConfig(display, vis_info, GLX_ALPHA_SIZE, &alpha);
glXGetConfig(display, vis_info, GLX_DEPTH_SIZE, &depth); _glXGetConfig(display, vis_info, GLX_DEPTH_SIZE, &depth);
glXGetConfig(display, vis_info, GLX_STENCIL_SIZE, &stencil); _glXGetConfig(display, vis_info, GLX_STENCIL_SIZE, &stencil);
if (extension_flags.GLX_ARB_multisample) { if (extension_flags->GLX_ARB_multisample) {
glXGetConfig(display, vis_info, GLX_SAMPLE_BUFFERS_ARB, &sample_buffers); _glXGetConfig(display, vis_info, GLX_SAMPLE_BUFFERS_ARB, &sample_buffers);
glXGetConfig(display, vis_info, GLX_SAMPLES_ARB, &samples); _glXGetConfig(display, vis_info, GLX_SAMPLES_ARB, &samples);
} }
printfDebugJava(env, "Pixel format info: r = %d, g = %d, b = %d, a = %d, depth = %d, stencil = %d, sample buffers = %d, samples = %d", r, g, b, alpha, depth, stencil, sample_buffers, samples); printfDebugJava(env, "Pixel format info: r = %d, g = %d, b = %d, a = %d, depth = %d, stencil = %d, sample buffers = %d, samples = %d", r, g, b, alpha, depth, stencil, sample_buffers, samples);
} }
@ -247,7 +249,8 @@ bool initPeerInfo(JNIEnv *env, jobject peer_info_handle, Display *display, int s
return false; return false;
} }
X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_info_handle); X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_info_handle);
if (!extgl_InitGLX(display, screen)) { GLXExtensions extension_flags;
if (!extgl_InitGLX(display, screen, &extension_flags)) {
throwException(env, "Could not init GLX"); throwException(env, "Could not init GLX");
return false; return false;
} }
@ -255,18 +258,24 @@ bool initPeerInfo(JNIEnv *env, jobject peer_info_handle, Display *display, int s
throwException(env, "GLX13 is required, but is not available"); throwException(env, "GLX13 is required, but is not available");
return false; return false;
} }
jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format);
int samples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "samples", "I"));
if (samples > 0 && !extension_flags.GLX_ARB_multisample) {
throwException(env, "Samples > 0 specified but there's no support for GLX_ARB_multisample");
return false;
}
peer_info->glx13 = extension_flags.GLX13; peer_info->glx13 = extension_flags.GLX13;
if (peer_info->glx13) { if (peer_info->glx13) {
GLXFBConfig *configs = chooseVisualGLX13(env, display, screen, pixel_format, use_display_bpp, drawable_type, double_buffered); GLXFBConfig *configs = chooseVisualGLX13(env, display, screen, pixel_format, use_display_bpp, drawable_type, double_buffered);
if (isDebugEnabled()) { if (isDebugEnabled()) {
XVisualInfo *vis_info = glXGetVisualFromFBConfig(display, configs[0]); XVisualInfo *vis_info = _glXGetVisualFromFBConfig(display, configs[0]);
if (vis_info != NULL) { if (vis_info != NULL) {
dumpVisualInfo(env, display, vis_info); dumpVisualInfo(env, display, &extension_flags, vis_info);
XFree(vis_info); XFree(vis_info);
} }
} }
int config_id; int config_id;
int result = glXGetFBConfigAttrib(display, configs[0], GLX_FBCONFIG_ID, &config_id); int result = _glXGetFBConfigAttrib(display, configs[0], GLX_FBCONFIG_ID, &config_id);
XFree(configs); XFree(configs);
if (result != Success) { if (result != Success) {
throwException(env, "Could not choose GLX13 config"); throwException(env, "Could not choose GLX13 config");
@ -283,7 +292,7 @@ bool initPeerInfo(JNIEnv *env, jobject peer_info_handle, Display *display, int s
peer_info->config.glx_config.depth = vis_info->depth; peer_info->config.glx_config.depth = vis_info->depth;
peer_info->screen = vis_info->screen; peer_info->screen = vis_info->screen;
if (isDebugEnabled()) if (isDebugEnabled())
dumpVisualInfo(env, display, vis_info); dumpVisualInfo(env, display, &extension_flags, vis_info);
XFree(vis_info); XFree(vis_info);
} }
peer_info->display = display; peer_info->display = display;

View File

@ -32,185 +32,180 @@
#include <dlfcn.h> #include <dlfcn.h>
#include "extgl_glx.h" #include "extgl_glx.h"
GLXExtensions extension_flags; glXGetFBConfigsPROC _glXGetFBConfigs = NULL;
glXChooseFBConfigPROC _glXChooseFBConfig = NULL;
glXGetFBConfigsPROC glXGetFBConfigs = NULL; glXGetFBConfigAttribPROC _glXGetFBConfigAttrib = NULL;
glXChooseFBConfigPROC glXChooseFBConfig = NULL; glXGetVisualFromFBConfigPROC _glXGetVisualFromFBConfig = NULL;
glXGetFBConfigAttribPROC glXGetFBConfigAttrib = NULL; glXCreateWindowPROC _glXCreateWindow = NULL;
glXGetVisualFromFBConfigPROC glXGetVisualFromFBConfig = NULL; glXDestroyWindowPROC _glXDestroyWindow = NULL;
glXCreateWindowPROC glXCreateWindow = NULL; glXCreatePixmapPROC _glXCreatePixmap = NULL;
glXDestroyWindowPROC glXDestroyWindow = NULL; glXDestroyPixmapPROC _glXDestroyPixmap = NULL;
glXCreatePixmapPROC glXCreatePixmap = NULL; glXCreatePbufferPROC _glXCreatePbuffer = NULL;
glXDestroyPixmapPROC glXDestroyPixmap = NULL; glXDestroyPbufferPROC _glXDestroyPbuffer = NULL;
glXCreatePbufferPROC glXCreatePbuffer = NULL; glXQueryDrawablePROC _glXQueryDrawable = NULL;
glXDestroyPbufferPROC glXDestroyPbuffer = NULL; glXCreateNewContextPROC _glXCreateNewContext = NULL;
glXQueryDrawablePROC glXQueryDrawable = NULL; glXMakeContextCurrentPROC _glXMakeContextCurrent = NULL;
glXCreateNewContextPROC glXCreateNewContext = NULL; glXGetCurrentReadDrawablePROC _glXGetCurrentReadDrawable = NULL;
glXMakeContextCurrentPROC glXMakeContextCurrent = NULL; glXGetCurrentDisplayPROC _glXGetCurrentDisplay = NULL;
glXGetCurrentReadDrawablePROC glXGetCurrentReadDrawable = NULL; glXQueryContextPROC _glXQueryContext = NULL;
glXGetCurrentDisplayPROC glXGetCurrentDisplay = NULL; glXSelectEventPROC _glXSelectEvent = NULL;
glXQueryContextPROC glXQueryContext = NULL; glXGetSelectedEventPROC _glXGetSelectedEvent = NULL;
glXSelectEventPROC glXSelectEvent = NULL; glXChooseVisualPROC _glXChooseVisual = NULL;
glXGetSelectedEventPROC glXGetSelectedEvent = NULL; glXCopyContextPROC _glXCopyContext = NULL;
glXChooseVisualPROC glXChooseVisual = NULL; glXCreateContextPROC _glXCreateContext = NULL;
glXCopyContextPROC glXCopyContext = NULL; glXCreateGLXPixmapPROC _glXCreateGLXPixmap = NULL;
glXCreateContextPROC glXCreateContext = NULL; glXDestroyContextPROC _glXDestroyContext = NULL;
glXCreateGLXPixmapPROC glXCreateGLXPixmap = NULL; glXDestroyGLXPixmapPROC _glXDestroyGLXPixmap = NULL;
glXDestroyContextPROC glXDestroyContext = NULL; glXGetConfigPROC _glXGetConfig = NULL;
glXDestroyGLXPixmapPROC glXDestroyGLXPixmap = NULL; glXGetCurrentContextPROC _glXGetCurrentContext = NULL;
glXGetConfigPROC glXGetConfig = NULL; glXGetCurrentDrawablePROC _glXGetCurrentDrawable = NULL;
glXGetCurrentContextPROC glXGetCurrentContext = NULL; glXIsDirectPROC _glXIsDirect = NULL;
glXGetCurrentDrawablePROC glXGetCurrentDrawable = NULL; glXMakeCurrentPROC _glXMakeCurrent = NULL;
glXIsDirectPROC glXIsDirect = NULL; glXQueryExtensionPROC _glXQueryExtension = NULL;
glXMakeCurrentPROC glXMakeCurrent = NULL; glXQueryVersionPROC _glXQueryVersion = NULL;
glXQueryExtensionPROC glXQueryExtension = NULL; glXSwapBuffersPROC _glXSwapBuffers = NULL;
glXQueryVersionPROC glXQueryVersion = NULL; glXUseXFontPROC _glXUseXFont = NULL;
glXSwapBuffersPROC glXSwapBuffers = NULL; glXWaitGLPROC _glXWaitGL = NULL;
glXUseXFontPROC glXUseXFont = NULL; glXWaitXPROC _glXWaitX = NULL;
glXWaitGLPROC glXWaitGL = NULL; glXGetClientStringPROC _glXGetClientString = NULL;
glXWaitXPROC glXWaitX = NULL; glXQueryServerStringPROC _glXQueryServerString = NULL;
glXGetClientStringPROC glXGetClientString = NULL; glXQueryExtensionsStringPROC _glXQueryExtensionsString = NULL;
glXQueryServerStringPROC glXQueryServerString = NULL;
glXQueryExtensionsStringPROC glXQueryExtensionsString = NULL;
/* GLX_SGI_swap_control */ /* GLX_SGI_swap_control */
glXSwapIntervalSGIPROC glXSwapIntervalSGI = NULL; glXSwapIntervalSGIPROC _glXSwapIntervalSGI = NULL;
static void * lib_gl_handle = NULL; static void * lib_gl_handle = NULL;
typedef void * (APIENTRY * glXGetProcAddressARBPROC) (const GLubyte *procName); typedef void * (APIENTRY * glXGetProcAddressARBPROC) (const GLubyte *procName);
static glXGetProcAddressARBPROC glXGetProcAddressARB; static glXGetProcAddressARBPROC _glXGetProcAddressARB;
bool extgl_Open(JNIEnv *env) static GLXExtensions symbols_flags;
{
/** returns true if the extention is available */
static bool GLXQueryExtension(Display *disp, int screen, const char *name) {
const GLubyte *exts = (const GLubyte *)_glXQueryExtensionsString(disp, screen);
return extgl_QueryExtension(exts, name);
}
static void extgl_InitGLX13() {
ExtFunction functions[] = {
{"glXGetFBConfigs", (void*)&_glXGetFBConfigs},
{"glXChooseFBConfig", (void*)&_glXChooseFBConfig},
{"glXGetFBConfigAttrib", (void*)&_glXGetFBConfigAttrib},
{"glXGetVisualFromFBConfig", (void*)&_glXGetVisualFromFBConfig},
{"glXCreateWindow", (void*)&_glXCreateWindow},
{"glXDestroyWindow", (void*)&_glXDestroyWindow},
{"glXCreatePixmap", (void*)&_glXCreatePixmap},
{"glXDestroyPixmap", (void*)&_glXDestroyPixmap},
{"glXCreatePbuffer", (void*)&_glXCreatePbuffer},
{"glXDestroyPbuffer", (void*)&_glXDestroyPbuffer},
{"glXQueryDrawable", (void*)&_glXQueryDrawable},
{"glXCreateNewContext", (void*)&_glXCreateNewContext},
{"glXMakeContextCurrent", (void*)&_glXMakeContextCurrent},
{"glXGetCurrentReadDrawable", (void*)&_glXGetCurrentReadDrawable},
{"glXGetCurrentDisplay", (void*)&_glXGetCurrentDisplay},
{"glXQueryContext", (void*)&_glXQueryContext},
{"glXSelectEvent", (void*)&_glXSelectEvent},
{"glXGetSelectedEvent", (void*)&_glXGetSelectedEvent}};
symbols_flags.GLX13 = extgl_InitializeFunctions(sizeof(functions)/sizeof(ExtFunction), functions);
}
static void extgl_InitGLX12(void) {
ExtFunction functions[] = {
{"glXChooseVisual", (void*)&_glXChooseVisual},
{"glXCopyContext", (void*)&_glXCopyContext},
{"glXCreateContext", (void*)&_glXCreateContext},
{"glXCreateGLXPixmap", (void*)&_glXCreateGLXPixmap},
{"glXDestroyContext", (void*)&_glXDestroyContext},
{"glXDestroyGLXPixmap", (void*)&_glXDestroyGLXPixmap},
{"glXGetConfig", (void*)&_glXGetConfig},
{"glXGetCurrentContext", (void*)&_glXGetCurrentContext},
{"glXGetCurrentDrawable", (void*)&_glXGetCurrentDrawable},
{"glXIsDirect", (void*)&_glXIsDirect},
{"glXMakeCurrent", (void*)&_glXMakeCurrent},
{"glXQueryExtension", (void*)&_glXQueryExtension},
{"glXQueryVersion", (void*)&_glXQueryVersion},
{"glXSwapBuffers", (void*)&_glXSwapBuffers},
{"glXUseXFont", (void*)&_glXUseXFont},
{"glXWaitGL", (void*)&_glXWaitGL},
{"glXWaitX", (void*)&_glXWaitX},
{"glXGetClientString", (void*)&_glXGetClientString},
{"glXQueryServerString", (void*)&_glXQueryServerString},
{"glXQueryExtensionsString", (void*)&_glXQueryExtensionsString}};
symbols_flags.GLX12 = extgl_InitializeFunctions(sizeof(functions)/sizeof(ExtFunction), functions);
}
static void extgl_InitGLXSGISwapControl() {
ExtFunction functions[] = {
{"glXSwapIntervalSGI", (void*)&_glXSwapIntervalSGI}};
symbols_flags.GLX_SGI_swap_control = extgl_InitializeFunctions(sizeof(functions)/sizeof(ExtFunction), functions);
}
static void extgl_InitGLXSupportedExtensions(Display *disp, int screen, GLXExtensions *extension_flags) {
/* extension_flags.GLX_EXT_visual_info = GLXQueryExtension(disp, screen, "GLX_EXT_visual_info");
extension_flags.GLX_EXT_visual_rating = GLXQueryExtension(disp, screen, "GLX_EXT_visual_rating");*/
extension_flags->GLX_SGI_swap_control = symbols_flags.GLX_SGI_swap_control && GLXQueryExtension(disp, screen, "GLX_SGI_swap_control");
extension_flags->GLX_ARB_multisample = GLXQueryExtension(disp, screen, "GLX_ARB_multisample");
}
bool extgl_Open(JNIEnv *env) {
#define BUFFER_SIZE 2000 #define BUFFER_SIZE 2000
static char buffer[BUFFER_SIZE]; static char buffer[BUFFER_SIZE];
if (lib_gl_handle != NULL) if (lib_gl_handle != NULL)
return true; return true;
lib_gl_handle = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); lib_gl_handle = dlopen("libGL.so.1", RTLD_LAZY);
if (lib_gl_handle == NULL) { if (lib_gl_handle == NULL) {
snprintf(buffer, BUFFER_SIZE, "Error loading libGL.so.1: %s", dlerror()); snprintf(buffer, BUFFER_SIZE, "Error loading libGL.so.1: %s", dlerror());
buffer[BUFFER_SIZE - 1] = '\0'; buffer[BUFFER_SIZE - 1] = '\0';
throwException(env, buffer); throwException(env, buffer);
return false; return false;
} }
glXGetProcAddressARB = (glXGetProcAddressARBPROC)dlsym(lib_gl_handle, "glXGetProcAddressARB"); _glXGetProcAddressARB = (glXGetProcAddressARBPROC)dlsym(lib_gl_handle, "glXGetProcAddressARB");
if (glXGetProcAddressARB == NULL) { if (_glXGetProcAddressARB == NULL) {
extgl_Close(); extgl_Close();
throwException(env, "Could not get address of glXGetProcAddressARB"); throwException(env, "Could not get address of glXGetProcAddressARB");
return false; return false;
} }
/* Unlike Windows, GLX function addresses are context-independent
* so we only have to initialize the addresses once at load
*/
extgl_InitGLX12();
extgl_InitGLX13();
extgl_InitGLXSGISwapControl();
return true; return true;
} }
void *extgl_GetProcAddress(const char *name) void *extgl_GetProcAddress(const char *name) {
{ void *t = (void*)_glXGetProcAddressARB((const GLubyte*)name);
void *t = (void*)glXGetProcAddressARB((const GLubyte*)name); if (t == NULL) {
if (t == NULL)
{
t = dlsym(lib_gl_handle, name); t = dlsym(lib_gl_handle, name);
if (t == NULL) if (t == NULL) {
{
printfDebug("Could not locate symbol %s\n", name); printfDebug("Could not locate symbol %s\n", name);
} }
} }
return t; return t;
} }
void extgl_Close(void) void extgl_Close(void) {
{
dlclose(lib_gl_handle); dlclose(lib_gl_handle);
lib_gl_handle = NULL; lib_gl_handle = NULL;
} }
/** returns true if the extention is available */ bool extgl_InitGLX(Display *disp, int screen, GLXExtensions *extension_flags) {
static bool GLXQueryExtension(Display *disp, int screen, const char *name)
{
const GLubyte *exts = (const GLubyte *)glXQueryExtensionsString(disp, screen);
return extgl_QueryExtension(exts, name);
}
static void extgl_InitGLX13()
{
ExtFunction functions[] = {
{"glXGetFBConfigs", (void*)&glXGetFBConfigs},
{"glXChooseFBConfig", (void*)&glXChooseFBConfig},
{"glXGetFBConfigAttrib", (void*)&glXGetFBConfigAttrib},
{"glXGetVisualFromFBConfig", (void*)&glXGetVisualFromFBConfig},
{"glXCreateWindow", (void*)&glXCreateWindow},
{"glXDestroyWindow", (void*)&glXDestroyWindow},
{"glXCreatePixmap", (void*)&glXCreatePixmap},
{"glXDestroyPixmap", (void*)&glXDestroyPixmap},
{"glXCreatePbuffer", (void*)&glXCreatePbuffer},
{"glXDestroyPbuffer", (void*)&glXDestroyPbuffer},
{"glXQueryDrawable", (void*)&glXQueryDrawable},
{"glXCreateNewContext", (void*)&glXCreateNewContext},
{"glXMakeContextCurrent", (void*)&glXMakeContextCurrent},
{"glXGetCurrentReadDrawable", (void*)&glXGetCurrentReadDrawable},
{"glXGetCurrentDisplay", (void*)&glXGetCurrentDisplay},
{"glXQueryContext", (void*)&glXQueryContext},
{"glXSelectEvent", (void*)&glXSelectEvent},
{"glXGetSelectedEvent", (void*)&glXGetSelectedEvent}};
if (extension_flags.GLX13)
extension_flags.GLX13 = extgl_InitializeFunctions(sizeof(functions)/sizeof(ExtFunction), functions);
}
static bool extgl_InitGLX12(void)
{
ExtFunction functions[] = {
{"glXChooseVisual", (void*)&glXChooseVisual},
{"glXCopyContext", (void*)&glXCopyContext},
{"glXCreateContext", (void*)&glXCreateContext},
{"glXCreateGLXPixmap", (void*)&glXCreateGLXPixmap},
{"glXDestroyContext", (void*)&glXDestroyContext},
{"glXDestroyGLXPixmap", (void*)&glXDestroyGLXPixmap},
{"glXGetConfig", (void*)&glXGetConfig},
{"glXGetCurrentContext", (void*)&glXGetCurrentContext},
{"glXGetCurrentDrawable", (void*)&glXGetCurrentDrawable},
{"glXIsDirect", (void*)&glXIsDirect},
{"glXMakeCurrent", (void*)&glXMakeCurrent},
{"glXQueryExtension", (void*)&glXQueryExtension},
{"glXQueryVersion", (void*)&glXQueryVersion},
{"glXSwapBuffers", (void*)&glXSwapBuffers},
{"glXUseXFont", (void*)&glXUseXFont},
{"glXWaitGL", (void*)&glXWaitGL},
{"glXWaitX", (void*)&glXWaitX},
{"glXGetClientString", (void*)&glXGetClientString},
{"glXQueryServerString", (void*)&glXQueryServerString},
{"glXQueryExtensionsString", (void*)&glXQueryExtensionsString}};
return extgl_InitializeFunctions(sizeof(functions)/sizeof(ExtFunction), functions);
}
static void extgl_InitGLXSupportedExtensions(Display *disp, int screen)
{
extension_flags.GLX_EXT_visual_info = GLXQueryExtension(disp, screen, "GLX_EXT_visual_info");
extension_flags.GLX_EXT_visual_rating = GLXQueryExtension(disp, screen, "GLX_EXT_visual_rating");
extension_flags.GLX_SGI_swap_control = GLXQueryExtension(disp, screen, "GLX_SGI_swap_control");
extension_flags.GLX_ARB_multisample = GLXQueryExtension(disp, screen, "GLX_ARB_multisample");
}
static void extgl_InitGLXSGISwapControl()
{
ExtFunction functions[] = {
{"glXSwapIntervalSGI", (void*)&glXSwapIntervalSGI}};
if (extension_flags.GLX_SGI_swap_control)
extension_flags.GLX_SGI_swap_control = extgl_InitializeFunctions(sizeof(functions)/sizeof(ExtFunction), functions);
}
bool extgl_InitGLX(Display *disp, int screen)
{
int major, minor; int major, minor;
/* Assume glx ver >= 1.2 */ /* Assume glx ver >= 1.2 */
if (!extgl_InitGLX12()) // Check GLX 1.2 symbols available
if (!symbols_flags.GLX12)
return false; return false;
extension_flags.GLX12 = true; if (_glXQueryVersion(disp, &major, &minor) != True)
if (glXQueryVersion(disp, &major, &minor) != True)
return false; return false;
if (major > 1 || (major == 1 && minor >= 3)) bool glx12 = major > 1 || (major == 1 && minor >= 2);
extension_flags.GLX13 = true; // Check GLX 1.2 version
extgl_InitGLX13(); if (!glx12)
extgl_InitGLXSupportedExtensions(disp, screen); return false;
extgl_InitGLXSGISwapControl(); extension_flags->GLX12 = glx12;
extension_flags->GLX13 = major > 1 || (major == 1 && minor >= 3);
extgl_InitGLXSupportedExtensions(disp, screen, extension_flags);
return true; return true;
} }

View File

@ -37,7 +37,7 @@
#include "extgl.h" #include "extgl.h"
/* /*
* Names for attributes to glXGetConfig. * Names for attributes to _glXGetConfig.
*/ */
#define GLX_USE_GL 1 /* support GLX rendering */ #define GLX_USE_GL 1 /* support GLX rendering */
#define GLX_BUFFER_SIZE 2 /* depth of the color buffer */ #define GLX_BUFFER_SIZE 2 /* depth of the color buffer */
@ -91,7 +91,7 @@
#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A #define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A
/* /*
* Error return values from glXGetConfig. Success is indicated by * Error return values from _glXGetConfig. Success is indicated by
* a value of 0. * a value of 0.
*/ */
#define GLX_BAD_SCREEN 1 /* screen # is bad */ #define GLX_BAD_SCREEN 1 /* screen # is bad */
@ -106,7 +106,7 @@
/* FBConfig attribute values */ /* FBConfig attribute values */
/* /*
* Generic "don't care" value for glX ChooseFBConfig attributes (except * Generic "don't care" value for _glX ChooseFBConfig attributes (except
* GLX_LEVEL). * GLX_LEVEL).
*/ */
#define GLX_DONT_CARE 0xFFFFFFFF #define GLX_DONT_CARE 0xFFFFFFFF
@ -143,7 +143,7 @@
#define GLX_TRANSPARENT_RGB 0x8008 #define GLX_TRANSPARENT_RGB 0x8008
#define GLX_TRANSPARENT_INDEX 0x8009 #define GLX_TRANSPARENT_INDEX 0x8009
/* glXCreateGLXPbuffer attributes */ /* _glXCreateGLXPbuffer attributes */
#define GLX_PRESERVED_CONTENTS 0x801B #define GLX_PRESERVED_CONTENTS 0x801B
#define GLX_LARGEST_PBUFFER 0x801C #define GLX_LARGEST_PBUFFER 0x801C
#define GLX_PBUFFER_HEIGHT 0x8040 /* New for GLX 1.3 */ #define GLX_PBUFFER_HEIGHT 0x8040 /* New for GLX 1.3 */
@ -151,7 +151,7 @@
#define GLX_PRESERVED_CONTENTS_SGIX GLX_PRESERVED_CONTENTS #define GLX_PRESERVED_CONTENTS_SGIX GLX_PRESERVED_CONTENTS
#define GLX_LARGEST_PBUFFER_SGIX GLX_LARGEST_PBUFFER #define GLX_LARGEST_PBUFFER_SGIX GLX_LARGEST_PBUFFER
/* glXQueryGLXPBuffer attributes */ /* _glXQueryGLXPBuffer attributes */
#define GLX_WIDTH 0x801D #define GLX_WIDTH 0x801D
#define GLX_HEIGHT 0x801E #define GLX_HEIGHT 0x801E
#define GLX_EVENT_MASK 0x801F #define GLX_EVENT_MASK 0x801F
@ -159,18 +159,18 @@
#define GLX_HEIGHT_SGIX GLX_HEIGHT #define GLX_HEIGHT_SGIX GLX_HEIGHT
#define GLX_EVENT_MASK_SGIX GLX_EVENT_MASK #define GLX_EVENT_MASK_SGIX GLX_EVENT_MASK
/* glXCreateNewContext render_type attribute values */ /* _glXCreateNewContext render_type attribute values */
#define GLX_RGBA_TYPE 0x8014 #define GLX_RGBA_TYPE 0x8014
#define GLX_COLOR_INDEX_TYPE 0x8015 #define GLX_COLOR_INDEX_TYPE 0x8015
#define GLX_RGBA_TYPE_SGIX GLX_RGBA_TYPE #define GLX_RGBA_TYPE_SGIX GLX_RGBA_TYPE
#define GLX_COLOR_INDEX_TYPE_SGIX GLX_COLOR_INDEX_TYPE #define GLX_COLOR_INDEX_TYPE_SGIX GLX_COLOR_INDEX_TYPE
/* glXQueryContext attributes */ /* _glXQueryContext attributes */
/* #define GLX_FBCONFIG_ID 0x8013 */ /* #define GLX_FBCONFIG_ID 0x8013 */
/* #define GLX_RENDER_TYPE 0x8011 */ /* #define GLX_RENDER_TYPE 0x8011 */
#define GLX_SCREEN 0x800C #define GLX_SCREEN 0x800C
/* glXSelectEvent event mask bits */ /* _glXSelectEvent event mask bits */
#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 #define GLX_PBUFFER_CLOBBER_MASK 0x08000000
#define GLX_PBUFFER_CLOBBER_MASK_SGIX GLX_PBUFFER_CLOBBER_MASK #define GLX_PBUFFER_CLOBBER_MASK_SGIX GLX_PBUFFER_CLOBBER_MASK
@ -205,8 +205,8 @@
#define GLX_ACCUM_BUFFER_BIT_SGIX GLX_ACCUM_BUFFER_BIT #define GLX_ACCUM_BUFFER_BIT_SGIX GLX_ACCUM_BUFFER_BIT
/* /*
* Extension return values from glXGetConfig. These are also * Extension return values from _glXGetConfig. These are also
* accepted as parameter values for glXChooseVisual. * accepted as parameter values for _glXChooseVisual.
*/ */
#define GLX_X_VISUAL_TYPE_EXT 0x22 /* visual_info extension type */ #define GLX_X_VISUAL_TYPE_EXT 0x22 /* visual_info extension type */
@ -236,14 +236,14 @@
#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D #define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
/* /*
* Names for attributes to glXGetClientString. * Names for attributes to _glXGetClientString.
*/ */
#define GLX_VENDOR 0x1 #define GLX_VENDOR 0x1
#define GLX_VERSION 0x2 #define GLX_VERSION 0x2
#define GLX_EXTENSIONS 0x3 #define GLX_EXTENSIONS 0x3
/* /*
* Names for attributes to glXQueryContextInfoEXT. * Names for attributes to _glXQueryContextInfoEXT.
*/ */
#define GLX_SHARE_CONTEXT_EXT 0x800A /* id of share context */ #define GLX_SHARE_CONTEXT_EXT 0x800A /* id of share context */
#define GLX_VISUAL_ID_EXT 0x800B /* id of context's visual */ #define GLX_VISUAL_ID_EXT 0x800B /* id of context's visual */
@ -315,56 +315,55 @@ typedef void (APIENTRY * glXSwapIntervalSGIPROC)(int interval);
typedef struct { typedef struct {
bool GLX12; bool GLX12;
bool GLX13; bool GLX13;
bool GLX_EXT_visual_info; /* bool GLX_EXT_visual_info;
bool GLX_EXT_visual_rating; bool GLX_EXT_visual_rating;*/
bool GLX_SGI_swap_control; bool GLX_SGI_swap_control;
bool GLX_ARB_multisample; bool GLX_ARB_multisample;
} GLXExtensions; } GLXExtensions;
extern GLXExtensions extension_flags; /* Add _ to global symbols to avoid symbol clash with the OpenGL library */
extern glXGetFBConfigsPROC _glXGetFBConfigs;
extern glXChooseFBConfigPROC _glXChooseFBConfig;
extern glXGetFBConfigAttribPROC _glXGetFBConfigAttrib;
extern glXGetVisualFromFBConfigPROC _glXGetVisualFromFBConfig;
extern glXCreateWindowPROC _glXCreateWindow;
extern glXDestroyWindowPROC _glXDestroyWindow;
extern glXCreatePixmapPROC _glXCreatePixmap;
extern glXDestroyPixmapPROC _glXDestroyPixmap;
extern glXCreatePbufferPROC _glXCreatePbuffer;
extern glXDestroyPbufferPROC _glXDestroyPbuffer;
extern glXQueryDrawablePROC _glXQueryDrawable;
extern glXCreateNewContextPROC _glXCreateNewContext;
extern glXMakeContextCurrentPROC _glXMakeContextCurrent;
extern glXGetCurrentReadDrawablePROC _glXGetCurrentReadDrawable;
extern glXGetCurrentDisplayPROC _glXGetCurrentDisplay;
extern glXQueryContextPROC _glXQueryContext;
extern glXSelectEventPROC _glXSelectEvent;
extern glXGetSelectedEventPROC _glXGetSelectedEvent;
extern glXGetFBConfigsPROC glXGetFBConfigs; extern glXChooseVisualPROC _glXChooseVisual;
extern glXChooseFBConfigPROC glXChooseFBConfig; extern glXCopyContextPROC _glXCopyContext;
extern glXGetFBConfigAttribPROC glXGetFBConfigAttrib; extern glXCreateContextPROC _glXCreateContext;
extern glXGetVisualFromFBConfigPROC glXGetVisualFromFBConfig; extern glXCreateGLXPixmapPROC _glXCreateGLXPixmap;
extern glXCreateWindowPROC glXCreateWindow; extern glXDestroyContextPROC _glXDestroyContext;
extern glXDestroyWindowPROC glXDestroyWindow; extern glXDestroyGLXPixmapPROC _glXDestroyGLXPixmap;
extern glXCreatePixmapPROC glXCreatePixmap; extern glXGetConfigPROC _glXGetConfig;
extern glXDestroyPixmapPROC glXDestroyPixmap; extern glXGetCurrentContextPROC _glXGetCurrentContext;
extern glXCreatePbufferPROC glXCreatePbuffer; extern glXGetCurrentDrawablePROC _glXGetCurrentDrawable;
extern glXDestroyPbufferPROC glXDestroyPbuffer; extern glXIsDirectPROC _glXIsDirect;
extern glXQueryDrawablePROC glXQueryDrawable; extern glXMakeCurrentPROC _glXMakeCurrent;
extern glXCreateNewContextPROC glXCreateNewContext; extern glXQueryExtensionPROC _glXQueryExtension;
extern glXMakeContextCurrentPROC glXMakeContextCurrent; extern glXQueryVersionPROC _glXQueryVersion;
extern glXGetCurrentReadDrawablePROC glXGetCurrentReadDrawable; extern glXSwapBuffersPROC _glXSwapBuffers;
extern glXGetCurrentDisplayPROC glXGetCurrentDisplay; extern glXUseXFontPROC _glXUseXFont;
extern glXQueryContextPROC glXQueryContext; extern glXWaitGLPROC _glXWaitGL;
extern glXSelectEventPROC glXSelectEvent; extern glXWaitXPROC _glXWaitX;
extern glXGetSelectedEventPROC glXGetSelectedEvent; extern glXGetClientStringPROC _glXGetClientString;
extern glXQueryServerStringPROC _glXQueryServerString;
extern glXQueryExtensionsStringPROC _glXQueryExtensionsString;
extern glXChooseVisualPROC glXChooseVisual; extern glXSwapIntervalSGIPROC _glXSwapIntervalSGI;
extern glXCopyContextPROC glXCopyContext;
extern glXCreateContextPROC glXCreateContext;
extern glXCreateGLXPixmapPROC glXCreateGLXPixmap;
extern glXDestroyContextPROC glXDestroyContext;
extern glXDestroyGLXPixmapPROC glXDestroyGLXPixmap;
extern glXGetConfigPROC glXGetConfig;
extern glXGetCurrentContextPROC glXGetCurrentContext;
extern glXGetCurrentDrawablePROC glXGetCurrentDrawable;
extern glXIsDirectPROC glXIsDirect;
extern glXMakeCurrentPROC glXMakeCurrent;
extern glXQueryExtensionPROC glXQueryExtension;
extern glXQueryVersionPROC glXQueryVersion;
extern glXSwapBuffersPROC glXSwapBuffers;
extern glXUseXFontPROC glXUseXFont;
extern glXWaitGLPROC glXWaitGL;
extern glXWaitXPROC glXWaitX;
extern glXGetClientStringPROC glXGetClientString;
extern glXQueryServerStringPROC glXQueryServerString;
extern glXQueryExtensionsStringPROC glXQueryExtensionsString;
extern glXSwapIntervalSGIPROC glXSwapIntervalSGI; extern bool extgl_InitGLX(Display *disp, int screen, GLXExtensions *extension_flags);
extern bool extgl_InitGLX(Display *disp, int screen);
#endif #endif

View File

@ -337,7 +337,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetTitle(JNIEnv * env
static void destroyWindow(JNIEnv *env) { static void destroyWindow(JNIEnv *env) {
if (glx_window != None) { if (glx_window != None) {
glXDestroyWindow(getDisplay(), glx_window); _glXDestroyWindow(getDisplay(), glx_window);
glx_window = None; glx_window = None;
} }
XDestroyWindow(getDisplay(), current_win); XDestroyWindow(getDisplay(), current_win);
@ -513,11 +513,11 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateWindow(JNIEnv *
return; return;
} }
if (peer_info->glx13) { if (peer_info->glx13) {
glx_window = glXCreateWindow(getDisplay(), *fb_config, getCurrentWindow(), NULL); glx_window = _glXCreateWindow(getDisplay(), *fb_config, getCurrentWindow(), NULL);
XFree(fb_config); XFree(fb_config);
} }
if (!checkXError(env, getDisplay())) { if (!checkXError(env, getDisplay())) {
glXDestroyWindow(getDisplay(), glx_window); _glXDestroyWindow(getDisplay(), glx_window);
destroyWindow(env); destroyWindow(env);
} }
} }

View File

@ -48,7 +48,8 @@
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxCanvasImplementation_nFindVisualIDFromFormat JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxCanvasImplementation_nFindVisualIDFromFormat
(JNIEnv *env, jclass clazz, jint screen, jobject pixel_format) { (JNIEnv *env, jclass clazz, jint screen, jobject pixel_format) {
if (!extgl_InitGLX(getDisplay(), screen)) { GLXExtensions extension_flags;
if (!extgl_InitGLX(getDisplay(), screen, &extension_flags)) {
throwException(env, "Could not initialize GLX"); throwException(env, "Could not initialize GLX");
return -1; return -1;
} }

View File

@ -48,7 +48,7 @@
#include "Window.h" #include "Window.h"
typedef struct { typedef struct {
bool glx13; GLXExtensions extension_flags;
GLXContext context; GLXContext context;
} X11Context; } X11Context;
@ -58,8 +58,8 @@ static bool checkContext(JNIEnv *env, Display *display, GLXContext context) {
return false; return false;
} }
jboolean allow_software_acceleration = getBooleanProperty(env, "org.lwjgl.opengl.Display.allowSoftwareOpenGL"); jboolean allow_software_acceleration = getBooleanProperty(env, "org.lwjgl.opengl.Display.allowSoftwareOpenGL");
if (!allow_software_acceleration && glXIsDirect(display, context) == False) { if (!allow_software_acceleration && _glXIsDirect(display, context) == False) {
glXDestroyContext(display, context); _glXDestroyContext(display, context);
throwException(env, "Could not create a direct GLX context"); throwException(env, "Could not create a direct GLX context");
return false; return false;
} }
@ -70,11 +70,10 @@ static void createContextGLX13(JNIEnv *env, X11PeerInfo *peer_info, X11Context *
GLXFBConfig *config = getFBConfigFromPeerInfo(env, peer_info); GLXFBConfig *config = getFBConfigFromPeerInfo(env, peer_info);
if (config == NULL) if (config == NULL)
return; return;
GLXContext context = glXCreateNewContext(peer_info->display, *config, GLX_RGBA_TYPE, shared_context, True); GLXContext context = _glXCreateNewContext(peer_info->display, *config, GLX_RGBA_TYPE, shared_context, True);
XFree(config); XFree(config);
if (!checkContext(env, peer_info->display, context)) if (!checkContext(env, peer_info->display, context))
return; return;
context_info->glx13 = true;
context_info->context = context; context_info->context = context;
} }
@ -82,20 +81,20 @@ static void createContextGLX(JNIEnv *env, X11PeerInfo *peer_info, X11Context *co
XVisualInfo *vis_info = getVisualInfoFromPeerInfo(env, peer_info); XVisualInfo *vis_info = getVisualInfoFromPeerInfo(env, peer_info);
if (vis_info == NULL) if (vis_info == NULL)
return; return;
GLXContext context = glXCreateContext(peer_info->display, vis_info, shared_context, True); GLXContext context = _glXCreateContext(peer_info->display, vis_info, shared_context, True);
XFree(vis_info); XFree(vis_info);
if (!checkContext(env, peer_info->display, context)) if (!checkContext(env, peer_info->display, context))
return; return;
context_info->glx13 = false;
context_info->context = context; context_info->context = context;
} }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nSetVSync JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nSetVSync
(JNIEnv *env, jclass clazz, jboolean sync) (JNIEnv *env, jclass clazz, jobject context_handle, jboolean sync)
{ {
if (extension_flags.GLX_SGI_swap_control) { X11Context *context_info = (*env)->GetDirectBufferAddress(env, context_handle);
if (context_info->extension_flags.GLX_SGI_swap_control) {
int interval = sync == JNI_TRUE ? 1 : 0; int interval = sync == JNI_TRUE ? 1 : 0;
glXSwapIntervalSGI(interval); _glXSwapIntervalSGI(interval);
} }
} }
@ -108,8 +107,8 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nCrea
} }
X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_handle); X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_handle);
X11Context *context_info = (*env)->GetDirectBufferAddress(env, context_handle); X11Context *context_info = (*env)->GetDirectBufferAddress(env, context_handle);
GLXExtensions extension_flags;
if (!extgl_InitGLX(peer_info->display, peer_info->screen)) { if (!extgl_InitGLX(peer_info->display, peer_info->screen, &extension_flags)) {
throwException(env, "Could not initialize GLX"); throwException(env, "Could not initialize GLX");
return NULL; return NULL;
} }
@ -123,6 +122,7 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nCrea
} else { } else {
createContextGLX(env, peer_info, context_info, shared_context); createContextGLX(env, peer_info, context_info, shared_context);
} }
context_info->extension_flags = extension_flags;
return context_handle; return context_handle;
} }
@ -130,17 +130,17 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nDestroy
(JNIEnv *env, jclass clazz, jobject peer_handle, jobject context_handle) { (JNIEnv *env, jclass clazz, jobject peer_handle, jobject context_handle) {
X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_handle); X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_handle);
X11Context *context_info = (*env)->GetDirectBufferAddress(env, context_handle); X11Context *context_info = (*env)->GetDirectBufferAddress(env, context_handle);
glXDestroyContext(peer_info->display, context_info->context); _glXDestroyContext(peer_info->display, context_info->context);
} }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nReleaseCurrentContext JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nReleaseCurrentContext
(JNIEnv *env , jclass clazz, jobject peer_info_handle) { (JNIEnv *env , jclass clazz, jobject peer_info_handle) {
X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_info_handle); X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_info_handle);
Bool result; Bool result;
if (extension_flags.GLX13) { if (peer_info->glx13) {
result = glXMakeContextCurrent(peer_info->display, None, None, NULL); result = _glXMakeContextCurrent(peer_info->display, None, None, NULL);
} else { } else {
result = glXMakeCurrent(peer_info->display, None, NULL); result = _glXMakeCurrent(peer_info->display, None, NULL);
} }
if (!result) if (!result)
throwException(env, "Could not release current context"); throwException(env, "Could not release current context");
@ -151,10 +151,10 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nMakeCur
X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_info_handle); X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_info_handle);
X11Context *context_info = (*env)->GetDirectBufferAddress(env, context_handle); X11Context *context_info = (*env)->GetDirectBufferAddress(env, context_handle);
Bool result; Bool result;
if (context_info->glx13) { if (peer_info->glx13) {
result = glXMakeContextCurrent(peer_info->display, peer_info->drawable, peer_info->drawable, context_info->context); result = _glXMakeContextCurrent(peer_info->display, peer_info->drawable, peer_info->drawable, context_info->context);
} else { } else {
result = glXMakeCurrent(peer_info->display, peer_info->drawable, context_info->context); result = _glXMakeCurrent(peer_info->display, peer_info->drawable, context_info->context);
} }
if (!result) if (!result)
throwException(env, "Could not make context current"); throwException(env, "Could not make context current");
@ -163,11 +163,11 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nMakeCur
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nIsCurrent JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nIsCurrent
(JNIEnv *env, jclass clazz, jobject context_handle) { (JNIEnv *env, jclass clazz, jobject context_handle) {
X11Context *context_info = (*env)->GetDirectBufferAddress(env, context_handle); X11Context *context_info = (*env)->GetDirectBufferAddress(env, context_handle);
return context_info->context == glXGetCurrentContext(); return context_info->context == _glXGetCurrentContext();
} }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nSwapBuffers JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxContextImplementation_nSwapBuffers
(JNIEnv *env, jclass clazz, jobject peer_info_handle) { (JNIEnv *env, jclass clazz, jobject peer_info_handle) {
X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_info_handle); X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_info_handle);
glXSwapBuffers(peer_info->display, peer_info->drawable); _glXSwapBuffers(peer_info->display, peer_info->drawable);
} }

View File

@ -47,20 +47,20 @@
#include "Window.h" #include "Window.h"
#include "common_tools.h" #include "common_tools.h"
static bool isPbuffersSupported() { JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetPbufferCapabilities
(JNIEnv *env, jclass clazz)
{
GLXExtensions extension_flags;
if (!extgl_InitGLX(getDisplay(), getCurrentScreen(), &extension_flags))
return 0;
// Only support the GLX 1.3 Pbuffers and ignore the GLX_SGIX_pbuffer extension // Only support the GLX 1.3 Pbuffers and ignore the GLX_SGIX_pbuffer extension
return extension_flags.GLX13 ? org_lwjgl_opengl_Pbuffer_PBUFFER_SUPPORTED : 0; return extension_flags.GLX13 ? org_lwjgl_opengl_Pbuffer_PBUFFER_SUPPORTED : 0;
} }
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetPbufferCapabilities
(JNIEnv *env, jclass clazz)
{
return isPbuffersSupported() ? org_lwjgl_opengl_Pbuffer_PBUFFER_SUPPORTED : 0;
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxPbufferPeerInfo_nInitHandle JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxPbufferPeerInfo_nInitHandle
(JNIEnv *env, jclass clazz, jobject peer_info_handle, jint width, jint height, jobject pixel_format) { (JNIEnv *env, jclass clazz, jobject peer_info_handle, jint width, jint height, jobject pixel_format) {
if (!extgl_InitGLX(getDisplay(), getCurrentScreen()) || !isPbuffersSupported()) { GLXExtensions extension_flags;
if (!extgl_InitGLX(getDisplay(), getCurrentScreen(), &extension_flags) || !extension_flags.GLX13) {
throwException(env, "No Pbuffer support"); throwException(env, "No Pbuffer support");
return; return;
} }
@ -75,7 +75,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxPbufferPeerInfo_nInitHandle
X11PeerInfo *peer_info = (X11PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); X11PeerInfo *peer_info = (X11PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle);
GLXFBConfig *config = getFBConfigFromPeerInfo(env, peer_info); GLXFBConfig *config = getFBConfigFromPeerInfo(env, peer_info);
GLXPbuffer buffer = glXCreatePbuffer(peer_info->display, *config, buffer_attribs); GLXPbuffer buffer = _glXCreatePbuffer(peer_info->display, *config, buffer_attribs);
XFree(config); XFree(config);
peer_info->drawable = buffer; peer_info->drawable = buffer;
} }
@ -83,5 +83,5 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxPbufferPeerInfo_nInitHandle
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxPbufferPeerInfo_nDestroy JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxPbufferPeerInfo_nDestroy
(JNIEnv *env, jclass clazz, jobject peer_info_handle) { (JNIEnv *env, jclass clazz, jobject peer_info_handle) {
X11PeerInfo *peer_info = (X11PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); X11PeerInfo *peer_info = (X11PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle);
glXDestroyPbuffer(peer_info->display, peer_info->drawable); _glXDestroyPbuffer(peer_info->display, peer_info->drawable);
} }