// working with GL attributes
// ----------------------------------------------------------------------------
+/* static */
+bool wxGLCanvasBase::IsExtensionSupported(const char *extension)
+{
+ Display * const dpy = wxGetX11Display();
+
+ return IsExtensionInList(glXQueryExtensionsString(dpy, DefaultScreen(dpy)),
+ extension);
+}
+
+
+/* static */
+bool wxGLCanvasX11::IsGLXMultiSampleAvailable()
+{
+ static int s_isMultiSampleAvailable = -1;
+ if ( s_isMultiSampleAvailable == -1 )
+ s_isMultiSampleAvailable = IsExtensionSupported("GLX_ARB_multisample");
+
+ return s_isMultiSampleAvailable != 0;
+}
+
bool
wxGLCanvasX11::ConvertWXAttrsToGL(const int *wxattrs, int *glattrs, size_t n)
{
wxCHECK_MSG( n >= 16, false, _T("GL attributes buffer too small") );
+ /*
+ Different versions of GLX API use rather different attributes lists, see
+ the following URLs:
+
+ - <= 1.2: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseVisual.xml
+ - >= 1.3: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseFBConfig.xml
+
+ Notice in particular that
+ - GLX_RGBA is boolean attribute in the old version of the API but a
+ value of GLX_RENDER_TYPE in the new one
+ - Boolean attributes such as GLX_DOUBLEBUFFER don't take values in the
+ old version but must be followed by True or False in the new one.
+ */
+
if ( !wxattrs )
{
- if ( GetGLXVersion() >= 13 )
- {
- // leave GLX >= 1.3 choose the default attributes
- glattrs[0] = None;
- }
- else // GLX < 1.3
+ size_t i = 0;
+
+ // use double-buffered true colour by default
+ glattrs[i++] = GLX_DOUBLEBUFFER;
+
+ if ( GetGLXVersion() < 13 )
{
// default settings if attriblist = 0
- size_t i = 0;
glattrs[i++] = GLX_RGBA;
- glattrs[i++] = GLX_DOUBLEBUFFER;
glattrs[i++] = GLX_DEPTH_SIZE; glattrs[i++] = 1;
glattrs[i++] = GLX_RED_SIZE; glattrs[i++] = 1;
glattrs[i++] = GLX_GREEN_SIZE; glattrs[i++] = 1;
glattrs[i++] = GLX_BLUE_SIZE; glattrs[i++] = 1;
glattrs[i++] = GLX_ALPHA_SIZE; glattrs[i++] = 0;
- glattrs[i++] = None;
-
- wxASSERT_MSG( i < n, _T("GL attributes buffer too small") );
}
+ else // recent GLX can choose the defaults on its own just fine
+ {
+ // we just need to have a value after GLX_DOUBLEBUFFER
+ glattrs[i++] = True;
+ }
+
+ glattrs[i] = None;
+
+ wxASSERT_MSG( i < n, _T("GL attributes buffer too small") );
}
else // have non-default attributes
{
// check if we have any space left, knowing that we may insert 2
// more elements during this loop iteration and we always need to
// terminate the list with None (hence -3)
- if ( p >= n - 2 )
+ if ( p > n - 3 )
return false;
+ // indicates whether we have a boolean attribute
+ bool isBoolAttr = false;
+
switch ( wxattrs[arg++] )
{
- case WX_GL_RGBA:
- // for GLX >= 1.3, GLX_RGBA is useless and apparently
- // harmful for some implementations
- //
- // FIXME: is this true?
- if ( GetGLXVersion() <= 12 )
- {
- glattrs[p++] = GLX_RGBA;
- }
-
- // use "continue" to skip the assignment of the attribute
- // value at the end of the loop
- continue;
-
case WX_GL_BUFFER_SIZE:
glattrs[p++] = GLX_BUFFER_SIZE;
break;
glattrs[p++] = GLX_LEVEL;
break;
- // the following boolean attributes don't have values in wx
- // API (they're turned on if specified) but do have them in
- // OpenGL, so do put them into glattrs and also skip the
- // copy of wx value after switch by using "continue"
- // instead of "break"
+ case WX_GL_RGBA:
+ if ( GetGLXVersion() >= 13 )
+ {
+ // this is the default GLX_RENDER_TYPE anyhow
+ continue;
+ }
+
+ glattrs[p++] = GLX_RGBA;
+ isBoolAttr = true;
+ break;
+
case WX_GL_DOUBLEBUFFER:
glattrs[p++] = GLX_DOUBLEBUFFER;
- glattrs[p++] = True;
- continue;
+ isBoolAttr = true;
+ break;
case WX_GL_STEREO:
glattrs[p++] = GLX_STEREO;
- glattrs[p++] = True;
- continue;
-
+ isBoolAttr = true;
+ break;
case WX_GL_AUX_BUFFERS:
glattrs[p++] = GLX_AUX_BUFFERS;
glattrs[p++] = GLX_ACCUM_ALPHA_SIZE;
break;
+ case WX_GL_SAMPLE_BUFFERS:
+ if ( !IsGLXMultiSampleAvailable() )
+ {
+ // if it was specified just to disable it, no problem
+ if ( !wxattrs[arg++] )
+ continue;
+
+ // otherwise indicate that it's not supported
+ return false;
+ }
+
+ glattrs[p++] = GLX_SAMPLE_BUFFERS_ARB;
+ break;
+
+ case WX_GL_SAMPLES:
+ if ( !IsGLXMultiSampleAvailable() )
+ {
+ if ( !wxattrs[arg++] )
+ continue;
+
+ return false;
+ }
+
+ glattrs[p++] = GLX_SAMPLES_ARB;
+ break;
+
default:
wxLogDebug(_T("Unsupported OpenGL attribute %d"),
wxattrs[arg - 1]);
continue;
}
- // copy attribute value as is
- glattrs[p++] = wxattrs[arg++];
+ if ( isBoolAttr )
+ {
+ // as explained above, for pre 1.3 API the attribute just needs
+ // to be present so we only add its value when using the new API
+ if ( GetGLXVersion() >= 13 )
+ glattrs[p++] = True;
+ }
+ else // attribute with real (non-boolean) value
+ {
+ // copy attribute value as is
+ glattrs[p++] = wxattrs[arg++];
+ }
}
glattrs[p] = None;