mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 19:08:55 -04:00
more robust handling of glx version and extension functions w.r.t. pbuffers and pixmaps
This commit is contained in:
parent
30dddab983
commit
4fd129413a
@ -408,8 +408,8 @@ make_output(GraphicsPipe *pipe,
|
|||||||
<< " got: " << window->get_fb_properties() << "\n";
|
<< " got: " << window->get_fb_properties() << "\n";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
display_cat.error()
|
display_cat.info()
|
||||||
<< "Window wouldn't open; abandoning window.\n";
|
<< window->get_type() << " wouldn't open; abandoning.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// No good; delete the window and keep trying.
|
// No good; delete the window and keep trying.
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
glxGraphicsWindow.h glxGraphicsWindow.cxx \
|
glxGraphicsWindow.h glxGraphicsWindow.cxx \
|
||||||
glxGraphicsStateGuardian.h glxGraphicsStateGuardian.I \
|
glxGraphicsStateGuardian.h glxGraphicsStateGuardian.I \
|
||||||
glxGraphicsStateGuardian.cxx \
|
glxGraphicsStateGuardian.cxx \
|
||||||
glxext.h
|
panda_glxext.h
|
||||||
|
|
||||||
#define INSTALL_HEADERS \
|
#define INSTALL_HEADERS \
|
||||||
glxGraphicsBuffer.I glxGraphicsBuffer.h \
|
glxGraphicsBuffer.I glxGraphicsBuffer.h \
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "glxGraphicsBuffer.h"
|
#include "glxGraphicsBuffer.h"
|
||||||
#include "glxGraphicsPipe.h"
|
#include "glxGraphicsPipe.h"
|
||||||
#include "glxGraphicsPixmap.h"
|
#include "glxGraphicsPixmap.h"
|
||||||
|
#include "glxGraphicsBuffer.h"
|
||||||
#include "glxGraphicsWindow.h"
|
#include "glxGraphicsWindow.h"
|
||||||
#include "glxGraphicsStateGuardian.h"
|
#include "glxGraphicsStateGuardian.h"
|
||||||
#include "graphicsPipeSelection.h"
|
#include "graphicsPipeSelection.h"
|
||||||
@ -43,6 +44,19 @@ ConfigVariableBool glx_get_os_address
|
|||||||
"addresses of extension functions. This will be done only "
|
"addresses of extension functions. This will be done only "
|
||||||
"if glxGetProcAddress() cannot be used for some reason."));
|
"if glxGetProcAddress() cannot be used for some reason."));
|
||||||
|
|
||||||
|
ConfigVariableBool gl_support_fbo
|
||||||
|
("gl-support-fbo", true,
|
||||||
|
PRC_DESC("Configure this false if your GL's implementation of "
|
||||||
|
"EXT_framebuffer_object is broken. The system might still be "
|
||||||
|
"able to create buffers using pbuffers or the like."));
|
||||||
|
|
||||||
|
ConfigVariableBool glx_support_fbconfig
|
||||||
|
("glx-support-fbconfig", true,
|
||||||
|
PRC_DESC("Set this true to enable the use of the advanced FBConfig "
|
||||||
|
"interface (as opposed to the older XVisual interface) "
|
||||||
|
"if it is available, to select a graphics visual and "
|
||||||
|
"create an OpenGL context."));
|
||||||
|
|
||||||
ConfigVariableBool glx_support_pbuffer
|
ConfigVariableBool glx_support_pbuffer
|
||||||
("glx-support-pbuffer", true,
|
("glx-support-pbuffer", true,
|
||||||
PRC_DESC("Set this true to enable the use of X pbuffer-based offscreen "
|
PRC_DESC("Set this true to enable the use of X pbuffer-based offscreen "
|
||||||
@ -53,9 +67,7 @@ ConfigVariableBool glx_support_pixmap
|
|||||||
("glx-support-pixmap", false,
|
("glx-support-pixmap", false,
|
||||||
PRC_DESC("Set this true to enable the use of X pixmap-based offscreen "
|
PRC_DESC("Set this true to enable the use of X pixmap-based offscreen "
|
||||||
"buffers. This is false by default because pixmap-based buffers "
|
"buffers. This is false by default because pixmap-based buffers "
|
||||||
"are usually slower than pbuffer-based buffers, and because at "
|
"are usually slower than pbuffer-based buffers."));
|
||||||
"least one driver is known to crash (crash!) when it attempts "
|
|
||||||
"to create a pixmap-based buffer."));
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -79,6 +91,7 @@ init_libglxdisplay() {
|
|||||||
#endif // HAVE_GLXFBCONFIG
|
#endif // HAVE_GLXFBCONFIG
|
||||||
glxGraphicsPipe::init_type();
|
glxGraphicsPipe::init_type();
|
||||||
glxGraphicsPixmap::init_type();
|
glxGraphicsPixmap::init_type();
|
||||||
|
glxGraphicsBuffer::init_type();
|
||||||
glxGraphicsWindow::init_type();
|
glxGraphicsWindow::init_type();
|
||||||
glxGraphicsStateGuardian::init_type();
|
glxGraphicsStateGuardian::init_type();
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@ extern EXPCL_PANDAGL void init_libglxdisplay();
|
|||||||
extern ConfigVariableBool glx_get_proc_address;
|
extern ConfigVariableBool glx_get_proc_address;
|
||||||
extern ConfigVariableBool glx_get_os_address;
|
extern ConfigVariableBool glx_get_os_address;
|
||||||
|
|
||||||
|
extern ConfigVariableBool gl_support_fbo;
|
||||||
|
extern ConfigVariableBool glx_support_fbconfig;
|
||||||
extern ConfigVariableBool glx_support_pbuffer;
|
extern ConfigVariableBool glx_support_pbuffer;
|
||||||
extern ConfigVariableBool glx_support_pixmap;
|
extern ConfigVariableBool glx_support_pixmap;
|
||||||
|
|
||||||
|
@ -21,10 +21,6 @@
|
|||||||
#include "glgsg.h"
|
#include "glgsg.h"
|
||||||
#include "pStatTimer.h"
|
#include "pStatTimer.h"
|
||||||
|
|
||||||
#ifdef HAVE_GLXFBCONFIG
|
|
||||||
// This whole class doesn't make sense unless we have the GLXFBConfig
|
|
||||||
// and associated GLXPbuffer interfaces available.
|
|
||||||
|
|
||||||
TypeHandle glxGraphicsBuffer::_type_handle;
|
TypeHandle glxGraphicsBuffer::_type_handle;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -76,7 +72,8 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||||||
PStatTimer timer(_make_current_pcollector, current_thread);
|
PStatTimer timer(_make_current_pcollector, current_thread);
|
||||||
|
|
||||||
begin_frame_spam(mode);
|
begin_frame_spam(mode);
|
||||||
if (_gsg == (GraphicsStateGuardian *)NULL) {
|
if (_gsg == (GraphicsStateGuardian *)NULL ||
|
||||||
|
_pbuffer == None) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,15 +137,19 @@ void glxGraphicsBuffer::
|
|||||||
close_buffer() {
|
close_buffer() {
|
||||||
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
||||||
glXMakeCurrent(_display, None, NULL);
|
glXMakeCurrent(_display, None, NULL);
|
||||||
|
|
||||||
|
if (_pbuffer != None) {
|
||||||
|
glxGraphicsStateGuardian *glxgsg;
|
||||||
|
DCAST_INTO_V(glxgsg, _gsg);
|
||||||
|
glxgsg->_glXDestroyPbuffer(_display, _pbuffer);
|
||||||
|
_pbuffer = None;
|
||||||
|
}
|
||||||
|
|
||||||
_gsg.clear();
|
_gsg.clear();
|
||||||
_active = false;
|
_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_pbuffer != None) {
|
_pbuffer = None;
|
||||||
glXDestroyPbuffer(_display, _pbuffer);
|
|
||||||
_pbuffer = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
_is_valid = false;
|
_is_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,43 +176,47 @@ open_buffer() {
|
|||||||
// If the old gsg has the wrong pixel format, create a
|
// If the old gsg has the wrong pixel format, create a
|
||||||
// new one that shares with the old gsg.
|
// new one that shares with the old gsg.
|
||||||
DCAST_INTO_R(glxgsg, _gsg, false);
|
DCAST_INTO_R(glxgsg, _gsg, false);
|
||||||
if (!glxgsg->get_fb_properties().subsumes(_fb_properties)) {
|
|
||||||
|
if (!glxgsg->_context_has_pbuffer ||
|
||||||
|
!glxgsg->get_fb_properties().subsumes(_fb_properties)) {
|
||||||
|
// We need a new pixel format, and hence a new GSG.
|
||||||
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg);
|
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg);
|
||||||
glxgsg->choose_pixel_format(_fb_properties, glx_pipe->get_display(), glx_pipe->get_screen(), true, false);
|
glxgsg->choose_pixel_format(_fb_properties, glx_pipe->get_display(), glx_pipe->get_screen(), true, false);
|
||||||
_gsg = glxgsg;
|
_gsg = glxgsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glxgsg->_fbconfig == None) {
|
if (glxgsg->_fbconfig == None || glxgsg->_context_has_pbuffer) {
|
||||||
// If we didn't use an fbconfig to create the GSG, we can't create
|
// If we didn't use an fbconfig to create the GSG, or it doesn't
|
||||||
// a PBuffer.
|
// support buffers, we can't create a PBuffer.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nassertr(glxgsg->_supports_pbuffer, false);
|
||||||
|
|
||||||
static const int max_attrib_list = 32;
|
static const int max_attrib_list = 32;
|
||||||
int attrib_list[max_attrib_list];
|
int attrib_list[max_attrib_list];
|
||||||
int n=0;
|
int n = 0;
|
||||||
|
|
||||||
#ifdef HAVE_OFFICIAL_GLXFBCONFIG
|
if (glxgsg->_uses_sgix_pbuffer) {
|
||||||
// The official GLX 1.3 version passes in the size in the attrib
|
// The SGI version passed in the size in the parameter list.
|
||||||
// list.
|
nassertr(n < max_attrib_list, false);
|
||||||
attrib_list[n++] = GLX_PBUFFER_WIDTH;
|
attrib_list[n] = (int)None;
|
||||||
attrib_list[n++] = _x_size;
|
_pbuffer = glxgsg->_glXCreateGLXPbufferSGIX(glxgsg->_display, glxgsg->_fbconfig,
|
||||||
attrib_list[n++] = GLX_PBUFFER_HEIGHT;
|
_x_size, _y_size, attrib_list);
|
||||||
attrib_list[n++] = _y_size;
|
} else {
|
||||||
|
// The official GLX 1.3 version passes in the size in the attrib
|
||||||
nassertr(n < max_attrib_list, false);
|
// list.
|
||||||
attrib_list[n] = (int)None;
|
attrib_list[n++] = GLX_PBUFFER_WIDTH;
|
||||||
_pbuffer = glXCreatePbuffer(glxgsg->_display, glxgsg->_fbconfig,
|
attrib_list[n++] = _x_size;
|
||||||
attrib_list);
|
attrib_list[n++] = GLX_PBUFFER_HEIGHT;
|
||||||
|
attrib_list[n++] = _y_size;
|
||||||
#else
|
|
||||||
// The SGI version passed in the size in the parameter list.
|
nassertr(n < max_attrib_list, false);
|
||||||
nassertr(n < max_attrib_list, false);
|
attrib_list[n] = (int)None;
|
||||||
attrib_list[n] = (int)None;
|
_pbuffer = glxgsg->_glXCreatePbuffer(glxgsg->_display, glxgsg->_fbconfig,
|
||||||
_pbuffer = glXCreateGLXPbufferSGIX(glxgsg->_display, glxgsg->_fbconfig,
|
attrib_list);
|
||||||
_x_size, _y_size, attrib_list);
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (_pbuffer == None) {
|
if (_pbuffer == None) {
|
||||||
glxdisplay_cat.error()
|
glxdisplay_cat.error()
|
||||||
@ -235,6 +240,3 @@ open_buffer() {
|
|||||||
_is_valid = true;
|
_is_valid = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // HAVE_GLXFBCONFIG
|
|
||||||
|
@ -20,10 +20,6 @@
|
|||||||
#include "glxGraphicsPipe.h"
|
#include "glxGraphicsPipe.h"
|
||||||
#include "graphicsBuffer.h"
|
#include "graphicsBuffer.h"
|
||||||
|
|
||||||
#ifdef HAVE_GLXFBCONFIG
|
|
||||||
// This whole class doesn't make sense unless we have the GLXFBConfig
|
|
||||||
// and associated GLXPbuffer interfaces available.
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : glxGraphicsBuffer
|
// Class : glxGraphicsBuffer
|
||||||
// Description : An offscreen buffer in the GLX environment. This
|
// Description : An offscreen buffer in the GLX environment. This
|
||||||
@ -71,6 +67,4 @@ private:
|
|||||||
|
|
||||||
#include "glxGraphicsBuffer.I"
|
#include "glxGraphicsBuffer.I"
|
||||||
|
|
||||||
#endif // HAVE_GLXFBCONFIG
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -119,7 +119,7 @@ make_output(const string &name,
|
|||||||
|
|
||||||
if (retry == 1) {
|
if (retry == 1) {
|
||||||
if ((host==0)||
|
if ((host==0)||
|
||||||
// (!gl_support_fbo)||
|
(!gl_support_fbo)||
|
||||||
((flags&BF_require_parasite)!=0)||
|
((flags&BF_require_parasite)!=0)||
|
||||||
((flags&BF_require_window)!=0)) {
|
((flags&BF_require_window)!=0)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -152,34 +152,33 @@ make_output(const string &name,
|
|||||||
flags, gsg, host);
|
flags, gsg, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_GLXFBCONFIG
|
|
||||||
// Third thing to try: a glxGraphicsBuffer
|
// Third thing to try: a glxGraphicsBuffer
|
||||||
|
if (glxgsg == NULL || glxgsg->_supports_fbconfig) {
|
||||||
if (retry == 2) {
|
if (retry == 2) {
|
||||||
if (!glx_support_pbuffer) {
|
if (!glx_support_pbuffer) {
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((flags&BF_require_parasite)!=0)||
|
|
||||||
((flags&BF_require_window)!=0)||
|
|
||||||
((flags&BF_resizeable)!=0)||
|
|
||||||
((flags&BF_size_track_host)!=0)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!support_rtt) {
|
|
||||||
if (((flags&BF_rtt_cumulative)!=0)||
|
|
||||||
((flags&BF_can_bind_every)!=0)) {
|
|
||||||
// If we require Render-to-Texture, but can't be sure we
|
|
||||||
// support it, bail.
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (((flags&BF_require_parasite)!=0)||
|
||||||
|
((flags&BF_require_window)!=0)||
|
||||||
|
((flags&BF_resizeable)!=0)||
|
||||||
|
((flags&BF_size_track_host)!=0)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!support_rtt) {
|
||||||
|
if (((flags&BF_rtt_cumulative)!=0)||
|
||||||
|
((flags&BF_can_bind_every)!=0)) {
|
||||||
|
// If we require Render-to-Texture, but can't be sure we
|
||||||
|
// support it, bail.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new glxGraphicsBuffer(engine, this, name, fb_prop, win_prop,
|
||||||
|
flags, gsg, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new glxGraphicsBuffer(engine, this, name, fb_prop, win_prop,
|
|
||||||
flags, gsg, host);
|
|
||||||
}
|
}
|
||||||
#endif // HAVE_GLXFBCONFIG
|
|
||||||
|
|
||||||
// Third thing to try: a glxGraphicsPixmap.
|
// Third thing to try: a glxGraphicsPixmap.
|
||||||
if (retry == 3) {
|
if (retry == 3) {
|
||||||
|
@ -27,20 +27,25 @@ class FrameBufferProperties;
|
|||||||
|
|
||||||
#ifndef CPPPARSER
|
#ifndef CPPPARSER
|
||||||
|
|
||||||
|
// Don't pick up the system glxext.h; use our own, which is better.
|
||||||
|
#define __glxext_h_
|
||||||
|
|
||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
|
|
||||||
|
/*
|
||||||
#if defined(GLX_VERSION_1_3)
|
#if defined(GLX_VERSION_1_3)
|
||||||
// If the system glx version is at least 1.3, then we know we have
|
// If the system glx version is at least 1.3, then we know we have
|
||||||
// GLXFBConfig and GLXPbuffer.
|
// GLXFBConfig and GLXPbuffer.
|
||||||
#define HAVE_GLXFBCONFIG
|
#define HAVE_GLXFBCONFIG
|
||||||
#define HAVE_OFFICIAL_GLXFBCONFIG
|
#define HAVE_OFFICIAL_GLXFBCONFIG
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
// This must be included after we have included glgsg.h (which
|
// This must be included after we have included glgsg.h (which
|
||||||
// includes gl.h), and after we have checked GLX_VERSION_1_3. But we
|
// includes gl.h), and after we have checked GLX_VERSION_1_3. But we
|
||||||
// must also include it before we redefine the GLXFBConfig types,
|
// must also include it before we redefine the GLXFBConfig types,
|
||||||
// below.
|
// below.
|
||||||
#include "glxext.h"
|
#include "panda_glxext.h"
|
||||||
|
|
||||||
// drose: the version of GL/glx.h that ships with Fedora Core 2 seems
|
// drose: the version of GL/glx.h that ships with Fedora Core 2 seems
|
||||||
// to define GLX_VERSION_1_4, but for some reason does not define
|
// to define GLX_VERSION_1_4, but for some reason does not define
|
||||||
@ -54,6 +59,7 @@ class FrameBufferProperties;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
#if !defined(HAVE_GLXFBCONFIG) && defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
|
#if !defined(HAVE_GLXFBCONFIG) && defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
|
||||||
// If the system glx version isn't 1.3, but these were defined as
|
// If the system glx version isn't 1.3, but these were defined as
|
||||||
// extensions, we can work with that.
|
// extensions, we can work with that.
|
||||||
@ -68,6 +74,7 @@ class FrameBufferProperties;
|
|||||||
#define HAVE_GLXFBCONFIG
|
#define HAVE_GLXFBCONFIG
|
||||||
#define HAVE_SGI_GLXFBCONFIG
|
#define HAVE_SGI_GLXFBCONFIG
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
#endif // CPPPARSER
|
#endif // CPPPARSER
|
||||||
|
|
||||||
|
@ -75,7 +75,8 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||||||
PStatTimer timer(_make_current_pcollector, current_thread);
|
PStatTimer timer(_make_current_pcollector, current_thread);
|
||||||
|
|
||||||
begin_frame_spam(mode);
|
begin_frame_spam(mode);
|
||||||
if (_gsg == (GraphicsStateGuardian *)NULL) {
|
if (_gsg == (GraphicsStateGuardian *)NULL ||
|
||||||
|
_glx_pixmap == None) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,13 +180,19 @@ open_buffer() {
|
|||||||
// If the old gsg has the wrong pixel format, create a
|
// If the old gsg has the wrong pixel format, create a
|
||||||
// new one that shares with the old gsg.
|
// new one that shares with the old gsg.
|
||||||
DCAST_INTO_R(glxgsg, _gsg, false);
|
DCAST_INTO_R(glxgsg, _gsg, false);
|
||||||
if (!glxgsg->get_fb_properties().subsumes(_fb_properties)) {
|
if (!glxgsg->_context_has_pixmap ||
|
||||||
|
!glxgsg->get_fb_properties().subsumes(_fb_properties)) {
|
||||||
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg);
|
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg);
|
||||||
glxgsg->choose_pixel_format(_fb_properties, _display, glx_pipe->get_screen(), false, true);
|
glxgsg->choose_pixel_format(_fb_properties, _display, glx_pipe->get_screen(), false, true);
|
||||||
_gsg = glxgsg;
|
_gsg = glxgsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!glxgsg->_context_has_pixmap) {
|
||||||
|
// Hmm, the GSG we created won't work.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
XVisualInfo *visual_info = glxgsg->_visual;
|
XVisualInfo *visual_info = glxgsg->_visual;
|
||||||
if (visual_info == NULL) {
|
if (visual_info == NULL) {
|
||||||
// No X visual for this fbconfig; how can we create the pixmap?
|
// No X visual for this fbconfig; how can we create the pixmap?
|
||||||
@ -214,16 +221,13 @@ open_buffer() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_GLXFBCONFIG
|
|
||||||
if (glxgsg->_fbconfig) {
|
if (glxgsg->_fbconfig) {
|
||||||
// Use the FBConfig to create the pixmap.
|
// Use the FBConfig to create the pixmap.
|
||||||
_glx_pixmap = glXCreatePixmap(_display, glxgsg->_fbconfig, _x_pixmap, NULL);
|
_glx_pixmap = glxgsg->_glXCreatePixmap(_display, glxgsg->_fbconfig, _x_pixmap, NULL);
|
||||||
} else
|
} else {
|
||||||
#endif // HAVE_GLXFBCONFIG
|
// Use the XVisual to create the pixmap.
|
||||||
{
|
_glx_pixmap = glXCreateGLXPixmap(_display, visual_info, _x_pixmap);
|
||||||
// Use the XVisual to create the pixmap.
|
}
|
||||||
_glx_pixmap = glXCreateGLXPixmap(_display, visual_info, _x_pixmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glx_pixmap == None) {
|
if (_glx_pixmap == None) {
|
||||||
glxdisplay_cat.error()
|
glxdisplay_cat.error()
|
||||||
|
@ -39,6 +39,14 @@ glxGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||||||
_visual=0;
|
_visual=0;
|
||||||
_visuals=0;
|
_visuals=0;
|
||||||
_fbconfig=0;
|
_fbconfig=0;
|
||||||
|
_context_has_pbuffer = false;
|
||||||
|
_context_has_pixmap = false;
|
||||||
|
_slow = false;
|
||||||
|
|
||||||
|
_supports_swap_control = false;
|
||||||
|
_supports_fbconfig = false;
|
||||||
|
_supports_pbuffer = false;
|
||||||
|
_uses_sgix_pbuffer = false;
|
||||||
|
|
||||||
if (share_with != (glxGraphicsStateGuardian *)NULL) {
|
if (share_with != (glxGraphicsStateGuardian *)NULL) {
|
||||||
_prepared_objects = share_with->get_prepared_objects();
|
_prepared_objects = share_with->get_prepared_objects();
|
||||||
@ -48,6 +56,7 @@ glxGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||||||
_libgl_handle = NULL;
|
_libgl_handle = NULL;
|
||||||
_checked_get_proc_address = false;
|
_checked_get_proc_address = false;
|
||||||
_glXGetProcAddress = NULL;
|
_glXGetProcAddress = NULL;
|
||||||
|
_temp_xwindow = (Window)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -57,6 +66,7 @@ glxGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
glxGraphicsStateGuardian::
|
glxGraphicsStateGuardian::
|
||||||
~glxGraphicsStateGuardian() {
|
~glxGraphicsStateGuardian() {
|
||||||
|
destroy_temp_xwindow();
|
||||||
if (_visuals != (XVisualInfo *)NULL) {
|
if (_visuals != (XVisualInfo *)NULL) {
|
||||||
XFree(_visuals);
|
XFree(_visuals);
|
||||||
}
|
}
|
||||||
@ -71,7 +81,7 @@ glxGraphicsStateGuardian::
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: glxGraphicsStateGuardian::get_properties
|
// Function: glxGraphicsStateGuardian::get_properties
|
||||||
// Access: Private
|
// Access: Public
|
||||||
// Description: Gets the FrameBufferProperties to match the
|
// Description: Gets the FrameBufferProperties to match the
|
||||||
// indicated visual.
|
// indicated visual.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -131,87 +141,86 @@ get_properties(FrameBufferProperties &properties, XVisualInfo *visual) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: glxGraphicsStateGuardian::get_properties_advanced
|
// Function: glxGraphicsStateGuardian::get_properties_advanced
|
||||||
// Access: Private
|
// Access: Public
|
||||||
// Description: Gets the FrameBufferProperties to match the
|
// Description: Gets the FrameBufferProperties to match the
|
||||||
// indicated GLXFBConfig
|
// indicated GLXFBConfig
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void glxGraphicsStateGuardian::
|
void glxGraphicsStateGuardian::
|
||||||
get_properties_advanced(FrameBufferProperties &properties,
|
get_properties_advanced(FrameBufferProperties &properties,
|
||||||
bool &pbuffer_supported, bool &pixmap_supported,
|
bool &context_has_pbuffer, bool &context_has_pixmap,
|
||||||
bool &slow, fbconfig config) {
|
bool &slow, GLXFBConfig config) {
|
||||||
|
|
||||||
properties.clear();
|
properties.clear();
|
||||||
|
|
||||||
#ifdef HAVE_GLXFBCONFIG
|
if (_supports_fbconfig) {
|
||||||
// Now update our framebuffer_mode and bit depth appropriately.
|
// Now update our framebuffer_mode and bit depth appropriately.
|
||||||
int render_mode, double_buffer, stereo, red_size, green_size, blue_size,
|
int render_mode, double_buffer, stereo, red_size, green_size, blue_size,
|
||||||
alpha_size, ared_size, agreen_size, ablue_size, aalpha_size,
|
alpha_size, ared_size, agreen_size, ablue_size, aalpha_size,
|
||||||
depth_size, stencil_size, samples, drawable_type, caveat;
|
depth_size, stencil_size, samples, drawable_type, caveat;
|
||||||
|
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_RGBA, &render_mode);
|
_glXGetFBConfigAttrib(_display, config, GLX_RGBA, &render_mode);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_DOUBLEBUFFER, &double_buffer);
|
_glXGetFBConfigAttrib(_display, config, GLX_DOUBLEBUFFER, &double_buffer);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_STEREO, &stereo);
|
_glXGetFBConfigAttrib(_display, config, GLX_STEREO, &stereo);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_RED_SIZE, &red_size);
|
_glXGetFBConfigAttrib(_display, config, GLX_RED_SIZE, &red_size);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_GREEN_SIZE, &green_size);
|
_glXGetFBConfigAttrib(_display, config, GLX_GREEN_SIZE, &green_size);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_BLUE_SIZE, &blue_size);
|
_glXGetFBConfigAttrib(_display, config, GLX_BLUE_SIZE, &blue_size);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_ALPHA_SIZE, &alpha_size);
|
_glXGetFBConfigAttrib(_display, config, GLX_ALPHA_SIZE, &alpha_size);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_ACCUM_RED_SIZE, &ared_size);
|
_glXGetFBConfigAttrib(_display, config, GLX_ACCUM_RED_SIZE, &ared_size);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_ACCUM_GREEN_SIZE, &agreen_size);
|
_glXGetFBConfigAttrib(_display, config, GLX_ACCUM_GREEN_SIZE, &agreen_size);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_ACCUM_BLUE_SIZE, &ablue_size);
|
_glXGetFBConfigAttrib(_display, config, GLX_ACCUM_BLUE_SIZE, &ablue_size);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_ACCUM_ALPHA_SIZE, &aalpha_size);
|
_glXGetFBConfigAttrib(_display, config, GLX_ACCUM_ALPHA_SIZE, &aalpha_size);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_DEPTH_SIZE, &depth_size);
|
_glXGetFBConfigAttrib(_display, config, GLX_DEPTH_SIZE, &depth_size);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_STENCIL_SIZE, &stencil_size);
|
_glXGetFBConfigAttrib(_display, config, GLX_STENCIL_SIZE, &stencil_size);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_SAMPLES, &samples);
|
_glXGetFBConfigAttrib(_display, config, GLX_SAMPLES, &samples);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_DRAWABLE_TYPE, &drawable_type);
|
_glXGetFBConfigAttrib(_display, config, GLX_DRAWABLE_TYPE, &drawable_type);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_CONFIG_CAVEAT, &caveat);
|
_glXGetFBConfigAttrib(_display, config, GLX_CONFIG_CAVEAT, &caveat);
|
||||||
|
|
||||||
pbuffer_supported = false;
|
context_has_pbuffer = false;
|
||||||
if ((drawable_type & GLX_PBUFFER_BIT)!=0) {
|
if ((drawable_type & GLX_PBUFFER_BIT)!=0) {
|
||||||
pbuffer_supported = true;
|
context_has_pbuffer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
context_has_pixmap = false;
|
||||||
|
if ((drawable_type & GLX_PIXMAP_BIT)!=0) {
|
||||||
|
context_has_pixmap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
slow = false;
|
||||||
|
if (caveat == GLX_SLOW_CONFIG) {
|
||||||
|
slow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((drawable_type & GLX_WINDOW_BIT)==0) {
|
||||||
|
// We insist on having a context that will support an onscreen window.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (double_buffer) {
|
||||||
|
properties.set_back_buffers(1);
|
||||||
|
}
|
||||||
|
if (stereo) {
|
||||||
|
properties.set_stereo(1);
|
||||||
|
}
|
||||||
|
if (render_mode) {
|
||||||
|
properties.set_rgb_color(1);
|
||||||
|
} else {
|
||||||
|
properties.set_indexed_color(1);
|
||||||
|
}
|
||||||
|
properties.set_color_bits(red_size+green_size+blue_size);
|
||||||
|
properties.set_stencil_bits(stencil_size);
|
||||||
|
properties.set_depth_bits(depth_size);
|
||||||
|
properties.set_alpha_bits(alpha_size);
|
||||||
|
properties.set_accum_bits(ared_size+agreen_size+ablue_size+aalpha_size);
|
||||||
|
properties.set_multisamples(samples);
|
||||||
|
|
||||||
|
// Set both hardware and software bits, indicating not-yet-known.
|
||||||
|
properties.set_force_software(1);
|
||||||
|
properties.set_force_hardware(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pixmap_supported = false;
|
|
||||||
if ((drawable_type & GLX_PIXMAP_BIT)!=0) {
|
|
||||||
pixmap_supported = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
slow = false;
|
|
||||||
if (caveat == GLX_SLOW_CONFIG) {
|
|
||||||
slow = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((drawable_type & GLX_WINDOW_BIT)==0) {
|
|
||||||
// We insist on having a context that will support an onscreen window.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (double_buffer) {
|
|
||||||
properties.set_back_buffers(1);
|
|
||||||
}
|
|
||||||
if (stereo) {
|
|
||||||
properties.set_stereo(1);
|
|
||||||
}
|
|
||||||
if (render_mode) {
|
|
||||||
properties.set_rgb_color(1);
|
|
||||||
} else {
|
|
||||||
properties.set_indexed_color(1);
|
|
||||||
}
|
|
||||||
properties.set_color_bits(red_size+green_size+blue_size);
|
|
||||||
properties.set_stencil_bits(stencil_size);
|
|
||||||
properties.set_depth_bits(depth_size);
|
|
||||||
properties.set_alpha_bits(alpha_size);
|
|
||||||
properties.set_accum_bits(ared_size+agreen_size+ablue_size+aalpha_size);
|
|
||||||
properties.set_multisamples(samples);
|
|
||||||
|
|
||||||
// Set both hardware and software bits, indicating not-yet-known.
|
|
||||||
properties.set_force_software(1);
|
|
||||||
properties.set_force_hardware(1);
|
|
||||||
#endif // HAVE_GLXFBCONFIG
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: glxGraphicsStateGuardian::choose_pixel_format
|
// Function: glxGraphicsStateGuardian::choose_pixel_format
|
||||||
// Access: Private
|
// Access: Public
|
||||||
// Description: Selects a visual or fbconfig for all the windows
|
// Description: Selects a visual or fbconfig for all the windows
|
||||||
// and buffers that use this gsg. Also creates the GL
|
// and buffers that use this gsg. Also creates the GL
|
||||||
// context and obtains the visual.
|
// context and obtains the visual.
|
||||||
@ -229,8 +238,51 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
|||||||
_visuals = 0;
|
_visuals = 0;
|
||||||
_fbprops.clear();
|
_fbprops.clear();
|
||||||
|
|
||||||
#ifdef HAVE_GLXFBCONFIG
|
// First, attempt to create a context using the XVisual interface.
|
||||||
//// Choose best format available using GLXFBConfig
|
// We need this before we can query the FBConfig interface, because
|
||||||
|
// we need an OpenGL context to get the required extension function
|
||||||
|
// pointers.
|
||||||
|
choose_visual(properties);
|
||||||
|
if (_context == NULL) {
|
||||||
|
// No good.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we have to initialize the context so we can query its
|
||||||
|
// capabilities and extensions. This also means creating a
|
||||||
|
// temporary window, so we have something to bind the context to and
|
||||||
|
// make it current.
|
||||||
|
init_temp_context();
|
||||||
|
|
||||||
|
if (!_supports_fbconfig) {
|
||||||
|
// We have a good OpenGL context, but it doesn't support the
|
||||||
|
// FBConfig interface, so we'll stop there.
|
||||||
|
if (glxdisplay_cat.is_debug()) {
|
||||||
|
glxdisplay_cat.debug()
|
||||||
|
<<" No FBConfig supported; using XVisual only.\n";
|
||||||
|
|
||||||
|
glxdisplay_cat.debug()
|
||||||
|
<< _fbprops << "\n";
|
||||||
|
|
||||||
|
// By convention, every indirect XVisual that can render to a
|
||||||
|
// window can also render to a GLXPixmap. Direct visuals we're
|
||||||
|
// not as sure about.
|
||||||
|
_context_has_pixmap = !glXIsDirect(_display, _context);
|
||||||
|
|
||||||
|
// Pbuffers aren't supported at all with the XVisual interface.
|
||||||
|
_context_has_pbuffer = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The OpenGL context supports the FBConfig interface, so we can use
|
||||||
|
// that more advanced interface to choose the actual window format
|
||||||
|
// we'll use. FBConfig provides for more options than the older
|
||||||
|
// XVisual interface, so we'd much rather use it if it's available.
|
||||||
|
|
||||||
|
int best_quality = 0;
|
||||||
|
int best_result = 0;
|
||||||
|
FrameBufferProperties best_props;
|
||||||
|
|
||||||
static const int max_attrib_list = 32;
|
static const int max_attrib_list = 32;
|
||||||
int attrib_list[max_attrib_list];
|
int attrib_list[max_attrib_list];
|
||||||
@ -242,35 +294,38 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
|||||||
attrib_list[n++] = GLX_DRAWABLE_TYPE;
|
attrib_list[n++] = GLX_DRAWABLE_TYPE;
|
||||||
attrib_list[n++] = GLX_DONT_CARE;
|
attrib_list[n++] = GLX_DONT_CARE;
|
||||||
attrib_list[n] = (int)None;
|
attrib_list[n] = (int)None;
|
||||||
|
|
||||||
int num_configs = 0;
|
int num_configs = 0;
|
||||||
GLXFBConfig *configs =
|
GLXFBConfig *configs =
|
||||||
glXChooseFBConfig(_display, _screen, attrib_list, &num_configs);
|
_glXChooseFBConfig(_display, _screen, attrib_list, &num_configs);
|
||||||
|
|
||||||
int best_quality = 0;
|
// Now that we're done querying the first context, we don't need it
|
||||||
int best_result = 0;
|
// anymore. Clear it so we can create our actual OpenGL context.
|
||||||
FrameBufferProperties best_props;
|
glXDestroyContext(_display, _context);
|
||||||
|
_context = (GLXContext)NULL;
|
||||||
|
destroy_temp_xwindow();
|
||||||
|
|
||||||
if (configs != 0) {
|
if (configs != 0) {
|
||||||
for (int i = 0; i < num_configs; ++i) {
|
for (int i = 0; i < num_configs; ++i) {
|
||||||
FrameBufferProperties fbprops;
|
FrameBufferProperties fbprops;
|
||||||
bool pbuffer_supported, pixmap_supported, slow;
|
bool context_has_pbuffer, context_has_pixmap, slow;
|
||||||
get_properties_advanced(fbprops, pbuffer_supported, pixmap_supported,
|
get_properties_advanced(fbprops, context_has_pbuffer, context_has_pixmap,
|
||||||
slow, configs[i]);
|
slow, configs[i]);
|
||||||
// We're not protecting this code by an is_debug() check, because if we do,
|
// We're not protecting this code by an is_debug() check,
|
||||||
// some weird compiler bug appears and somehow makes the quality always 0.
|
// because if we do, some weird compiler bug appears and somehow
|
||||||
const char *pbuffertext = pbuffer_supported ? " (pbuffer)" : "";
|
// makes the quality always 0.
|
||||||
const char *pixmaptext = pixmap_supported ? " (pixmap)" : "";
|
const char *pbuffertext = context_has_pbuffer ? " (pbuffer)" : "";
|
||||||
|
const char *pixmaptext = context_has_pixmap ? " (pixmap)" : "";
|
||||||
const char *slowtext = slow ? " (slow)" : "";
|
const char *slowtext = slow ? " (slow)" : "";
|
||||||
glxdisplay_cat.debug()
|
glxdisplay_cat.debug()
|
||||||
<< i << ": " << fbprops << pbuffertext << pixmaptext << slowtext << "\n";
|
<< i << ": " << fbprops << pbuffertext << pixmaptext << slowtext << "\n";
|
||||||
int quality = fbprops.get_quality(properties);
|
int quality = fbprops.get_quality(properties);
|
||||||
if ((quality > 0)&&(slow)) quality -= 10000000;
|
if ((quality > 0)&&(slow)) quality -= 10000000;
|
||||||
|
|
||||||
if (need_pbuffer && !pbuffer_supported) {
|
if (need_pbuffer && !context_has_pbuffer) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (need_pixmap && !pixmap_supported) {
|
if (need_pixmap && !context_has_pixmap) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,17 +336,31 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best_quality > 0) {
|
if (best_quality > 0) {
|
||||||
_fbconfig = configs[best_result];
|
_fbconfig = configs[best_result];
|
||||||
_context =
|
_context =
|
||||||
glXCreateNewContext(_display, _fbconfig, GLX_RGBA_TYPE, _share_context,
|
_glXCreateNewContext(_display, _fbconfig, GLX_RGBA_TYPE, _share_context,
|
||||||
GL_TRUE);
|
GL_TRUE);
|
||||||
if (_context) {
|
if (_context) {
|
||||||
_visuals = glXGetVisualFromFBConfig(_display, _fbconfig);
|
_visuals = _glXGetVisualFromFBConfig(_display, _fbconfig);
|
||||||
_visual = _visuals;
|
_visual = _visuals;
|
||||||
|
|
||||||
if (_visual) {
|
if (_visual) {
|
||||||
_fbprops = best_props;
|
get_properties_advanced(_fbprops, _context_has_pbuffer, _context_has_pixmap,
|
||||||
|
_slow, _fbconfig);
|
||||||
|
|
||||||
|
// hack?
|
||||||
|
//init_temp_context();
|
||||||
|
|
||||||
|
if (glxdisplay_cat.is_debug()) {
|
||||||
|
glxdisplay_cat.debug()
|
||||||
|
<< "Selected context " << best_result << "\n";
|
||||||
|
glxdisplay_cat.debug()
|
||||||
|
<< "context_has_pbuffer = " << _context_has_pbuffer
|
||||||
|
<< ", context_has_pixmap = " << _context_has_pixmap << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -303,40 +372,9 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
|||||||
_visual = 0;
|
_visual = 0;
|
||||||
_visuals = 0;
|
_visuals = 0;
|
||||||
}
|
}
|
||||||
#endif // HAVE_GLXFBCONFIG
|
|
||||||
|
|
||||||
if (need_pbuffer) {
|
|
||||||
// The xvisual interface cannot create pbuffers.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan available visuals.
|
glxdisplay_cat.info()
|
||||||
int nvisuals=0;
|
<< "No suitable FBConfig contexts available.\n";
|
||||||
_visuals = XGetVisualInfo(_display, 0, 0, &nvisuals);
|
|
||||||
if (_visuals != 0) {
|
|
||||||
for (int i=0; i<nvisuals; i++) {
|
|
||||||
FrameBufferProperties fbprops;
|
|
||||||
get_properties(fbprops, _visuals+i);
|
|
||||||
int quality = fbprops.get_quality(properties);
|
|
||||||
if (quality > best_quality) {
|
|
||||||
best_quality = quality;
|
|
||||||
best_result = i;
|
|
||||||
best_props = fbprops;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (best_quality > 0) {
|
|
||||||
_visual = _visuals+best_result;
|
|
||||||
_context = glXCreateContext(_display, _visual, None, GL_TRUE);
|
|
||||||
if (_context) {
|
|
||||||
_fbprops = best_props;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glxdisplay_cat.error() <<
|
|
||||||
"Could not find a usable pixel format.\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -367,6 +405,108 @@ reset() {
|
|||||||
_glXSwapIntervalSGI(sync_video ? 1 : 0);
|
_glXSwapIntervalSGI(sync_video ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (glx_support_fbconfig) {
|
||||||
|
if (glx_is_at_least_version(1, 3)) {
|
||||||
|
// If we have glx 1.3 or better, we have the FBConfig interface.
|
||||||
|
_supports_fbconfig = true;
|
||||||
|
|
||||||
|
_glXChooseFBConfig =
|
||||||
|
(PFNGLXCHOOSEFBCONFIGPROC)get_extension_func("glX", "ChooseFBConfig");
|
||||||
|
_glXCreateNewContext =
|
||||||
|
(PFNGLXCREATENEWCONTEXTPROC)get_extension_func("glX", "CreateNewContext");
|
||||||
|
_glXGetVisualFromFBConfig =
|
||||||
|
(PFNGLXGETVISUALFROMFBCONFIGPROC)get_extension_func("glX", "GetVisualFromFBConfig");
|
||||||
|
_glXGetFBConfigAttrib =
|
||||||
|
(PFNGLXGETFBCONFIGATTRIBPROC)get_extension_func("glX", "GetFBConfigAttrib");
|
||||||
|
_glXCreatePixmap =
|
||||||
|
(PFNGLXCREATEPIXMAPPROC)get_extension_func("glX", "CreatePixmap");
|
||||||
|
|
||||||
|
if (_glXChooseFBConfig == NULL ||
|
||||||
|
_glXCreateNewContext == NULL ||
|
||||||
|
_glXGetVisualFromFBConfig == NULL ||
|
||||||
|
_glXGetFBConfigAttrib == NULL ||
|
||||||
|
_glXCreatePixmap == NULL) {
|
||||||
|
glxdisplay_cat.error()
|
||||||
|
<< "Driver claims to support GLX_fbconfig extension, but does not define all functions.\n";
|
||||||
|
_supports_fbconfig = false;
|
||||||
|
}
|
||||||
|
} else if (has_extension("GLX_SGIX_fbconfig")) {
|
||||||
|
// Or maybe we have the old SGIX extension for FBConfig. This is
|
||||||
|
// the same, but the function names are different--we just remap
|
||||||
|
// them to the same function pointers.
|
||||||
|
_supports_fbconfig = true;
|
||||||
|
|
||||||
|
_glXChooseFBConfig =
|
||||||
|
(PFNGLXCHOOSEFBCONFIGPROC)get_extension_func("glX", "ChooseFBConfigSGIX");
|
||||||
|
_glXCreateNewContext =
|
||||||
|
(PFNGLXCREATENEWCONTEXTPROC)get_extension_func("glX", "CreateContextWithConfigSGIX");
|
||||||
|
_glXGetVisualFromFBConfig =
|
||||||
|
(PFNGLXGETVISUALFROMFBCONFIGPROC)get_extension_func("glX", "GetVisualFromFBConfigSGIX");
|
||||||
|
_glXGetFBConfigAttrib =
|
||||||
|
(PFNGLXGETFBCONFIGATTRIBPROC)get_extension_func("glX", "GetFBConfigAttribSGIX");
|
||||||
|
_glXCreatePixmap =
|
||||||
|
(PFNGLXCREATEPIXMAPPROC)get_extension_func("glX", "CreateGLXPixmapWithConfigSGIX");
|
||||||
|
|
||||||
|
if (_glXChooseFBConfig == NULL ||
|
||||||
|
_glXCreateNewContext == NULL ||
|
||||||
|
_glXGetVisualFromFBConfig == NULL ||
|
||||||
|
_glXGetFBConfigAttrib == NULL ||
|
||||||
|
_glXCreatePixmap == NULL) {
|
||||||
|
glxdisplay_cat.error()
|
||||||
|
<< "Driver claims to support GLX_SGIX_fbconfig extension, but does not define all functions.\n";
|
||||||
|
_supports_fbconfig = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (glx_is_at_least_version(1, 3)) {
|
||||||
|
// If we have glx 1.3 or better, we have the PBuffer interface.
|
||||||
|
_supports_pbuffer = true;
|
||||||
|
_uses_sgix_pbuffer = false;
|
||||||
|
|
||||||
|
_glXCreatePbuffer =
|
||||||
|
(PFNGLXCREATEPBUFFERPROC)get_extension_func("glX", "CreatePbuffer");
|
||||||
|
_glXCreateGLXPbufferSGIX = NULL;
|
||||||
|
_glXDestroyPbuffer =
|
||||||
|
(PFNGLXDESTROYPBUFFERPROC)get_extension_func("glX", "DestroyPbuffer");
|
||||||
|
if (_glXCreatePbuffer == NULL ||
|
||||||
|
_glXDestroyPbuffer == NULL) {
|
||||||
|
glxdisplay_cat.error()
|
||||||
|
<< "Driver claims to support GLX_pbuffer extension, but does not define all functions.\n";
|
||||||
|
_supports_pbuffer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (has_extension("GLX_SGIX_pbuffer")) {
|
||||||
|
// Or maybe we have the old SGIX extension for PBuffers.
|
||||||
|
_uses_sgix_pbuffer = true;
|
||||||
|
|
||||||
|
// CreatePbuffer has a different form between SGIX and 1.3,
|
||||||
|
// however, so we must treat it specially. But we can use the
|
||||||
|
// same function pointer for DestroyPbuffer.
|
||||||
|
_glXCreatePbuffer = NULL;
|
||||||
|
_glXCreateGLXPbufferSGIX =
|
||||||
|
(PFNGLXCREATEGLXPBUFFERSGIXPROC)get_extension_func("glX", "CreateGLXPbufferSGIX");
|
||||||
|
_glXDestroyPbuffer =
|
||||||
|
(PFNGLXDESTROYPBUFFERPROC)get_extension_func("glX", "DestroyGLXPbufferSGIX");
|
||||||
|
if (_glXCreateGLXPbufferSGIX == NULL ||
|
||||||
|
_glXDestroyPbuffer == NULL) {
|
||||||
|
glxdisplay_cat.error()
|
||||||
|
<< "Driver claims to support GLX_SGIX_pbuffer extension, but does not define all functions.\n";
|
||||||
|
_supports_pbuffer = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (glxdisplay_cat.is_debug()) {
|
||||||
|
glxdisplay_cat.debug()
|
||||||
|
<< "supports_swap_control = " << _supports_swap_control << "\n";
|
||||||
|
glxdisplay_cat.debug()
|
||||||
|
<< "supports_fbconfig = " << _supports_fbconfig << "\n";
|
||||||
|
glxdisplay_cat.debug()
|
||||||
|
<< "supports_pbuffer = " << _supports_pbuffer
|
||||||
|
<< " sgix = " << _uses_sgix_pbuffer << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
// If "Mesa" is present, assume software. However, if "Mesa DRI" is
|
// If "Mesa" is present, assume software. However, if "Mesa DRI" is
|
||||||
// found, it's actually a Mesa-based OpenGL layer running over a
|
// found, it's actually a Mesa-based OpenGL layer running over a
|
||||||
// hardware driver.
|
// hardware driver.
|
||||||
@ -604,3 +744,90 @@ show_glx_server_string(const string &name, int id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsStateGuardian::choose_visual
|
||||||
|
// Access: Private
|
||||||
|
// Description: Selects a visual for this gsg. This may be called
|
||||||
|
// initially, to create the first context needed in
|
||||||
|
// order to create the fbconfig. On successful return,
|
||||||
|
// _visual and _context will be filled in with a
|
||||||
|
// non-NULL value.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void glxGraphicsStateGuardian::
|
||||||
|
choose_visual(const FrameBufferProperties &properties) {
|
||||||
|
int best_quality = 0;
|
||||||
|
int best_result = 0;
|
||||||
|
FrameBufferProperties best_props;
|
||||||
|
|
||||||
|
// Scan available visuals.
|
||||||
|
int nvisuals = 0;
|
||||||
|
_visuals = XGetVisualInfo(_display, 0, 0, &nvisuals);
|
||||||
|
if (_visuals != 0) {
|
||||||
|
for (int i = 0; i < nvisuals; i++) {
|
||||||
|
FrameBufferProperties fbprops;
|
||||||
|
get_properties(fbprops, _visuals + i);
|
||||||
|
int quality = fbprops.get_quality(properties);
|
||||||
|
if (quality > best_quality) {
|
||||||
|
best_quality = quality;
|
||||||
|
best_result = i;
|
||||||
|
best_props = fbprops;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best_quality > 0) {
|
||||||
|
_visual = _visuals + best_result;
|
||||||
|
_context = glXCreateContext(_display, _visual, None, GL_TRUE);
|
||||||
|
if (_context) {
|
||||||
|
_fbprops = best_props;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glxdisplay_cat.error()
|
||||||
|
<< "Could not find a usable pixel format.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsStateGuardian::init_temp_context
|
||||||
|
// Access: Private
|
||||||
|
// Description: Initializes the context created in choose_visual() by
|
||||||
|
// creating a temporary window and binding the context
|
||||||
|
// to that window.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void glxGraphicsStateGuardian::
|
||||||
|
init_temp_context() {
|
||||||
|
x11GraphicsPipe *x11_pipe;
|
||||||
|
DCAST_INTO_V(x11_pipe, get_pipe());
|
||||||
|
Window root_window = x11_pipe->get_root();
|
||||||
|
|
||||||
|
destroy_temp_xwindow();
|
||||||
|
|
||||||
|
_temp_xwindow = XCreateWindow
|
||||||
|
(_display, root_window, 0, 0, 1, 1,
|
||||||
|
0, _visual->depth, InputOutput,
|
||||||
|
_visual->visual, 0, NULL);
|
||||||
|
if (_temp_xwindow == (Window)NULL) {
|
||||||
|
glxdisplay_cat.error()
|
||||||
|
<< "Could not create temporary window for context\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glXMakeCurrent(_display, _temp_xwindow, _context);
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsStateGuardian::destroy_temp_xwindow
|
||||||
|
// Access: Private
|
||||||
|
// Description: Destroys the temporary unmapped window created by
|
||||||
|
// init_temp_context().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void glxGraphicsStateGuardian::
|
||||||
|
destroy_temp_xwindow() {
|
||||||
|
if (_temp_xwindow != (Window)NULL) {
|
||||||
|
XDestroyWindow(_display, _temp_xwindow);
|
||||||
|
_temp_xwindow = (Window)NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -20,6 +20,9 @@
|
|||||||
#include "glgsg.h"
|
#include "glgsg.h"
|
||||||
#include "glxGraphicsPipe.h"
|
#include "glxGraphicsPipe.h"
|
||||||
|
|
||||||
|
// Don't pick up the system glxext.h; use our own, which is better.
|
||||||
|
#define __glxext_h_
|
||||||
|
|
||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
|
|
||||||
#if defined(GLX_VERSION_1_4)
|
#if defined(GLX_VERSION_1_4)
|
||||||
@ -39,7 +42,7 @@ extern "C" void (*glXGetProcAddressARB(const GLubyte *procName))( void );
|
|||||||
|
|
||||||
// This must be included after we have included glgsg.h (which
|
// This must be included after we have included glgsg.h (which
|
||||||
// includes gl.h).
|
// includes gl.h).
|
||||||
#include "glxext.h"
|
#include "panda_glxext.h"
|
||||||
|
|
||||||
// drose: the version of GL/glx.h that ships with Fedora Core 2 seems
|
// drose: the version of GL/glx.h that ships with Fedora Core 2 seems
|
||||||
// to define GLX_VERSION_1_4, but for some reason does not define
|
// to define GLX_VERSION_1_4, but for some reason does not define
|
||||||
@ -69,17 +72,11 @@ typedef int (* PFNGLXSWAPINTERVALSGIPROC) (int interval);
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class glxGraphicsStateGuardian : public GLGraphicsStateGuardian {
|
class glxGraphicsStateGuardian : public GLGraphicsStateGuardian {
|
||||||
public:
|
public:
|
||||||
#ifdef HAVE_GLXFBCONFIG
|
|
||||||
typedef GLXFBConfig fbconfig;
|
|
||||||
#else
|
|
||||||
typedef int fbconfig;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
INLINE const FrameBufferProperties &get_fb_properties() const;
|
INLINE const FrameBufferProperties &get_fb_properties() const;
|
||||||
void get_properties(FrameBufferProperties &properties, XVisualInfo *visual);
|
void get_properties(FrameBufferProperties &properties, XVisualInfo *visual);
|
||||||
void get_properties_advanced(FrameBufferProperties &properties,
|
void get_properties_advanced(FrameBufferProperties &properties,
|
||||||
bool &pbuffer_supported, bool &pixmap_supported,
|
bool &context_has_pbuffer, bool &pixmap_supported,
|
||||||
bool &slow, fbconfig config);
|
bool &slow, GLXFBConfig config);
|
||||||
void choose_pixel_format(const FrameBufferProperties &properties,
|
void choose_pixel_format(const FrameBufferProperties &properties,
|
||||||
Display *_display,
|
Display *_display,
|
||||||
int _screen,
|
int _screen,
|
||||||
@ -100,13 +97,30 @@ public:
|
|||||||
int _screen;
|
int _screen;
|
||||||
XVisualInfo *_visual;
|
XVisualInfo *_visual;
|
||||||
XVisualInfo *_visuals;
|
XVisualInfo *_visuals;
|
||||||
fbconfig _fbconfig;
|
|
||||||
|
GLXFBConfig _fbconfig;
|
||||||
FrameBufferProperties _fbprops;
|
FrameBufferProperties _fbprops;
|
||||||
|
bool _context_has_pbuffer; // true if the particular fbconfig supports pbuffers
|
||||||
|
bool _context_has_pixmap;
|
||||||
|
bool _slow;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool _supports_swap_control;
|
bool _supports_swap_control;
|
||||||
PFNGLXSWAPINTERVALSGIPROC _glXSwapIntervalSGI;
|
PFNGLXSWAPINTERVALSGIPROC _glXSwapIntervalSGI;
|
||||||
|
|
||||||
|
bool _supports_fbconfig;
|
||||||
|
PFNGLXCHOOSEFBCONFIGPROC _glXChooseFBConfig;
|
||||||
|
PFNGLXCREATENEWCONTEXTPROC _glXCreateNewContext;
|
||||||
|
PFNGLXGETVISUALFROMFBCONFIGPROC _glXGetVisualFromFBConfig;
|
||||||
|
PFNGLXGETFBCONFIGATTRIBPROC _glXGetFBConfigAttrib;
|
||||||
|
PFNGLXCREATEPIXMAPPROC _glXCreatePixmap;
|
||||||
|
|
||||||
|
bool _supports_pbuffer; // true if the interface is available.
|
||||||
|
bool _uses_sgix_pbuffer;
|
||||||
|
PFNGLXCREATEPBUFFERPROC _glXCreatePbuffer;
|
||||||
|
PFNGLXCREATEGLXPBUFFERSGIXPROC _glXCreateGLXPbufferSGIX;
|
||||||
|
PFNGLXDESTROYPBUFFERPROC _glXDestroyPbuffer;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void gl_flush() const;
|
virtual void gl_flush() const;
|
||||||
virtual GLenum gl_get_error() const;
|
virtual GLenum gl_get_error() const;
|
||||||
@ -119,13 +133,16 @@ private:
|
|||||||
void *get_system_func(const char *name);
|
void *get_system_func(const char *name);
|
||||||
void show_glx_client_string(const string &name, int id);
|
void show_glx_client_string(const string &name, int id);
|
||||||
void show_glx_server_string(const string &name, int id);
|
void show_glx_server_string(const string &name, int id);
|
||||||
|
void choose_visual(const FrameBufferProperties &properties);
|
||||||
|
void init_temp_context();
|
||||||
|
void destroy_temp_xwindow();
|
||||||
|
|
||||||
int _glx_version_major, _glx_version_minor;
|
int _glx_version_major, _glx_version_minor;
|
||||||
|
|
||||||
void *_libgl_handle;
|
void *_libgl_handle;
|
||||||
bool _checked_get_proc_address;
|
bool _checked_get_proc_address;
|
||||||
PFNGLXGETPROCADDRESSPROC _glXGetProcAddress;
|
PFNGLXGETPROCADDRESSPROC _glXGetProcAddress;
|
||||||
|
Window _temp_xwindow;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
|
@ -188,15 +188,11 @@ open_window() {
|
|||||||
}
|
}
|
||||||
Visual *visual = _visual_info->visual;
|
Visual *visual = _visual_info->visual;
|
||||||
|
|
||||||
#ifdef HAVE_GLXFBCONFIG
|
|
||||||
if (glxgsg->_fbconfig != None) {
|
if (glxgsg->_fbconfig != None) {
|
||||||
setup_colormap(glxgsg->_fbconfig);
|
setup_colormap(glxgsg->_fbconfig);
|
||||||
} else {
|
} else {
|
||||||
setup_colormap(_visual_info);
|
setup_colormap(_visual_info);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
setup_colormap(_visual_info);
|
|
||||||
#endif // HAVE_GLXFBCONFIG
|
|
||||||
|
|
||||||
if (!x11GraphicsWindow::open_window()) {
|
if (!x11GraphicsWindow::open_window()) {
|
||||||
return false;
|
return false;
|
||||||
@ -218,7 +214,6 @@ open_window() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_GLXFBCONFIG
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: glxGraphicsWindow::setup_colormap
|
// Function: glxGraphicsWindow::setup_colormap
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -227,7 +222,11 @@ open_window() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void glxGraphicsWindow::
|
void glxGraphicsWindow::
|
||||||
setup_colormap(GLXFBConfig fbconfig) {
|
setup_colormap(GLXFBConfig fbconfig) {
|
||||||
XVisualInfo *visual_info = glXGetVisualFromFBConfig(_display, fbconfig);
|
glxGraphicsStateGuardian *glxgsg;
|
||||||
|
DCAST_INTO_V(glxgsg, _gsg);
|
||||||
|
nassertv(glxgsg->_supports_fbconfig);
|
||||||
|
|
||||||
|
XVisualInfo *visual_info = glxgsg->_glXGetVisualFromFBConfig(_display, fbconfig);
|
||||||
if (visual_info == NULL) {
|
if (visual_info == NULL) {
|
||||||
// No X visual; no need to set up a colormap.
|
// No X visual; no need to set up a colormap.
|
||||||
return;
|
return;
|
||||||
@ -244,7 +243,7 @@ setup_colormap(GLXFBConfig fbconfig) {
|
|||||||
|
|
||||||
switch (visual_class) {
|
switch (visual_class) {
|
||||||
case PseudoColor:
|
case PseudoColor:
|
||||||
rc = glXGetFBConfigAttrib(_display, fbconfig, GLX_RGBA, &is_rgb);
|
rc = glxgsg->_glXGetFBConfigAttrib(_display, fbconfig, GLX_RGBA, &is_rgb);
|
||||||
if (rc == 0 && is_rgb) {
|
if (rc == 0 && is_rgb) {
|
||||||
glxdisplay_cat.warning()
|
glxdisplay_cat.warning()
|
||||||
<< "mesa pseudocolor not supported.\n";
|
<< "mesa pseudocolor not supported.\n";
|
||||||
@ -274,7 +273,6 @@ setup_colormap(GLXFBConfig fbconfig) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // HAVE_GLXFBCONFIG
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: glxGraphicsWindow::setup_colormap
|
// Function: glxGraphicsWindow::setup_colormap
|
||||||
|
@ -46,10 +46,7 @@ protected:
|
|||||||
virtual bool open_window();
|
virtual bool open_window();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#ifdef HAVE_GLXFBCONFIG
|
|
||||||
virtual void setup_colormap(GLXFBConfig fbconfig);
|
virtual void setup_colormap(GLXFBConfig fbconfig);
|
||||||
#endif // HAVE_GLXFBCONFIG
|
|
||||||
virtual void setup_colormap(XVisualInfo *visual);
|
virtual void setup_colormap(XVisualInfo *visual);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef __glxext_h_
|
#ifndef panda__glxext_h_
|
||||||
#define __glxext_h_
|
#define panda__glxext_h_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
Loading…
x
Reference in New Issue
Block a user