Added more intelligent pixel format chooser in linux
This commit is contained in:
parent
86279b768f
commit
04909d4f55
|
@ -72,12 +72,12 @@ glXQueryContextPROC glXQueryContext = NULL;
|
|||
glXSelectEventPROC glXSelectEvent = NULL;
|
||||
glXGetSelectedEventPROC glXGetSelectedEvent = NULL;
|
||||
|
||||
glXGetContextIDEXTPROC glXGetContextIDEXT = NULL;
|
||||
/*glXGetContextIDEXTPROC glXGetContextIDEXT = NULL;
|
||||
glXGetCurrentDrawableEXTPROC glXGetCurrentDrawableEXT = NULL;
|
||||
glXImportContextEXTPROC glXImportContextEXT = NULL;
|
||||
glXFreeContextEXTPROC glXFreeContextEXT = NULL;
|
||||
glXQueryContextInfoEXTPROC glXQueryContextInfoEXT = NULL;
|
||||
|
||||
*/
|
||||
glXGetProcAddressARBPROC glXGetProcAddressARB = NULL;
|
||||
|
||||
glXChooseVisualPROC glXChooseVisual = NULL;
|
||||
|
@ -1376,10 +1376,11 @@ void *extgl_GetProcAddress(char *name)
|
|||
if (t == NULL)
|
||||
{
|
||||
t = dlsym(lib_glu_handle, name);
|
||||
if (t == NULL)
|
||||
if (t == NULL) {
|
||||
extgl_error = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
#endif
|
||||
}
|
||||
|
@ -1561,6 +1562,14 @@ int QueryExtension(const GLubyte*extensions, const char *name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
/** returns true if the extention is available */
|
||||
int GLXQueryExtension(Display *disp, int screen, const char *name)
|
||||
{
|
||||
return QueryExtension(glXQueryExtensionsString(disp, screen), name);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** returns true if the extention is available */
|
||||
int GLUQueryExtension(const char *name)
|
||||
{
|
||||
|
@ -2410,7 +2419,7 @@ int extgl_InitEXTNurbsTesselator(void)
|
|||
int extgl_InitGLX13(void)
|
||||
{
|
||||
if (extgl_Extensions.glx.GLX13 == 0)
|
||||
return 1;
|
||||
return extgl_error;
|
||||
glXGetFBConfigs = (glXGetFBConfigsPROC) extgl_GetProcAddress("glXGetFBConfigs");
|
||||
glXChooseFBConfig = (glXChooseFBConfigPROC) extgl_GetProcAddress("glXChooseFBConfig");
|
||||
glXGetFBConfigAttrib = (glXGetFBConfigAttribPROC) extgl_GetProcAddress("glXGetFBConfigAttrib");
|
||||
|
@ -2434,12 +2443,12 @@ int extgl_InitGLX13(void)
|
|||
|
||||
int extgl_InitGLX12(void)
|
||||
{
|
||||
glXGetContextIDEXT = (glXGetContextIDEXTPROC) extgl_GetProcAddress("glXGetContextIDEXT");
|
||||
/* glXGetContextIDEXT = (glXGetContextIDEXTPROC) extgl_GetProcAddress("glXGetContextIDEXT");
|
||||
glXGetCurrentDrawableEXT = (glXGetCurrentDrawableEXTPROC) extgl_GetProcAddress("glXGetCurrentDrawableEXT");
|
||||
glXImportContextEXT = (glXImportContextEXTPROC) extgl_GetProcAddress("glXImportContextEXT");
|
||||
glXFreeContextEXT = (glXFreeContextEXTPROC) extgl_GetProcAddress("glXFreeContextEXT");
|
||||
glXQueryContextInfoEXT = (glXQueryContextInfoEXTPROC) extgl_GetProcAddress("glXQueryContextInfoEXT");
|
||||
|
||||
*/
|
||||
glXChooseVisual = (glXChooseVisualPROC) extgl_GetProcAddress("glXChooseVisual");
|
||||
glXCopyContext = (glXCopyContextPROC) extgl_GetProcAddress("glXCopyContext");
|
||||
glXCreateContext = (glXCreateContextPROC) extgl_GetProcAddress("glXCreateContext");
|
||||
|
@ -2463,18 +2472,30 @@ int extgl_InitGLX12(void)
|
|||
return extgl_error;
|
||||
}
|
||||
|
||||
int extgl_InitGLX(void)
|
||||
#ifndef _WIN32
|
||||
void extgl_InitGLXSupportedExtensions(Display *disp, int screen)
|
||||
{
|
||||
/* Assume glx ver >= 1.3 */
|
||||
extgl_Extensions.glx.GLX12 = 1;
|
||||
extgl_Extensions.glx.GLX13 = 1;
|
||||
extgl_Extensions.glx.EXT_visual_info = GLXQueryExtension(disp, screen, "GLX_EXT_visual_info");
|
||||
extgl_Extensions.glx.EXT_visual_rating = GLXQueryExtension(disp, screen, "GLX_EXT_visual_rating");
|
||||
}
|
||||
#endif
|
||||
|
||||
int extgl_InitGLX(Display *disp, int screen)
|
||||
{
|
||||
int major, minor;
|
||||
/* Assume glx ver >= 1.2 */
|
||||
extgl_Extensions.glx.GLX12 = 1;
|
||||
glXGetProcAddressARB = (glXGetProcAddressARBPROC) dlsym(lib_gl_handle, "glXGetProcAddressARB");
|
||||
if (glXGetProcAddressARB == NULL)
|
||||
return 1;
|
||||
|
||||
if (extgl_InitGLX12() != 0)
|
||||
return 1;
|
||||
extgl_InitGLXSupportedExtensions(disp, screen);
|
||||
if (glXQueryVersion(disp, &major, &minor) != True)
|
||||
return 1;
|
||||
if (major > 1 || (major == 1 && minor >= 3))
|
||||
extgl_Extensions.glx.GLX13 = 1;
|
||||
if (extgl_InitGLX13() != 0)
|
||||
return 1;
|
||||
return 0;
|
||||
|
@ -2989,6 +3010,7 @@ void extgl_InitOpenGL1_4()
|
|||
#endif /* GL_VERSION_1_4 */
|
||||
}
|
||||
|
||||
|
||||
void extgl_InitGLUSupportedExtensions()
|
||||
{
|
||||
char *s = (char*) gluGetString(GLU_VERSION);
|
||||
|
@ -3198,9 +3220,9 @@ int extgl_Initialize()
|
|||
return extgl_error;
|
||||
}
|
||||
|
||||
int extgl_Open(void)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
int extgl_Open(Display *disp, int screen)
|
||||
{
|
||||
lib_gl_handle = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL);
|
||||
if (lib_gl_handle == NULL)
|
||||
return 1;
|
||||
|
@ -3208,9 +3230,13 @@ int extgl_Open(void)
|
|||
lib_glu_handle = dlopen("libGLU.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||
if (lib_glu_handle == NULL)
|
||||
return 1;
|
||||
|
||||
extgl_InitGLX();
|
||||
if (extgl_InitGLX(disp, screen) != 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int extgl_Open(void)
|
||||
{
|
||||
|
||||
lib_gl_handle = LoadLibrary("opengl32.dll");
|
||||
if (lib_gl_handle == NULL)
|
||||
|
@ -3218,10 +3244,9 @@ int extgl_Open(void)
|
|||
lib_glu_handle = LoadLibrary("glu32.dll");
|
||||
if (lib_glu_handle == NULL)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void extgl_Close(void)
|
||||
{
|
||||
|
|
|
@ -354,12 +354,12 @@ extern glXQueryContextPROC glXQueryContext;
|
|||
extern glXSelectEventPROC glXSelectEvent;
|
||||
extern glXGetSelectedEventPROC glXGetSelectedEvent;
|
||||
|
||||
extern glXGetContextIDEXTPROC glXGetContextIDEXT;
|
||||
/*extern glXGetContextIDEXTPROC glXGetContextIDEXT;
|
||||
extern glXGetCurrentDrawableEXTPROC glXGetCurrentDrawableEXT;
|
||||
extern glXImportContextEXTPROC glXImportContextEXT;
|
||||
extern glXFreeContextEXTPROC glXFreeContextEXT;
|
||||
extern glXQueryContextInfoEXTPROC glXQueryContextInfoEXT;
|
||||
|
||||
*/
|
||||
extern glXGetProcAddressARBPROC glXGetProcAddressARB;
|
||||
|
||||
extern glXChooseVisualPROC glXChooseVisual;
|
||||
|
@ -5547,6 +5547,8 @@ struct GLXExtensionTypes
|
|||
{
|
||||
int GLX12;
|
||||
int GLX13;
|
||||
int EXT_visual_info;
|
||||
int EXT_visual_rating;
|
||||
};
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
@ -5661,7 +5663,11 @@ extern struct ExtensionTypes SupportedExtensions; /* deprecated, please do not u
|
|||
|
||||
/* initializes everything, call this right after the rc is created. the function returns 0 if successful */
|
||||
int extgl_Initialize();
|
||||
#ifndef _WIN32
|
||||
int extgl_Open(Display *disp, int screen);
|
||||
#else
|
||||
int extgl_Open(void);
|
||||
#endif
|
||||
void extgl_Close(void);
|
||||
|
||||
int glInitialize(); /* deprecated, please do not use */
|
||||
|
|
|
@ -60,40 +60,123 @@ int win_width;
|
|||
int win_height;
|
||||
XF86VidModeModeInfo **avail_modes;
|
||||
XVisualInfo * vis_info;
|
||||
int gl_loaded = 0;
|
||||
|
||||
struct pixelformat {
|
||||
int bpp;
|
||||
int depth;
|
||||
int alpha;
|
||||
int stencil;
|
||||
};
|
||||
|
||||
struct pixelformat * getAvailablePixelFormats(int *length) {
|
||||
*length = 8;
|
||||
struct pixelformat *formats = (struct pixelformat *)malloc((*length)*sizeof(struct pixelformat));
|
||||
formats[0].depth = 24;
|
||||
formats[0].alpha = 8;
|
||||
formats[0].stencil = 8;
|
||||
formats[1].depth = 16;
|
||||
formats[1].alpha = 8;
|
||||
formats[1].stencil = 8;
|
||||
formats[2].depth = 24;
|
||||
formats[2].alpha = 0;
|
||||
formats[2].stencil = 8;
|
||||
formats[3].depth = 16;
|
||||
formats[3].alpha = 0;
|
||||
formats[3].stencil = 8;
|
||||
formats[4].depth = 24;
|
||||
formats[4].alpha = 8;
|
||||
formats[4].stencil = 0;
|
||||
formats[5].depth = 16;
|
||||
formats[5].alpha = 8;
|
||||
formats[5].stencil = 0;
|
||||
formats[6].depth = 24;
|
||||
formats[6].alpha = 0;
|
||||
formats[6].stencil = 0;
|
||||
formats[7].depth = 16;
|
||||
formats[7].alpha = 0;
|
||||
formats[7].stencil = 0;
|
||||
int fillFormat(struct pixelformat *formats, int index, int bpp, int depth, int alpha, int stencil) {
|
||||
for (int i = 0; i < index; i++)
|
||||
if (formats[i].bpp == bpp &&
|
||||
formats[i].depth == depth &&
|
||||
formats[i].alpha == alpha &&
|
||||
formats[i].stencil == stencil)
|
||||
return 0;
|
||||
formats[index].bpp = bpp;
|
||||
formats[index].depth = depth;
|
||||
formats[index].stencil = stencil;
|
||||
formats[index].alpha = alpha;
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct pixelformat *getGLXAvailablePixelFormats(Display *disp, int screen, int *length) {
|
||||
if (extgl_Extensions.glx.GLX13 == 1) {
|
||||
int num_formats;
|
||||
int attriblist[] = {GLX_DOUBLEBUFFER, True,
|
||||
GLX_STEREO, False,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
||||
GLX_CONFIG_CAVEAT, GLX_NONE,
|
||||
None};
|
||||
GLXFBConfig *configs = glXChooseFBConfig(disp, screen, attriblist, &num_formats);
|
||||
struct pixelformat *formats = (struct pixelformat *)malloc(num_formats*sizeof(struct pixelformat));
|
||||
*length = 0;
|
||||
for (int i = 0; i < num_formats; i++) {
|
||||
int bpp, depth, alpha, stencil;
|
||||
int val;
|
||||
if (glXGetFBConfigAttrib(disp, configs[i], GLX_RED_SIZE, &val) != 0) {
|
||||
free(formats);
|
||||
return NULL;
|
||||
}
|
||||
bpp = val;
|
||||
if (glXGetFBConfigAttrib(disp, configs[i], GLX_GREEN_SIZE, &val) != 0) {
|
||||
free(formats);
|
||||
return NULL;
|
||||
}
|
||||
bpp += val;
|
||||
if (glXGetFBConfigAttrib(disp, configs[i], GLX_BLUE_SIZE, &val) != 0) {
|
||||
free(formats);
|
||||
return NULL;
|
||||
}
|
||||
bpp += val;
|
||||
if (glXGetFBConfigAttrib(disp, configs[i], GLX_ALPHA_SIZE, &alpha) != 0) {
|
||||
free(formats);
|
||||
return NULL;
|
||||
}
|
||||
if (glXGetFBConfigAttrib(disp, configs[i], GLX_DEPTH_SIZE, &depth) != 0) {
|
||||
free(formats);
|
||||
return NULL;
|
||||
}
|
||||
if (glXGetFBConfigAttrib(disp, configs[i], GLX_STENCIL_SIZE, &stencil) != 0) {
|
||||
free(formats);
|
||||
return NULL;
|
||||
}
|
||||
if (fillFormat(formats, *length, bpp, depth, alpha, stencil) == 1)
|
||||
(*length)++;
|
||||
}
|
||||
return formats;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XVisualInfo *chooseVisual(Display *disp, int screen, int bpp, int depth, int alpha, int stencil) {
|
||||
int bpe;
|
||||
switch (bpp) {
|
||||
case 32:
|
||||
case 24:
|
||||
bpe = 8;
|
||||
break;
|
||||
case 16:
|
||||
bpe = 4;
|
||||
break;
|
||||
default:
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
int attriblist[] = { GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_DEPTH_SIZE, depth,
|
||||
GLX_RED_SIZE, bpe,
|
||||
GLX_GREEN_SIZE, bpe,
|
||||
GLX_BLUE_SIZE, bpe,
|
||||
GLX_ALPHA_SIZE, alpha,
|
||||
GLX_STENCIL_SIZE, stencil,
|
||||
None };
|
||||
return glXChooseVisual(disp, screen, attriblist);
|
||||
}
|
||||
|
||||
struct pixelformat *getAvailablePixelFormats(Display *disp, int screen, int *length) {
|
||||
struct pixelformat *formats = getGLXAvailablePixelFormats(disp, screen, length);
|
||||
if (formats != NULL)
|
||||
return formats;
|
||||
*length = 16;
|
||||
formats = (struct pixelformat *)malloc((*length)*sizeof(struct pixelformat));
|
||||
*length = 0;
|
||||
for (int bpp = 16; bpp <= 24; bpp += 8)
|
||||
for (int depth = 16; depth <= 24; depth += 8)
|
||||
for (int alpha = 0; alpha <= 8; alpha += 8)
|
||||
for (int stencil = 0; stencil <= 8; stencil += 8) {
|
||||
XVisualInfo * visual = chooseVisual(disp, screen, bpp, depth, alpha, stencil);
|
||||
if (visual != NULL) {
|
||||
if (fillFormat(formats, *length, bpp, depth, alpha, stencil) == 1)
|
||||
(*length)++;
|
||||
XFree(visual);
|
||||
}
|
||||
}
|
||||
return formats;
|
||||
}
|
||||
|
||||
|
@ -116,6 +199,19 @@ int isFocused(void) {
|
|||
return current_focused;
|
||||
}
|
||||
|
||||
int loadGL(Display *disp, int screen) {
|
||||
if (gl_loaded == 1)
|
||||
return JNI_TRUE;
|
||||
if (extgl_Open(disp, screen) != 0) {
|
||||
#ifdef _DEBUG
|
||||
printf("Could not load gl libs\n");
|
||||
#endif
|
||||
return JNI_FALSE;
|
||||
}
|
||||
gl_loaded = 1;
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
int getDisplayModes(Display *disp, int screen, int *num_modes, XF86VidModeModeInfo ***avail_modes) {
|
||||
int event_base, error_base, xvid_ver, xvid_rev;
|
||||
|
||||
|
@ -138,38 +234,6 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass c
|
|||
XSetWindowAttributes attribs;
|
||||
Colormap cmap;
|
||||
int attribmask;
|
||||
int bpe;
|
||||
switch (bpp) {
|
||||
case 32:
|
||||
case 24:
|
||||
bpe = 8;
|
||||
break;
|
||||
case 16:
|
||||
bpe = 4;
|
||||
break;
|
||||
default:
|
||||
return JNI_FALSE;
|
||||
}
|
||||
if (depth_bits == 32)
|
||||
depth_bits = 24;
|
||||
|
||||
int attriblist[] = { GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_DEPTH_SIZE, depth_bits,
|
||||
GLX_RED_SIZE, bpe,
|
||||
GLX_GREEN_SIZE, bpe,
|
||||
GLX_BLUE_SIZE, bpe,
|
||||
GLX_ALPHA_SIZE, alpha_bits,
|
||||
GLX_STENCIL_SIZE, stencil_bits,
|
||||
None };
|
||||
/* int attriblistna[] = { GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_DEPTH_SIZE, bpp,
|
||||
GLX_RED_SIZE, bpe,
|
||||
GLX_GREEN_SIZE, bpe,
|
||||
GLX_BLUE_SIZE, bpe,
|
||||
None };
|
||||
*/
|
||||
int num_modes, i;
|
||||
|
||||
|
||||
|
@ -186,6 +250,12 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass c
|
|||
return JNI_FALSE;
|
||||
}
|
||||
screen = DefaultScreen(disp);
|
||||
if (loadGL(disp, screen) != JNI_TRUE) {
|
||||
#ifdef _DEBUG
|
||||
printf("Could not load GL libs\n");
|
||||
#endif
|
||||
return JNI_FALSE;
|
||||
}
|
||||
if (!getDisplayModes(disp, screen, &num_modes, &avail_modes)) {
|
||||
XCloseDisplay(disp);
|
||||
#ifdef _DEBUG
|
||||
|
@ -194,19 +264,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass c
|
|||
return JNI_FALSE;
|
||||
}
|
||||
root_win = RootWindow(disp, screen);
|
||||
if (extgl_Open() != 0) {
|
||||
#ifdef _DEBUG
|
||||
printf("Could not load gl libs\n");
|
||||
#endif
|
||||
return JNI_FALSE;
|
||||
}
|
||||
vis_info = glXChooseVisual(disp, screen, attriblist);
|
||||
|
||||
/* might be a better way to handle not being able to set GLX_ALPHA_SIZE... */
|
||||
/* if (vis_info == NULL) {
|
||||
vis_info = glXChooseVisual(disp, screen, attriblistna);
|
||||
}
|
||||
*/
|
||||
vis_info = chooseVisual(disp, screen, bpp, depth_bits, alpha_bits, stencil_bits);
|
||||
if (vis_info == NULL) {
|
||||
XCloseDisplay(disp);
|
||||
#ifdef _DEBUG
|
||||
|
@ -288,22 +346,29 @@ JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_Display_getAvailableDisplayModes
|
|||
int screen = DefaultScreen(disp);
|
||||
XF86VidModeModeInfo **avail_modes;
|
||||
|
||||
int depth = DefaultDepth(disp, screen);
|
||||
|
||||
if (disp == NULL) {
|
||||
#ifdef _DEBUG
|
||||
printf("Could not open X connection\n");
|
||||
#endif
|
||||
XCloseDisplay(disp);
|
||||
return NULL;
|
||||
}
|
||||
if (loadGL(disp, screen) != JNI_TRUE) {
|
||||
#ifdef _DEBUG
|
||||
printf("Could not load GL\n");
|
||||
#endif
|
||||
XCloseDisplay(disp);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
if (!getDisplayModes(disp, screen, &num_modes, &avail_modes)) {
|
||||
#ifdef _DEBUG
|
||||
printf("Could not get display modes\n");
|
||||
#endif
|
||||
XCloseDisplay(disp);
|
||||
return NULL;
|
||||
}
|
||||
int num_pixelformats;
|
||||
struct pixelformat *formats = getAvailablePixelFormats(&num_pixelformats);
|
||||
struct pixelformat *formats = getAvailablePixelFormats(disp, screen, &num_pixelformats);
|
||||
// Allocate an array of DisplayModes big enough
|
||||
jclass displayModeClass = env->FindClass("org/lwjgl/DisplayMode");
|
||||
jobjectArray ret = env->NewObjectArray(num_modes*num_pixelformats, displayModeClass, NULL);
|
||||
|
@ -311,7 +376,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_Display_getAvailableDisplayModes
|
|||
|
||||
for (i = 0; i < num_modes; i++) {
|
||||
for (int j = 0; j < num_pixelformats; j++) {
|
||||
jobject displayMode = env->NewObject(displayModeClass, displayModeConstructor, avail_modes[i]->hdisplay, avail_modes[i]->vdisplay, depth, 0, formats[j].alpha, formats[j].depth, formats[j].stencil);
|
||||
jobject displayMode = env->NewObject(displayModeClass, displayModeConstructor, avail_modes[i]->hdisplay, avail_modes[i]->vdisplay, formats[j].bpp, 0, formats[j].alpha, formats[j].depth, formats[j].stencil);
|
||||
env->SetObjectArrayElement(ret, i*num_pixelformats + j, displayMode);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue