glx: Always request an ARGB visual

When requesting the GLXFBConfig for creating the GLX context, we should
always request one that links to an ARGB visual instead of a plain RGB
one.

By using an ARGB visual we allow the ClutterStage:use-alpha property to
work as intended when running Clutter under a compositing manager.

The default behaviour of requesting an ARGB visual can be disabled by
using the:

  CLUTTER_DISABLE_ARGB_VISUAL

Environment variable.
This commit is contained in:
Emmanuele Bassi 2009-12-01 16:18:39 +00:00
parent 2f7ff4d3e3
commit e6ca2d891a
6 changed files with 125 additions and 43 deletions

View File

@ -354,6 +354,20 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
return flags;
}
enum
{
DRAWABLE_TYPE = 0,
RENDER_TYPE = 2,
DOUBLE_BUFFER = 4,
RED_SIZE = 6,
GREEN_SIZE = 8,
BLUE_SIZE = 10,
ALPHA_SIZE = 12,
DEPTH_SIZE = 14,
STENCIL_SIZE = 16,
TRANSPARENT_TYPE = 18
};
/* It seems the GLX spec never defined an invalid GLXFBConfig that
* we could overload as an indication of error, so we have to return
* an explicit boolean status. */
@ -362,7 +376,11 @@ _clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_glx,
GLXFBConfig *config)
{
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend_glx);
int attributes[] = {
GLXFBConfig *configs = NULL;
gboolean retval = FALSE;
gboolean use_argb = clutter_x11_has_argb_visuals ();
int n_configs, i;
static int attributes[] = {
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DOUBLEBUFFER, GL_TRUE,
@ -372,20 +390,29 @@ _clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_glx,
GLX_ALPHA_SIZE, 1,
GLX_DEPTH_SIZE, 1,
GLX_STENCIL_SIZE, 1,
GLX_TRANSPARENT_TYPE, GLX_NONE,
None
};
GLXFBConfig *configs = NULL;
int n_configs;
if (backend_x11->xdpy == None || backend_x11->xscreen == None)
return FALSE;
if (backend_glx->found_fbconfig)
if (backend_glx->found_fbconfig > 0)
{
*config = backend_glx->fbconfig;
if (use_argb && backend_glx->found_fbconfig == 2)
*config = backend_glx->fbconfig_rgba;
else
*config = backend_glx->fbconfig_rgb;
return TRUE;
}
if (use_argb)
{
attributes[ALPHA_SIZE] = 8;
attributes[TRANSPARENT_TYPE] = GLX_TRANSPARENT_RGB;
}
CLUTTER_NOTE (BACKEND,
"Retrieving GL fbconfig, dpy: %p, xscreen; %p (%d)",
backend_x11->xdpy,
@ -396,16 +423,64 @@ _clutter_backend_glx_get_fbconfig (ClutterBackendGLX *backend_glx,
backend_x11->xscreen_num,
attributes,
&n_configs);
if (configs)
if (!configs)
return FALSE;
if (!use_argb)
{
*config = configs[0];
backend_glx->found_fbconfig = TRUE;
backend_glx->fbconfig = configs[0];
XFree (configs);
return TRUE;
backend_glx->found_fbconfig = 1;
backend_glx->fbconfig_rgb = configs[0];
retval = TRUE;
goto out;
}
else
return FALSE;
for (i = 0; i < n_configs; i++)
{
XVisualInfo *vinfo;
vinfo = glXGetVisualFromFBConfig (backend_x11->xdpy, configs[i]);
if (vinfo == None)
continue;
if (vinfo->depth == 32 &&
(vinfo->red_mask == 0xff0000 &&
vinfo->green_mask == 0x00ff00 &&
vinfo->blue_mask == 0x0000ff))
{
CLUTTER_NOTE (BACKEND, "Found GLX visual ARGB [index:%d]", i);
*config = configs[i];
backend_glx->found_fbconfig = 2;
backend_glx->fbconfig_rgba = configs[i];
retval = TRUE;
goto out;
}
}
/* XXX - we might add a warning here */
if (use_argb && !backend_glx->found_fbconfig != 2)
{
CLUTTER_NOTE (BACKEND, "ARGB visual requested, but none found");
*config = configs[0];
backend_glx->found_fbconfig = 1;
backend_glx->fbconfig_rgb = configs[0];
retval = TRUE;
}
out:
XFree (configs);
return retval;
}
static XVisualInfo *
@ -436,12 +511,14 @@ clutter_backend_glx_create_context (ClutterBackend *backend,
{
g_set_error (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND,
"Unable to find suitable fbconfig for GL context");
"Unable to find a suitable GLXFBConfig for "
"the GLX context");
return FALSE;
}
CLUTTER_NOTE (GL, "Creating GL Context (display: %p)",
CLUTTER_NOTE (GL, "Creating GLX Context (display: %p)",
backend_x11->xdpy);
backend_glx->gl_context =
glXCreateNewContext (backend_x11->xdpy,
config,
@ -460,7 +537,8 @@ clutter_backend_glx_create_context (ClutterBackend *backend,
is_direct = glXIsDirect (backend_x11->xdpy,
backend_glx->gl_context);
CLUTTER_NOTE (GL, "Setting %s context",
CLUTTER_NOTE (GL,
"Setting %s context",
is_direct ? "direct" : "indirect");
_cogl_set_indirect_context (!is_direct);
}

View File

@ -63,8 +63,9 @@ struct _ClutterBackendGLX
ClutterBackendX11 parent_instance;
/* Single context for all wins */
gboolean found_fbconfig;
GLXFBConfig fbconfig;
gint found_fbconfig;
GLXFBConfig fbconfig_rgb;
GLXFBConfig fbconfig_rgba;
GLXContext gl_context;
/* Vblank stuff */

View File

@ -43,9 +43,4 @@
#include <clutter/clutter.h>
#include <clutter/glx/clutter-glx-texture-pixmap.h>
G_BEGIN_DECLS
G_END_DECLS
#endif /* __CLUTTER_GLX_H__ */

View File

@ -105,18 +105,11 @@ clutter_stage_glx_realize (ClutterStageWindow *stage_window)
{
XSetWindowAttributes xattr;
unsigned long mask;
GLXFBConfig config;
XVisualInfo *xvisinfo;
CLUTTER_NOTE (MISC, "Creating stage X window");
if (!_clutter_backend_glx_get_fbconfig (backend_glx, &config))
{
g_critical ("Unable to find suitable FBConfig to realize stage.");
return FALSE;
}
xvisinfo = glXGetVisualFromFBConfig (backend_x11->xdpy, config);
xvisinfo = clutter_backend_x11_get_visual_info (backend_x11);
if (xvisinfo == NULL)
{
g_critical ("Unable to find suitable GL visual.");
@ -145,9 +138,9 @@ clutter_stage_glx_realize (ClutterStageWindow *stage_window)
XFree (xvisinfo);
}
if (clutter_x11_has_event_retrieval())
if (clutter_x11_has_event_retrieval ())
{
if (clutter_x11_has_xinput())
if (clutter_x11_has_xinput ())
{
XSelectInput (backend_x11->xdpy, stage_x11->xwin,
StructureNotifyMask |

View File

@ -97,6 +97,7 @@ static ClutterBackendX11 *backend_singleton = NULL;
/* various flags corresponding to pre init setup calls */
static gboolean _no_xevent_retrieval = FALSE;
static gboolean clutter_enable_xinput = FALSE;
static gboolean clutter_enable_argb = TRUE;
static Display *_foreign_dpy = NULL;
/* options */
@ -124,6 +125,13 @@ clutter_backend_x11_pre_parse (ClutterBackend *backend,
env_string = NULL;
}
env_string = g_getenv ("CLUTTER_DISABLE_ARGB_VISUAL");
if (env_string)
{
clutter_enable_argb = FALSE;
env_string = NULL;
}
return TRUE;
}
@ -980,6 +988,12 @@ clutter_x11_has_composite_extension (void)
return have_composite;
}
gboolean
clutter_x11_has_argb_visuals (void)
{
return clutter_enable_argb;
}
XVisualInfo *
clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11)
{
@ -993,4 +1007,3 @@ clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11)
return NULL;
}

View File

@ -124,6 +124,8 @@ gboolean clutter_x11_has_xinput (void);
gboolean clutter_x11_has_composite_extension (void);
gboolean clutter_x11_has_argb_visuals (void);
Time clutter_x11_get_current_event_time (void);
G_END_DECLS