Tentative fix for multi-stage support on GLX

The fix for bug 1138 broke multi-stage support on GLX, causing
X11 to segfault with the following stack trace:

Backtrace:
0: /usr/X11R6/bin/X(xf86SigHandler+0x7e) [0x80c91fe]
1: [0xb7eea400]
2: /usr/lib/xorg/modules/extensions//libglx.so [0xb7ae880c]
3: /usr/lib/xorg/modules/extensions//libglx.so [0xb7aec0d6]
4: /usr/X11R6/bin/X [0x8154c24]
5: /usr/X11R6/bin/X(Dispatch+0x314) [0x808de54]
6: /usr/X11R6/bin/X(main+0x4b5) [0x8074795]
7: /lib/i686/cmov/libc.so.6(__libc_start_main+0xe5) [0xb7c75775]
8: /usr/X11R6/bin/X(FontFileCompleteXLFD+0x21d) [0x8073a81]

which I can only track down to clutter_backend_glx_ensure_current()
being passed a NULL stage -- something that happens when a stage
is not correct realized. That should lead to a glXMakeCurrent(None)
and not to a segmentation fault, though.
This commit is contained in:
Emmanuele Bassi 2009-05-08 17:17:48 +01:00
parent 91126558d3
commit 5bcde25cbb
3 changed files with 29 additions and 10 deletions

View File

@ -304,8 +304,8 @@ void
_clutter_backend_ensure_context (ClutterBackend *backend,
ClutterStage *stage)
{
ClutterBackendClass *klass;
static ClutterStage *current_context_stage = NULL;
ClutterBackendClass *klass;
g_return_if_fail (CLUTTER_IS_BACKEND (backend));
g_return_if_fail (CLUTTER_IS_STAGE (stage));
@ -314,8 +314,16 @@ _clutter_backend_ensure_context (ClutterBackend *backend,
{
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
{
CLUTTER_NOTE (MULTISTAGE, "Stage is not realized, unsetting");
stage = NULL;
CLUTTER_NOTE (MULTISTAGE,
"Stage [%p] is not realized, realizing",
stage);
/* if we are asked to ensure a particular stage we need
* to make sure that is has been realized; calling
* realized() twice in a row is cheap, since the method
* will check first
*/
clutter_actor_realize (CLUTTER_ACTOR (stage));
}
else
CLUTTER_NOTE (MULTISTAGE, "Setting the new stage [%p]", stage);

View File

@ -275,8 +275,9 @@ clutter_stage_realize (ClutterActor *self)
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
/* Make sure the viewport and projection matrix are valid for the
first paint (which will likely occur before the ConfigureNotify
is received) */
* first paint (which will likely occur before the ConfigureNotify
* is received)
*/
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_SYNC_MATRICES);
g_assert (priv->impl != NULL);
@ -286,7 +287,10 @@ clutter_stage_realize (ClutterActor *self)
* realization sequence was successful
*/
if (CLUTTER_ACTOR_IS_REALIZED (priv->impl))
{
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
clutter_stage_ensure_current (CLUTTER_STAGE (self));
}
else
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
}
@ -582,8 +586,9 @@ clutter_stage_dispose (GObject *object)
if (priv->impl)
{
CLUTTER_NOTE (MISC, "Disposing of the stage implementation");
g_object_unref (priv->impl);
CLUTTER_NOTE (BACKEND, "Disposing of the stage implementation");
clutter_actor_hide (priv->impl);
clutter_actor_destroy (priv->impl);
priv->impl = NULL;
}
@ -847,6 +852,9 @@ clutter_stage_init (ClutterStage *self)
else
g_object_ref_sink (priv->impl);
/* make sure that the implementation is considered a top level */
CLUTTER_SET_PRIVATE_FLAGS (priv->impl, CLUTTER_ACTOR_IS_TOPLEVEL);
priv->is_offscreen = FALSE;
priv->is_fullscreen = FALSE;
priv->is_user_resizable = FALSE;

View File

@ -483,10 +483,13 @@ clutter_backend_glx_create_stage (ClutterBackend *backend,
stage_x11->backend = backend_x11;
stage_x11->wrapper = wrapper;
CLUTTER_NOTE (BACKEND, "GLX stage created (display:%p, screen:%d, root:%u)",
CLUTTER_NOTE (BACKEND,
"GLX stage created[%p] (dpy:%p, screen:%d, root:%u, wrap:%p)",
stage,
stage_x11->xdpy,
stage_x11->xscreen,
(unsigned int) stage_x11->xwin_root);
(unsigned int) stage_x11->xwin_root,
wrapper);
return stage;
}