mirror of
https://github.com/brl/mutter.git
synced 2025-03-03 11:58:09 +00:00
[x11] Abstract XVisualInfo creation
The XVisualInfo for GL is created when a stage is being realized. When embedding Clutter inside another toolkit we might not want to realize a stage to extract the XVisualInfo, then set the stage window using a foreign X Window -- which will cause a re-realization. Instead, we should abstract as much as possible into the X11 backend. Unfortunately, the XVisualInfo for GL is requested using GLX API; for this reason we have to create a ClutterBackendX11 method that we override inside the ClutterBackendGLX implementation. This also allows us to move a little bit of complexity from out of the stage realization, which is currently a very delicate and hard to debug section.
This commit is contained in:
parent
dd95939d26
commit
e59a19bd03
@ -434,8 +434,11 @@ clutter_backend_glx_redraw (ClutterBackend *backend,
|
||||
ClutterStageWindow *impl;
|
||||
|
||||
impl = _clutter_stage_get_window (stage);
|
||||
if (!impl)
|
||||
return;
|
||||
if (G_UNLIKELY (impl == NULL))
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "Stage [%p] has no implementation", stage);
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert (CLUTTER_IS_STAGE_GLX (impl));
|
||||
|
||||
@ -445,18 +448,23 @@ clutter_backend_glx_redraw (ClutterBackend *backend,
|
||||
/* this will cause the stage implementation to be painted */
|
||||
clutter_actor_paint (CLUTTER_ACTOR (stage));
|
||||
|
||||
/* Why this paint is done in backend as likely GL windowing system
|
||||
* specific calls, like swapping buffers.
|
||||
*/
|
||||
if (stage_x11->xwin)
|
||||
if (stage_x11->xwin != None)
|
||||
{
|
||||
/* wait for the next vblank */
|
||||
CLUTTER_NOTE (BACKEND, "Waiting for vblank");
|
||||
clutter_backend_glx_wait_for_vblank (CLUTTER_BACKEND_GLX (backend));
|
||||
|
||||
/* push on the screen */
|
||||
CLUTTER_NOTE (BACKEND, "glXSwapBuffers (display: %p, window: 0x%lx)",
|
||||
stage_x11->xdpy,
|
||||
(unsigned long) stage_x11->xwin);
|
||||
glXSwapBuffers (stage_x11->xdpy, stage_x11->xwin);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* offscreen */
|
||||
glXWaitGL ();
|
||||
|
||||
CLUTTER_GLERR ();
|
||||
}
|
||||
}
|
||||
@ -494,11 +502,56 @@ clutter_backend_glx_create_stage (ClutterBackend *backend,
|
||||
return stage;
|
||||
}
|
||||
|
||||
static XVisualInfo *
|
||||
clutter_backend_glx_get_visual_info (ClutterBackendX11 *backend_x11,
|
||||
gboolean for_offscreen)
|
||||
{
|
||||
XVisualInfo *xvisinfo;
|
||||
int onscreen_gl_attributes[] = {
|
||||
GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_STENCIL_SIZE, 1,
|
||||
0
|
||||
};
|
||||
int offscreen_gl_attributes[] = {
|
||||
GLX_RGBA,
|
||||
GLX_USE_GL,
|
||||
GLX_DEPTH_SIZE, 0,
|
||||
GLX_ALPHA_SIZE, 0,
|
||||
GLX_STENCIL_SIZE, 1,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
0
|
||||
};
|
||||
|
||||
if (backend_x11->xdpy == None || backend_x11->xscreen == None)
|
||||
return NULL;
|
||||
|
||||
CLUTTER_NOTE (BACKEND,
|
||||
"Retrieving GL visual (for %s use), dpy: %p, xscreen; %p (%d)",
|
||||
for_offscreen ? "offscreen" : "onscreen",
|
||||
backend_x11->xdpy,
|
||||
backend_x11->xscreen,
|
||||
backend_x11->xscreen_num);
|
||||
|
||||
xvisinfo = glXChooseVisual (backend_x11->xdpy,
|
||||
backend_x11->xscreen_num,
|
||||
for_offscreen ? offscreen_gl_attributes
|
||||
: onscreen_gl_attributes);
|
||||
|
||||
return xvisinfo;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_glx_class_init (ClutterBackendGLXClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass);
|
||||
ClutterBackendX11Class *backendx11_class = CLUTTER_BACKEND_X11_CLASS (klass);
|
||||
|
||||
gobject_class->constructor = clutter_backend_glx_constructor;
|
||||
gobject_class->dispose = clutter_backend_glx_dispose;
|
||||
@ -511,6 +564,8 @@ clutter_backend_glx_class_init (ClutterBackendGLXClass *klass)
|
||||
backend_class->get_features = clutter_backend_glx_get_features;
|
||||
backend_class->redraw = clutter_backend_glx_redraw;
|
||||
backend_class->ensure_context = clutter_backend_glx_ensure_context;
|
||||
|
||||
backendx11_class->get_visual_info = clutter_backend_glx_get_visual_info;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -124,26 +124,14 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
||||
|
||||
if (G_LIKELY (!is_offscreen))
|
||||
{
|
||||
int gl_attributes[] =
|
||||
{
|
||||
GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_STENCIL_SIZE, 1,
|
||||
0
|
||||
};
|
||||
|
||||
if (stage_x11->xvisinfo != None)
|
||||
{
|
||||
XFree (stage_x11->xvisinfo);
|
||||
stage_x11->xvisinfo = None;
|
||||
}
|
||||
|
||||
stage_x11->xvisinfo = glXChooseVisual (stage_x11->xdpy,
|
||||
stage_x11->xscreen,
|
||||
gl_attributes);
|
||||
stage_x11->xvisinfo =
|
||||
clutter_backend_x11_get_visual_info (backend_x11, FALSE);
|
||||
if (stage_x11->xvisinfo == None)
|
||||
{
|
||||
g_critical ("Unable to find suitable GL visual.");
|
||||
@ -232,27 +220,15 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
||||
}
|
||||
else
|
||||
{
|
||||
int gl_attributes[] = {
|
||||
GLX_DEPTH_SIZE, 0,
|
||||
GLX_ALPHA_SIZE, 0,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_USE_GL,
|
||||
GLX_RGBA,
|
||||
0
|
||||
};
|
||||
if (stage_x11->xvisinfo != None)
|
||||
{
|
||||
XFree (stage_x11->xvisinfo);
|
||||
stage_x11->xvisinfo = None;
|
||||
}
|
||||
|
||||
if (stage_x11->xvisinfo)
|
||||
XFree (stage_x11->xvisinfo);
|
||||
|
||||
stage_x11->xvisinfo = NULL;
|
||||
|
||||
CLUTTER_NOTE (GL, "glXChooseVisual");
|
||||
stage_x11->xvisinfo = glXChooseVisual (stage_x11->xdpy,
|
||||
stage_x11->xscreen,
|
||||
gl_attributes);
|
||||
if (!stage_x11->xvisinfo)
|
||||
stage_x11->xvisinfo =
|
||||
clutter_backend_x11_get_visual_info (backend_x11, TRUE);
|
||||
if (stage_x11->xvisinfo == None)
|
||||
{
|
||||
g_critical ("Unable to find suitable GL visual.");
|
||||
goto fail;
|
||||
|
@ -969,3 +969,17 @@ clutter_x11_has_composite_extension (void)
|
||||
return have_composite;
|
||||
}
|
||||
|
||||
XVisualInfo *
|
||||
clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11,
|
||||
gboolean for_offscreen)
|
||||
{
|
||||
ClutterBackendX11Class *klass;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_BACKEND_X11 (backend_x11), NULL);
|
||||
|
||||
klass = CLUTTER_BACKEND_X11_GET_CLASS (backend_x11);
|
||||
if (klass->get_visual_info)
|
||||
return klass->get_visual_info (backend_x11, for_offscreen);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -90,6 +90,9 @@ struct _ClutterBackendX11
|
||||
struct _ClutterBackendX11Class
|
||||
{
|
||||
ClutterBackendClass parent_class;
|
||||
|
||||
XVisualInfo *(* get_visual_info) (ClutterBackendX11 *backend,
|
||||
gboolean for_offscreen);
|
||||
};
|
||||
|
||||
void _clutter_backend_x11_events_init (ClutterBackend *backend);
|
||||
@ -120,6 +123,10 @@ clutter_backend_x11_add_options (ClutterBackend *backend,
|
||||
ClutterFeatureFlags
|
||||
clutter_backend_x11_get_features (ClutterBackend *backend);
|
||||
|
||||
XVisualInfo *
|
||||
clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11,
|
||||
gboolean for_offscreen);
|
||||
|
||||
#ifdef USE_XINPUT
|
||||
void
|
||||
_clutter_x11_register_xinput (void);
|
||||
|
@ -656,13 +656,27 @@ XVisualInfo *
|
||||
clutter_x11_get_stage_visual (ClutterStage *stage)
|
||||
{
|
||||
ClutterStageWindow *impl;
|
||||
ClutterStageX11 *stage_x11;
|
||||
gboolean is_offscreen = FALSE;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
||||
|
||||
g_object_get (G_OBJECT (stage), "offscreen", &is_offscreen, NULL);
|
||||
|
||||
impl = _clutter_stage_get_window (stage);
|
||||
g_assert (CLUTTER_IS_STAGE_X11 (impl));
|
||||
|
||||
return CLUTTER_STAGE_X11 (impl)->xvisinfo;
|
||||
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
||||
|
||||
if (stage_x11->xvisinfo == NULL)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11 = stage_x11->backend;
|
||||
|
||||
stage_x11->xvisinfo =
|
||||
clutter_backend_x11_get_visual_info (backend_x11, is_offscreen);
|
||||
}
|
||||
|
||||
return stage_x11->xvisinfo;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
Loading…
x
Reference in New Issue
Block a user