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:
parent
91126558d3
commit
5bcde25cbb
@ -304,8 +304,8 @@ void
|
|||||||
_clutter_backend_ensure_context (ClutterBackend *backend,
|
_clutter_backend_ensure_context (ClutterBackend *backend,
|
||||||
ClutterStage *stage)
|
ClutterStage *stage)
|
||||||
{
|
{
|
||||||
ClutterBackendClass *klass;
|
|
||||||
static ClutterStage *current_context_stage = NULL;
|
static ClutterStage *current_context_stage = NULL;
|
||||||
|
ClutterBackendClass *klass;
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_BACKEND (backend));
|
g_return_if_fail (CLUTTER_IS_BACKEND (backend));
|
||||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||||
@ -314,8 +314,16 @@ _clutter_backend_ensure_context (ClutterBackend *backend,
|
|||||||
{
|
{
|
||||||
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
|
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
|
||||||
{
|
{
|
||||||
CLUTTER_NOTE (MULTISTAGE, "Stage is not realized, unsetting");
|
CLUTTER_NOTE (MULTISTAGE,
|
||||||
stage = NULL;
|
"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
|
else
|
||||||
CLUTTER_NOTE (MULTISTAGE, "Setting the new stage [%p]", stage);
|
CLUTTER_NOTE (MULTISTAGE, "Setting the new stage [%p]", stage);
|
||||||
|
@ -275,8 +275,9 @@ clutter_stage_realize (ClutterActor *self)
|
|||||||
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||||
|
|
||||||
/* Make sure the viewport and projection matrix are valid for the
|
/* Make sure the viewport and projection matrix are valid for the
|
||||||
first paint (which will likely occur before the ConfigureNotify
|
* first paint (which will likely occur before the ConfigureNotify
|
||||||
is received) */
|
* is received)
|
||||||
|
*/
|
||||||
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_SYNC_MATRICES);
|
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_SYNC_MATRICES);
|
||||||
|
|
||||||
g_assert (priv->impl != NULL);
|
g_assert (priv->impl != NULL);
|
||||||
@ -286,7 +287,10 @@ clutter_stage_realize (ClutterActor *self)
|
|||||||
* realization sequence was successful
|
* realization sequence was successful
|
||||||
*/
|
*/
|
||||||
if (CLUTTER_ACTOR_IS_REALIZED (priv->impl))
|
if (CLUTTER_ACTOR_IS_REALIZED (priv->impl))
|
||||||
|
{
|
||||||
|
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
||||||
clutter_stage_ensure_current (CLUTTER_STAGE (self));
|
clutter_stage_ensure_current (CLUTTER_STAGE (self));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
||||||
}
|
}
|
||||||
@ -582,8 +586,9 @@ clutter_stage_dispose (GObject *object)
|
|||||||
|
|
||||||
if (priv->impl)
|
if (priv->impl)
|
||||||
{
|
{
|
||||||
CLUTTER_NOTE (MISC, "Disposing of the stage implementation");
|
CLUTTER_NOTE (BACKEND, "Disposing of the stage implementation");
|
||||||
g_object_unref (priv->impl);
|
clutter_actor_hide (priv->impl);
|
||||||
|
clutter_actor_destroy (priv->impl);
|
||||||
priv->impl = NULL;
|
priv->impl = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -847,6 +852,9 @@ clutter_stage_init (ClutterStage *self)
|
|||||||
else
|
else
|
||||||
g_object_ref_sink (priv->impl);
|
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_offscreen = FALSE;
|
||||||
priv->is_fullscreen = FALSE;
|
priv->is_fullscreen = FALSE;
|
||||||
priv->is_user_resizable = FALSE;
|
priv->is_user_resizable = FALSE;
|
||||||
|
@ -483,10 +483,13 @@ clutter_backend_glx_create_stage (ClutterBackend *backend,
|
|||||||
stage_x11->backend = backend_x11;
|
stage_x11->backend = backend_x11;
|
||||||
stage_x11->wrapper = wrapper;
|
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->xdpy,
|
||||||
stage_x11->xscreen,
|
stage_x11->xscreen,
|
||||||
(unsigned int) stage_x11->xwin_root);
|
(unsigned int) stage_x11->xwin_root,
|
||||||
|
wrapper);
|
||||||
|
|
||||||
return stage;
|
return stage;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user